* [RFC 1/6] app/test: remove packet framework tests
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
@ 2026-07-24 16:43 ` Stephen Hemminger
2026-07-24 16:43 ` [RFC 2/6] app/test-pipeline: remove application Stephen Hemminger
` (14 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-24 16:43 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The legacy packet framework libraries (port, table, pipeline) are
being removed, so remove the unit tests exercising them.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 1 -
app/test/meson.build | 6 -
app/test/test_table.c | 209 -------
app/test/test_table.h | 184 ------
app/test/test_table_acl.c | 728 ----------------------
app/test/test_table_acl.h | 6 -
app/test/test_table_combined.c | 846 -------------------------
app/test/test_table_combined.h | 27 -
app/test/test_table_pipeline.c | 575 -----------------
app/test/test_table_pipeline.h | 6 -
app/test/test_table_ports.c | 195 ------
app/test/test_table_ports.h | 13 -
app/test/test_table_tables.c | 1058 --------------------------------
app/test/test_table_tables.h | 22 -
14 files changed, 3876 deletions(-)
delete mode 100644 app/test/test_table.c
delete mode 100644 app/test/test_table.h
delete mode 100644 app/test/test_table_acl.c
delete mode 100644 app/test/test_table_acl.h
delete mode 100644 app/test/test_table_combined.c
delete mode 100644 app/test/test_table_combined.h
delete mode 100644 app/test/test_table_pipeline.c
delete mode 100644 app/test/test_table_pipeline.h
delete mode 100644 app/test/test_table_ports.c
delete mode 100644 app/test/test_table_ports.h
delete mode 100644 app/test/test_table_tables.c
delete mode 100644 app/test/test_table_tables.h
diff --git a/MAINTAINERS b/MAINTAINERS
index e99a65d197..77a41b3fcf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,7 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test/test_table*
F: app/test-pipeline/
F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
diff --git a/app/test/meson.build b/app/test/meson.build
index 51abeeb732..4fcd755940 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -195,12 +195,6 @@ source_file_deps = {
'test_stack.c': ['stack'],
'test_stack_perf.c': ['stack'],
'test_string_fns.c': [],
- 'test_table.c': ['table', 'pipeline', 'port'],
- 'test_table_acl.c': ['net', 'table', 'pipeline', 'port'],
- 'test_table_combined.c': ['table', 'pipeline', 'port'],
- 'test_table_pipeline.c': ['pipeline', 'table', 'port'],
- 'test_table_ports.c': ['table', 'pipeline', 'port'],
- 'test_table_tables.c': ['table', 'pipeline', 'port'],
'test_tailq.c': [],
'test_telemetry_data.c': ['telemetry'],
'test_telemetry_json.c': ['telemetry'],
diff --git a/app/test/test_table.c b/app/test/test_table.c
deleted file mode 100644
index 20623b8735..0000000000
--- a/app/test/test_table.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_byteorder.h>
-#include <rte_hexdump.h>
-#include <rte_string_fns.h>
-#include <string.h>
-#include "test.h"
-
-#ifdef RTE_EXEC_ENV_WINDOWS
-static int
-test_table(void)
-{
- printf("table not supported on Windows, skipping test\n");
- return TEST_SKIPPED;
-}
-#else
-
-#include "test_table.h"
-#include "test_table_pipeline.h"
-#include "test_table_ports.h"
-#include "test_table_tables.h"
-#include "test_table_combined.h"
-#include "test_table_acl.h"
-
-/* Global variables */
-struct rte_pipeline *p;
-struct rte_ring *rings_rx[N_PORTS];
-struct rte_ring *rings_tx[N_PORTS];
-struct rte_mempool *pool = NULL;
-
-uint32_t port_in_id[N_PORTS];
-uint32_t port_out_id[N_PORTS];
-uint32_t port_out_id_type[3];
-uint32_t table_id[N_PORTS*2];
-uint64_t override_hit_mask = 0xFFFFFFFF;
-uint64_t override_miss_mask = 0xFFFFFFFF;
-uint64_t non_reserved_actions_hit = 0;
-uint64_t non_reserved_actions_miss = 0;
-uint8_t connect_miss_action_to_port_out = 0;
-uint8_t connect_miss_action_to_table = 0;
-uint32_t table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
-uint32_t table_entry_hit_action = RTE_PIPELINE_ACTION_PORT;
-uint32_t table_entry_miss_action = RTE_PIPELINE_ACTION_DROP;
-rte_pipeline_port_in_action_handler port_in_action = NULL;
-rte_pipeline_port_out_action_handler port_out_action = NULL;
-rte_pipeline_table_action_handler_hit action_handler_hit = NULL;
-rte_pipeline_table_action_handler_miss action_handler_miss = NULL;
-
-/* Function prototypes */
-static void app_init_rings(void);
-static void app_init_mbuf_pools(void);
-
-uint64_t pipeline_test_hash(void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = ip_dst;
-
- return signature;
-}
-
-uint32_t pipeline_test_hash_cuckoo(const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = ip_dst;
-
- return signature;
-}
-
-static void
-app_free_resources(void) {
- int i;
- for (i = 0; i < N_PORTS; i++)
- rte_ring_free(rings_rx[i]);
- rte_mempool_free(pool);
-}
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- printf("Getting/Creating the mempool ...\n");
- pool = rte_mempool_lookup("mempool");
- if (!pool) {
- pool = rte_pktmbuf_pool_create(
- "mempool",
- POOL_SIZE,
- POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE,
- 0);
- if (pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
- }
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
- rings_rx[i] = rte_ring_lookup(name);
- if (rings_rx[i] == NULL) {
- rings_rx[i] = rte_ring_create(
- name,
- RING_RX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
- rings_tx[i] = rte_ring_lookup(name);
- if (rings_tx[i] == NULL) {
- rings_tx[i] = rte_ring_create(
- name,
- RING_TX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static int
-test_table(void)
-{
- int status, ret;
- unsigned i;
-
- ret = TEST_SUCCESS;
-
- app_init_rings();
- app_init_mbuf_pools();
-
- printf("\n\n\n\n************Pipeline tests************\n");
-
- if (test_table_pipeline() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-
- printf("\n\n\n\n************Port tests************\n");
- for (i = 0; i < n_port_tests; i++) {
- status = port_tests[i]();
- if (status < 0) {
- printf("\nPort test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests; i++) {
- status = table_tests[i]();
- if (status < 0) {
- printf("\nTable test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests_combined; i++) {
- status = table_tests_combined[i]();
- if (status < 0) {
- printf("\nCombined table test number %d failed with "
- "reason number %d.\n", i, status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
-#ifdef RTE_LIB_ACL
- printf("\n\n\n\n************ACL tests************\n");
- if (test_table_acl() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-#endif
-
-end:
- app_free_resources();
-
- return ret;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
-
-REGISTER_FAST_TEST(table_autotest, NOHUGE_OK, ASAN_OK, test_table);
diff --git a/app/test/test_table.h b/app/test/test_table.h
deleted file mode 100644
index 209bdbff2c..0000000000
--- a/app/test/test_table.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_table_stub.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_table_array.h>
-#include <rte_pipeline.h>
-
-#ifdef RTE_LIB_ACL
-#include <rte_table_acl.h>
-#endif
-
-#include <rte_port_ring.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_source_sink.h>
-
-#ifndef TEST_TABLE_H_
-#define TEST_TABLE_H_
-
-#define RING_SIZE 4096
-#define MAX_BULK 32
-#define N 65536
-#define TIME_S 5
-#define TEST_RING_FULL_EMTPY_ITER 8
-#define N_PORTS 2
-#define N_PKTS 2
-#define N_PKTS_EXT 6
-#define RING_RX rings_rx[0]
-#define RING_RX_2 rings_rx[1]
-#define RING_TX rings_tx[0]
-#define RING_TX_2 rings_tx[1]
-#define PORT_RX_RING_SIZE 128
-#define PORT_TX_RING_SIZE 512
-#define RING_RX_SIZE 128
-#define RING_TX_SIZE 128
-#define POOL_BUFFER_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
-#define POOL_SIZE (32 * 1024)
-#define POOL_CACHE_SIZE 256
-#define BURST_SIZE 8
-#define WORKER_TYPE 1
-#define MAX_DUMMY_PORTS 2
-#define MP_NAME "dummy_port_mempool"
-#define MBUF_COUNT (8000 * MAX_DUMMY_PORTS)
-#define MP_CACHE_SZ 256
-#define MP_SOCKET 0
-#define MP_FLAGS 0
-
-/* Macros */
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#define RING_ENQUEUE(ring, value) do { \
- struct rte_mbuf *m; \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- \
- m = rte_pktmbuf_alloc(pool); \
- if (m == NULL) \
- return -1; \
- signature = RTE_MBUF_METADATA_UINT32_PTR(m, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(m, \
- APP_METADATA_OFFSET(32)); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
- rte_ring_enqueue((ring), m); \
-} while (0)
-
-#define RUN_PIPELINE(pipeline) do { \
- rte_pipeline_run((pipeline)); \
- rte_pipeline_flush((pipeline)); \
-} while (0)
-
-#define VERIFY(var, value) do { \
- if ((var) != -(value)) \
- return var; \
-} while (0)
-
-#define VERIFY_TRAFFIC(ring, sent, expected) do { \
- unsigned i, n = 0; \
- void *mbuf = NULL; \
- \
- for (i = 0; i < (sent); i++) { \
- if (!rte_ring_dequeue((ring), &mbuf)) { \
- if (mbuf == NULL) \
- continue; \
- n++; \
- rte_pktmbuf_free((struct rte_mbuf *)mbuf); \
- } \
- else \
- break; \
- } \
- printf("Expected %d, got %d\n", expected, n); \
- if (n != (expected)) { \
- return -21; \
- } \
-} while (0)
-
-/* Function definitions */
-uint64_t pipeline_test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed);
-
-uint32_t pipeline_test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed);
-
-/* Extern variables */
-extern struct rte_pipeline *p;
-extern struct rte_ring *rings_rx[N_PORTS];
-extern struct rte_ring *rings_tx[N_PORTS];
-extern struct rte_mempool *pool;
-extern uint32_t port_in_id[N_PORTS];
-extern uint32_t port_out_id[N_PORTS];
-extern uint32_t port_out_id_type[3];
-extern uint32_t table_id[N_PORTS*2];
-extern uint64_t override_hit_mask;
-extern uint64_t override_miss_mask;
-extern uint64_t non_reserved_actions_hit;
-extern uint64_t non_reserved_actions_miss;
-extern uint8_t connect_miss_action_to_port_out;
-extern uint8_t connect_miss_action_to_table;
-extern uint32_t table_entry_default_action;
-extern uint32_t table_entry_hit_action;
-extern uint32_t table_entry_miss_action;
-extern rte_pipeline_port_in_action_handler port_in_action;
-extern rte_pipeline_port_out_action_handler port_out_action;
-extern rte_pipeline_table_action_handler_hit action_handler_hit;
-extern rte_pipeline_table_action_handler_miss action_handler_miss;
-
-/* Global data types */
-struct manage_ops {
- uint32_t op_id;
- void *op_data;
- int expected_result;
-};
-
-/* Internal pipeline structures */
-struct rte_port_in {
- struct rte_port_in_ops ops;
- uint32_t burst_size;
- uint32_t table_id;
- void *h_port;
-};
-
-struct rte_port_out {
- struct rte_port_out_ops ops;
- void *h_port;
-};
-
-struct rte_table {
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action;
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
- uint8_t actions_lookup_miss[RTE_CACHE_LINE_SIZE];
- uint32_t action_data_size;
- void *h_table;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct rte_pipeline {
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- uint32_t socket_id;
- struct rte_port_in ports_in[16];
- struct rte_port_out ports_out[16];
- struct rte_table tables[64];
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_table_entry *actions[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t mask_action[64];
- uint32_t mask_actions;
-};
-#endif
diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c
deleted file mode 100644
index 4fdf731596..0000000000
--- a/app/test/test_table_acl.c
+++ /dev/null
@@ -1,728 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <rte_ip.h>
-#include <rte_string_fns.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_acl.h"
-
-/*
- * Rule and trace formats definitions.
- **/
-
-struct ipv4_5tuple {
- uint8_t proto;
- uint32_t ip_src;
- uint32_t ip_dst;
- uint16_t port_src;
- uint16_t port_dst;
-};
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, proto),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_dst),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_dst),
- },
-};
-
-struct rte_table_acl_rule_add_params table_acl_IPv4_rule;
-
-typedef int (*parse_5tuple)(char *text,
- struct rte_table_acl_rule_add_params *rule);
-
-/*
-* The order of the fields in the rule string after the initial '@'
-*/
-enum {
- CB_FLD_SRC_ADDR,
- CB_FLD_DST_ADDR,
- CB_FLD_SRC_PORT_RANGE,
- CB_FLD_DST_PORT_RANGE,
- CB_FLD_PROTO,
- CB_FLD_NUM,
-};
-
-
-#define GET_CB_FIELD(in, fd, base, lim, dlm) \
-do { \
- unsigned long val; \
- char *end; \
- \
- errno = 0; \
- val = strtoul((in), &end, (base)); \
- if (errno != 0 || end[0] != (dlm) || val > (lim)) \
- return -EINVAL; \
- (fd) = (typeof(fd)) val; \
- (in) = end + 1; \
-} while (0)
-
-
-
-
-static int
-parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len)
-{
- uint8_t a, b, c, d, m;
-
- GET_CB_FIELD(in, a, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, b, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, c, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, d, 0, UINT8_MAX, '/');
- GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0);
-
- addr[0] = RTE_IPV4(a, b, c, d);
- mask_len[0] = m;
-
- return 0;
-}
-
-static int
-parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high)
-{
- uint16_t a, b;
-
- GET_CB_FIELD(in, a, 0, UINT16_MAX, ':');
- GET_CB_FIELD(in, b, 0, UINT16_MAX, 0);
-
- port_low[0] = a;
- port_high[0] = b;
-
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-setup_acl_pipeline(void)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
- uint32_t n;
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_acl_rule_delete_params *delete_params;
- parse_5tuple parser;
- char acl_name[64];
-
- /*
- * The format for these rules DO NOT need the port ranges to be
- * separated by ' : ', just ':'. It's a lot more readable and
- * cleaner, IMO.
- */
- static const char * const lines[] = {
- "@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */
- "@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP check */
- "@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */
- "@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */
- "@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */
- };
- char line[LINE_MAX];
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = port_in_action;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params;
-
- /* Set up defaults for stub */
- table_params.ops = &rte_table_stub_ops;
- table_params.arg_create = NULL;
- table_params.f_action_hit = action_handler_hit;
- table_params.f_action_miss = NULL;
- table_params.action_data_size = 0;
-
- printf("miss_action=%x\n",
- table_entry_miss_action);
-
- printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs),
- RTE_ACL_RULE_SZ(DIM(ipv4_defs)));
-
- struct rte_table_acl_params acl_params;
-
- acl_params.n_rules = 1 << 5;
- acl_params.n_rule_fields = DIM(ipv4_defs);
- snprintf(acl_name, sizeof(acl_name), "ACL%d", i);
- acl_params.name = acl_name;
- memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
-
- table_params.ops = &rte_table_acl_ops;
- table_params.arg_create = &acl_params;
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table) {
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
- }
-
- for (i = 0; i < N_PORTS; i++) {
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n",
- port_in_id[i], table_id[i]);
- goto fail;
- }
- }
-
- /* Add bulk entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_add_params keys[5];
- struct rte_pipeline_table_entry entries[5];
- struct rte_table_acl_rule_add_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
- struct rte_pipeline_table_entry *table_entries_ptr[5];
- struct rte_pipeline_table_entry entries_ptr[5];
-
- parser = parse_cb_ipv4_rule;
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1;
-
- entries[n].action = RTE_PIPELINE_ACTION_PORT;
- entries[n].port_id = port_out_id[i^1];
- table_entries[n] = &entries[n];
- table_entries_ptr[n] = &entries_ptr[n];
- }
-
- ret = rte_pipeline_table_entry_add_bulk(p, table_id[i],
- (void **)key_array, table_entries, 5, key_found, table_entries_ptr);
- if (ret < 0) {
- rte_panic("Add entry bulk to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* Delete bulk entries from tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_delete_params keys[5];
- struct rte_table_acl_rule_delete_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
-
- memset(table_entries, 0, sizeof(table_entries));
-
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parse_cb_ipv4_rule_del(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
- }
-
- ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i],
- (void **)key_array, 5, key_found, table_entries);
- if (ret < 0) {
- rte_panic("Delete bulk entries from table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Bulk deleted rules.\n");
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- int key_found;
- struct rte_pipeline_table_entry *entry_ptr;
-
- memset(&rule_params, 0, sizeof(rule_params));
- parser = parse_cb_ipv4_rule;
-
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* delete a few rules */
- for (n = 2; n <= 3; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- delete_params = (struct
- rte_pipeline_table_acl_rule_delete_params *)
- &(rule_params.field_value[0]);
- ret = rte_pipeline_table_entry_delete(p, table_id[i],
- delete_params, &key_found, NULL);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Deleted Rule.\n");
- }
-
-
- /* Try to add duplicates */
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- }
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int expected_count)
-{
- int i, j, ret, tx_count;
- struct ipv4_5tuple five_tuple;
-
- /* Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++) {
- for (j = 0; j < 8; j++) {
- struct rte_mbuf *mbuf;
-
- mbuf = rte_pktmbuf_alloc(pool);
- if (mbuf == NULL)
- /* this will cause test failure after cleanup
- * of already enqueued mbufs, as the mbuf
- * counts won't match */
- break;
- memset(rte_pktmbuf_mtod(mbuf, char *), 0x00,
- sizeof(struct ipv4_5tuple));
-
- five_tuple.proto = j;
- five_tuple.ip_src = rte_bswap32(RTE_IPV4(192, 168, j, 1));
- five_tuple.ip_dst = rte_bswap32(RTE_IPV4(10, 4, j, 1));
- five_tuple.port_src = rte_bswap16(100 + j);
- five_tuple.port_dst = rte_bswap16(200 + j);
-
- memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple,
- sizeof(struct ipv4_5tuple));
- printf("%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], mbuf);
- }
- }
-
- /* Run pipeline once */
- for (i = 0; i< N_PORTS; i++)
- rte_pipeline_run(p);
-
- rte_pipeline_flush(p);
-
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0) {
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- } else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "mbuf",
- rte_pktmbuf_mtod(mbuf, char *), 64);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets for ACL test, expected %d, got %d\n",
- __func__, expected_count, tx_count);
- goto fail;
- }
-
- rte_pipeline_free(p);
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_acl(void)
-{
-
-
- override_hit_mask = 0xFF; /* All packets are a hit */
-
- setup_acl_pipeline();
- if (test_pipeline_single_filter(10) < 0)
- return -1;
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_acl.h b/app/test/test_table_acl.h
deleted file mode 100644
index a6ae7d2838..0000000000
--- a/app/test/test_table_acl.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_acl(void);
diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
deleted file mode 100644
index 04503baa51..0000000000
--- a/app/test/test_table_combined.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include "test_table_combined.h"
-#include "test_table.h"
-#include <rte_table_lpm_ipv6.h>
-
-#define MAX_TEST_KEYS 128
-#define N_PACKETS 50
-
-enum check_table_result {
- CHECK_TABLE_OK,
- CHECK_TABLE_PORT_CONFIG,
- CHECK_TABLE_PORT_ENABLE,
- CHECK_TABLE_TABLE_CONFIG,
- CHECK_TABLE_ENTRY_ADD,
- CHECK_TABLE_DEFAULT_ENTRY_ADD,
- CHECK_TABLE_CONNECT,
- CHECK_TABLE_MANAGE_ERROR,
- CHECK_TABLE_CONSISTENCY,
- CHECK_TABLE_NO_TRAFFIC,
- CHECK_TABLE_INVALID_PARAMETER,
-};
-
-struct table_packets {
- uint32_t hit_packet[MAX_TEST_KEYS];
- uint32_t miss_packet[MAX_TEST_KEYS];
- uint32_t n_hit_packets;
- uint32_t n_miss_packets;
-};
-
-combined_table_test table_tests_combined[] = {
- test_table_lpm_combined,
- test_table_lpm_ipv6_combined,
- test_table_hash8lru,
- test_table_hash8ext,
- test_table_hash16lru,
- test_table_hash16ext,
- test_table_hash32lru,
- test_table_hash32ext,
- test_table_hash_cuckoo_combined,
-};
-
-unsigned n_table_tests_combined = RTE_DIM(table_tests_combined);
-
-/* Generic port tester function */
-static int
-test_table_type(struct rte_table_ops *table_ops, void *table_args,
- void *key, struct table_packets *table_packets,
- struct manage_ops *manage_ops, unsigned n_ops)
-{
- uint32_t ring_in_id, table_id, ring_out_id, ring_out_2_id;
- unsigned i;
-
- RTE_SET_USED(manage_ops);
- RTE_SET_USED(n_ops);
- /* Create pipeline */
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = 0,
- };
-
- struct rte_pipeline *pipeline = rte_pipeline_create(&pipeline_params);
-
- /* Create input ring */
- struct rte_port_ring_reader_params ring_params_rx = {
- .ring = RING_RX,
- };
-
- struct rte_port_ring_writer_params ring_params_tx = {
- .ring = RING_RX,
- .tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- struct rte_pipeline_port_in_params ring_in_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *)&ring_params_rx,
- .f_action = NULL,
- .burst_size = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- if (rte_pipeline_port_in_create(pipeline, &ring_in_params,
- &ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Create table */
- struct rte_pipeline_table_params table_params = {
- .ops = table_ops,
- .arg_create = table_args,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(pipeline, &table_params,
- &table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_TABLE_CONFIG;
- }
-
- /* Create output ports */
- ring_params_tx.ring = RING_TX;
-
- struct rte_pipeline_port_out_params ring_out_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *)&ring_params_tx,
- .f_action = NULL,
- };
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- ring_params_tx.ring = RING_TX_2;
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_2_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Add entry to the table */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_DROP,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry *default_entry_ptr, *entry_ptr;
-
- int key_found;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_DEFAULT_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Create connections and check consistency */
- if (rte_pipeline_port_in_connect_to_table(pipeline, ring_in_id,
- table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONNECT;
- }
-
- if (rte_pipeline_port_in_enable(pipeline, ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_ENABLE;
- }
-
- if (rte_pipeline_check(pipeline) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONSISTENCY;
- }
-
-
-
- /* Flow test - All hits */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- /* Flow test - All misses */
- if (table_packets->n_miss_packets) {
- for (i = 0; i < table_packets->n_miss_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
- /* Flow test - Half hits, half misses */
- if (table_packets->n_hit_packets && table_packets->n_miss_packets) {
- for (i = 0; i < (table_packets->n_hit_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- for (i = 0; i < (table_packets->n_miss_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets / 2);
- }
-
- /* Flow test - Single packet */
- if (table_packets->n_hit_packets) {
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 1);
- }
- if (table_packets->n_miss_packets) {
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
-
- /* Change table entry action */
- printf("Change entry action\n");
- table_entry.table_id = ring_out_2_id;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Check that traffic destination has changed */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 0);
- VERIFY_TRAFFIC(RING_TX_2, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- printf("delete entry\n");
- /* Delete table entry */
- rte_pipeline_table_entry_delete(pipeline, table_id,
- key ? key : &table_entry, &key_found, NULL);
-
- rte_pipeline_free(pipeline);
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub_combined(void)
-{
- int status, i;
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = i;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = 0;
-
- status = test_table_type(&rte_table_stub_ops, NULL, NULL,
- &table_packets, NULL, 1);
- VERIFY(status, CHECK_TABLE_OK);
-
- return 0;
-}
-
-int
-test_table_lpm_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(0),
- };
-
- struct rte_table_lpm_key lpm_key = {
- .ip = 0xadadadad,
- .depth = 16,
- };
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_params.n_rules = 1 << 24;
- lpm_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_key.depth = 33;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_ipv6_params lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 13,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_table_lpm_ipv6_key lpm_ipv6_key = {
- .depth = 16,
- };
- memset(&lpm_ipv6_key.ip, 0xad, 16);
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xadadadab;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_ipv6_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_ipv6_params.n_rules = 1 << 24;
- lpm_ipv6_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_ipv6_key.depth = 129;
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_hash8lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8lru_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8lru[8];
- uint32_t *k8lru = (uint32_t *) key8lru;
-
- memset(key8lru, 0, sizeof(key8lru));
- k8lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8lru_params.n_keys = 1<<16;
- key8lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16lru_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16lru[16];
- uint32_t *k16lru = (uint32_t *) key16lru;
-
- memset(key16lru, 0, sizeof(key16lru));
- k16lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16lru_params.n_keys = 1<<16;
- key16lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32lru_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32lru[32];
- uint32_t *k32lru = (uint32_t *) key32lru;
-
- memset(key32lru, 0, sizeof(key32lru));
- k32lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32lru_params.n_keys = 1<<16;
- key32lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash8ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8ext_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8ext[8];
- uint32_t *k8ext = (uint32_t *) key8ext;
-
- memset(key8ext, 0, sizeof(key8ext));
- k8ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8ext_params.n_keys = 1<<16;
- key8ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16ext_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16ext[16];
- uint32_t *k16ext = (uint32_t *) key16ext;
-
- memset(key16ext, 0, sizeof(key16ext));
- k16ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16ext_params.n_keys = 1<<16;
- key16ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32ext_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32ext[32];
- uint32_t *k32ext = (uint32_t *) key32ext;
-
- memset(key32ext, 0, sizeof(key32ext));
- k32ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32ext_params.n_keys = 1<<16;
- key32ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash_cuckoo_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) key_cuckoo;
-
- memset(key_cuckoo, 0, sizeof(key_cuckoo));
- kcuckoo[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- cuckoo_params.key_size = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.n_keys = 1<<16;
- cuckoo_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_combined.h b/app/test/test_table_combined.h
deleted file mode 100644
index fb94dbb94d..0000000000
--- a/app/test/test_table_combined.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_stub_combined(void);
-int test_table_lpm_combined(void);
-int test_table_lpm_ipv6_combined(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash8unoptimized(void);
-int test_table_hash8lru(void);
-int test_table_hash8ext(void);
-int test_table_hash16unoptimized(void);
-int test_table_hash16lru(void);
-int test_table_hash16ext(void);
-int test_table_hash32unoptimized(void);
-int test_table_hash32lru(void);
-int test_table_hash32ext(void);
-int test_table_hash_cuckoo_combined(void);
-
-/* Extern variables */
-typedef int (*combined_table_test)(void);
-
-extern combined_table_test table_tests_combined[];
-extern unsigned n_table_tests_combined;
diff --git a/app/test/test_table_pipeline.c b/app/test/test_table_pipeline.c
deleted file mode 100644
index 960f730cf2..0000000000
--- a/app/test/test_table_pipeline.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_pipeline.h>
-#include <inttypes.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_pipeline.h"
-
-#if 0
-
-static rte_pipeline_port_out_action_handler port_action_0x00
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_0xFF
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_stub
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-
-
-rte_pipeline_port_out_action_handler port_action_0x00(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0x00\n");
- *pkts_mask = 0x00;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_0xFF(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0xFF\n");
- *pkts_mask = 0xFF;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(pkts_mask);
- RTE_SET_USED(arg);
- printf("Port Action stub\n");
- return 0;
-}
-
-#endif
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-static int
-table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry *entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("Table Action, setting pkts_mask to 0x00\n");
- pkts_mask = ~0x00;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Hit - doing nothing\n");
- printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n",
- override_hit_mask);
- pkts_mask = (~override_hit_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-static int
-table_action_stub_miss(struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry *entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n",
- override_miss_mask);
- pkts_mask = (~override_miss_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-enum e_test_type {
- e_TEST_STUB = 0,
- e_TEST_LPM,
- e_TEST_LPM6,
- e_TEST_HASH_LRU_8,
- e_TEST_HASH_LRU_16,
- e_TEST_HASH_LRU_32,
- e_TEST_HASH_EXT_8,
- e_TEST_HASH_EXT_16,
- e_TEST_HASH_EXT_32
-};
-
-char pipeline_test_names[][64] = {
- "Stub",
- "LPM",
- "LPMv6",
- "8-bit LRU Hash",
- "16-bit LRU Hash",
- "32-bit LRU Hash",
- "16-bit Ext Hash",
- "8-bit Ext Hash",
- "32-bit Ext Hash",
- ""
-};
-
-
-static int
-cleanup_pipeline(void)
-{
-
- rte_pipeline_free(p);
-
- return 0;
-}
-
-
-static int check_pipeline_invalid_params(void);
-
-static int
-check_pipeline_invalid_params(void)
-{
- struct rte_pipeline_params pipeline_params_1 = {
- .name = NULL,
- .socket_id = 0,
- };
- struct rte_pipeline_params pipeline_params_2 = {
- .name = "PIPELINE",
- .socket_id = -1,
- };
- struct rte_pipeline_params pipeline_params_3 = {
- .name = "PIPELINE",
- .socket_id = 127,
- };
-
- p = rte_pipeline_create(NULL);
- if (p != NULL) {
- fprintf(stderr,
- "%s: configured pipeline with null params\n",
- __func__);
- goto fail;
- }
- p = rte_pipeline_create(&pipeline_params_1);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with NULL name\n", __func__);
- goto fail;
- }
-
- p = rte_pipeline_create(&pipeline_params_2);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n", __func__);
- goto fail;
- }
-
- if (rte_eal_has_hugepages()) {
- p = rte_pipeline_create(&pipeline_params_3);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n",
- __func__);
- goto fail;
- }
- }
-
- /* Check pipeline consistency */
- if (!rte_pipeline_check(p)) {
- rte_panic("Pipeline consistency reported as OK\n");
- goto fail;
- }
-
-
- return 0;
-fail:
- return -1;
-}
-
-
-static int
-setup_pipeline(int test_type)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
-
- fprintf(stderr, "%s: **** Setting up %s test\n",
- __func__, pipeline_test_names[test_type]);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- ret = rte_pipeline_free(p);
- if (ret != 0) {
- fprintf(stderr, "%s: Failed to free pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = NULL;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (i)
- port_params.f_action = port_out_action;
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = action_handler_hit,
- .f_action_miss = action_handler_miss,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table)
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
-
- for (i = 0; i < N_PORTS; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
- goto fail;
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry default_entry = {
- .action = (enum rte_pipeline_action)
- table_entry_default_action,
- {.port_id = port_out_id[i^1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (connect_miss_action_to_table) {
- printf("Setting first table to output to next table\n");
- default_entry.action = RTE_PIPELINE_ACTION_TABLE;
- default_entry.table_id = table_id[i+2];
- }
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p, table_id[i],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to table %u "
- "code %d\n", table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d with "
- "action %x\n",
- table_id[i], default_entry.action);
-
- if (connect_miss_action_to_table) {
- /* We create a second table so the first can pass
- traffic into it */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- printf("Setting second table to output to port\n");
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p,
- table_id[i+2],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to "
- "table %u code %d\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d "
- "with action %x\n",
- table_id[i], default_entry.action);
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- } else
- printf("Pipeline Consistency OK!\n");
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int test_type, int expected_count)
-{
- int i;
- int j;
- int ret;
- int tx_count;
-
- fprintf(stderr, "%s: **** Running %s test\n",
- __func__, pipeline_test_names[test_type]);
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
-
- ret = rte_pipeline_flush(NULL);
- if (ret != -EINVAL) {
- fprintf(stderr,
- "%s: No pipeline flush error NULL pipeline (%d)\n",
- __func__, ret);
- goto fail;
- }
-
- /*
- * Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++)
- for (j = 0; j < N_PORTS; j++) {
- struct rte_mbuf *m;
- uint8_t *key;
- uint32_t *k32;
-
- m = rte_pktmbuf_alloc(pool);
- if (m == NULL) {
- rte_panic("Failed to alloc mbuf from pool\n");
- return -1;
- }
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- k32 = (uint32_t *) key;
- k32[0] = 0xadadadad >> (j % 2);
-
- fprintf(stderr, "%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], m);
- }
-
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
- /*
- * need to flush the pipeline, as there may be less hits than the burst
- size and they will not have been flushed to the tx rings. */
- rte_pipeline_flush(p);
-
- /*
- * Now we'll see what we got back on the tx rings. We should see whatever
- * packets we had hits on that were destined for the output ports.
- */
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0)
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "Object:",
- rte_pktmbuf_mtod(mbuf, char *),
- mbuf->data_len);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets out for %s test, expected %d, got %d\n",
- __func__, pipeline_test_names[test_type],
- expected_count, tx_count);
- goto fail;
- }
-
- cleanup_pipeline();
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_pipeline(void)
-{
- /* TEST - All packets dropped */
- action_handler_hit = NULL;
- action_handler_miss = NULL;
- table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 0) < 0)
- return -1;
-
- /* TEST - All packets passed through */
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /* TEST - one packet per port */
- action_handler_hit = NULL;
- action_handler_miss = table_action_stub_miss;
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- override_miss_mask = 0x01; /* one packet per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - one packet per port */
- override_miss_mask = 0x02; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - all packets per port */
- override_miss_mask = 0x03; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /*
- * This test will set up two tables in the pipeline. the first table
- * will forward to another table on miss, and the second table will
- * forward to port.
- */
- connect_miss_action_to_table = 1;
- table_entry_default_action = RTE_PIPELINE_ACTION_TABLE;
- action_handler_hit = NULL; /* not for stub, hitmask always zero */
- action_handler_miss = NULL;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- printf("TEST - two tables, hitmask override to 0x01\n");
- connect_miss_action_to_table = 1;
- action_handler_miss = table_action_stub_miss;
- override_miss_mask = 0x01;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- if (check_pipeline_invalid_params()) {
- fprintf(stderr, "%s: Check pipeline invalid params failed.\n",
- __func__);
- return -1;
- }
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_pipeline.h b/app/test/test_table_pipeline.h
deleted file mode 100644
index d66d09d6f1..0000000000
--- a/app/test/test_table_pipeline.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_pipeline(void);
diff --git a/app/test/test_table_ports.c b/app/test/test_table_ports.c
deleted file mode 100644
index 282ec2a3d2..0000000000
--- a/app/test/test_table_ports.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include "test_table_ports.h"
-#include "test_table.h"
-
-port_test port_tests[] = {
- test_port_ring_reader,
- test_port_ring_writer,
-};
-
-unsigned n_port_tests = RTE_DIM(port_tests);
-
-/* Port tests */
-int
-test_port_ring_reader(void)
-{
- int status, i;
- struct rte_port_ring_reader_params port_ring_reader_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_reader_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- /* Create and free */
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
- if (port == NULL)
- return -3;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status != 0)
- return -4;
-
- /* -- Traffic RX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- void *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
-
- /* Single packet */
- mbuf[0] = (void *)rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- mbuf, 1, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, 1);
-
- if (received_pkts < expected_pkts)
- return -5;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- (void * const *) mbuf, RTE_PORT_IN_BURST_SIZE_MAX, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf,
- RTE_PORT_IN_BURST_SIZE_MAX);
-
- if (received_pkts < expected_pkts)
- return -6;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-int
-test_port_ring_writer(void)
-{
- int status, i;
- struct rte_port_ring_writer_params port_ring_writer_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_writer_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- port_ring_writer_params.ring = NULL;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -3;
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX + 1;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -4;
-
- /* Create and free */
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port == NULL)
- return -5;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status != 0)
- return -6;
-
- /* -- Traffic TX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
-
- /* Single packet */
- mbuf[0] = rte_pktmbuf_alloc(pool);
-
- rte_port_ring_writer_ops.f_tx(port, mbuf[0]);
- rte_port_ring_writer_ops.f_flush(port);
- expected_pkts = 1;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -7;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx(port, mbuf[i]);
- }
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- /* TX Bulk */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-1);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-3);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)2);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -9;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_ports.h b/app/test/test_table_ports.h
deleted file mode 100644
index dfa6119319..0000000000
--- a/app/test/test_table_ports.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_port_ring_reader(void);
-int test_port_ring_writer(void);
-
-/* Extern variables */
-typedef int (*port_test)(void);
-
-extern port_test port_tests[];
-extern unsigned n_port_tests;
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
deleted file mode 100644
index 920aa555cb..0000000000
--- a/app/test/test_table_tables.c
+++ /dev/null
@@ -1,1058 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_byteorder.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_lru.h>
-#include <rte_cycles.h>
-#include "test_table_tables.h"
-#include "test_table.h"
-
-table_test table_tests[] = {
- test_table_stub,
- test_table_array,
- test_table_lpm,
- test_table_lpm_ipv6,
- test_table_hash_lru,
- test_table_hash_ext,
- test_table_hash_cuckoo,
-};
-
-#define PREPARE_PACKET(mbuf, value) do { \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- mbuf = rte_pktmbuf_alloc(pool); \
- signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \
- APP_METADATA_OFFSET(32)); \
- if (mbuf->priv_size + mbuf->buf_len >= 64) \
- memset(key, 0, 32); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
-} while (0)
-
-unsigned n_table_tests = RTE_DIM(table_tests);
-
-/* Function prototypes */
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size);
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size);
-
-struct rte_bucket_4_8 {
- /* Cache line 0 */
- uint64_t signature;
- uint64_t lru_list;
- struct rte_bucket_4_8 *next;
- uint64_t next_valid;
- uint64_t key[4];
- /* Cache line 1 */
- uint8_t data[];
-};
-
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
-uint64_t shuffles = 0xfffffffdfffbfff9ULL;
-#else
-uint64_t shuffles = 0x0003000200010000ULL;
-#endif
-
-static int test_lru_update(void)
-{
- struct rte_bucket_4_8 b;
- struct rte_bucket_4_8 *bucket;
- uint32_t i;
- uint64_t pos;
- uint64_t iterations;
- uint64_t j;
- int poss;
-
- printf("---------------------------\n");
- printf("Testing lru_update macro...\n");
- printf("---------------------------\n");
- bucket = &b;
- iterations = 10;
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
- bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL;
-#else
- bucket->lru_list = 0x0000000100020003ULL;
-#endif
- poss = 0;
- for (j = 0; j < iterations; j++)
- for (i = 0; i < 9; i++) {
- uint32_t idx = i >> 1;
- lru_update(bucket, idx);
- pos = lru_pos(bucket);
- poss += pos;
- printf("%s: %d lru_list=%016"PRIx64", upd=%d, "
- "pos=%"PRIx64"\n",
- __func__, i, bucket->lru_list, i>>1, pos);
- }
-
- if (bucket->lru_list != shuffles) {
- printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016"
- PRIx64"\n",
- __func__, i, bucket->lru_list, shuffles);
- return -1;
- }
- printf("%s: output checksum of results =%d\n",
- __func__, poss);
-#if 0
- if (poss != 126) {
- printf("%s: ERROR output checksum of results =%d expected %d\n",
- __func__, poss, 126);
- return -1;
- }
-#endif
-
- fflush(stdout);
-
- uint64_t sc_start = rte_rdtsc();
- iterations = 100000000;
- poss = 0;
- for (j = 0; j < iterations; j++) {
- for (i = 0; i < 4; i++) {
- lru_update(bucket, i);
- pos |= bucket->lru_list;
- }
- }
- uint64_t sc_end = rte_rdtsc();
-
- printf("%s: output checksum of results =%llu\n",
- __func__, (long long unsigned int)pos);
- printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n",
- __func__, sc_start, sc_end);
- printf("\nlru_update: %lu cycles per loop iteration.\n\n",
- (long unsigned int)((sc_end-sc_start)/(iterations*4)));
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub(void)
-{
- int i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
-
- /* Create */
- table = rte_table_stub_ops.f_create(NULL, 0, 1);
- if (table == NULL)
- return -1;
-
- /* Traffic flow */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- expected_mask = 0;
- rte_table_stub_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -2;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- return 0;
-}
-
-int
-test_table_array(void)
-{
- int status, i;
- uint64_t result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry1, entry2;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_array_params array_params = {
- .n_entries = 7,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_array_ops.f_create(NULL, 0, 1);
- if (table != NULL)
- return -1;
-
- array_params.n_entries = 0;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -2;
-
- array_params.n_entries = 7;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -3;
-
- array_params.n_entries = 1 << 24;
- array_params.offset = APP_METADATA_OFFSET(1);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -4;
-
- array_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = rte_table_array_ops.f_free(table);
- if (status < 0)
- return -6;
-
- status = rte_table_array_ops.f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- struct rte_table_array_key array_key_1 = {
- .pos = 10,
- };
- struct rte_table_array_key array_key_2 = {
- .pos = 20,
- };
- entry1 = 'A';
- entry2 = 'B';
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -8;
-
- status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1,
- &key_found, &entry_ptr);
- if (status == 0)
- return -9;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL,
- &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1,
- &entry1, &key_found, &entry_ptr);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- status = rte_table_array_ops.f_add(table, (void *) &array_key_2,
- &entry2, &key_found, &entry_ptr);
- if (status != 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 10);
- else
- PREPARE_PACKET(mbufs[i], 20);
-
- rte_table_array_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0 && *entries[i] != 'A')
- return -13;
- else
- if (i % 2 == 1 && *entries[i] != 'B')
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_array_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_lpm_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.offset = APP_METADATA_OFFSET(32);
- lpm_params.entry_unique_size = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.entry_unique_size = entry_size + 1;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_lpm_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_lpm_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- struct rte_table_lpm_key lpm_key;
- lpm_key.ip = 0xadadadad;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -9;
-
- status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status != 0)
- return -15;
-
- /* Delete */
- status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -17;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -20;
-
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -21;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -22;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -23;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_ipv6_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 18,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(32)
- };
-
- table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.number_tbl8s = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.number_tbl8s = 1 << 18;
- lpm_params.entry_unique_size = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size + 1;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -6;
-
- lpm_params.entry_unique_size = entry_size;
- lpm_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -7;
-
- /* Free */
- status = rte_table_lpm_ipv6_ops.f_free(table);
- if (status < 0)
- return -8;
-
- status = rte_table_lpm_ipv6_ops.f_free(NULL);
- if (status == 0)
- return -9;
-
- /* Add */
- struct rte_table_lpm_ipv6_key lpm_key;
-
- lpm_key.ip.a[0] = 0xad;
- lpm_key.ip.a[1] = 0xad;
- lpm_key.ip.a[2] = 0xad;
- lpm_key.ip.a[3] = 0xad;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -10;
-
- status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -15;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status != 0)
- return -16;
-
- /* Delete */
- status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -17;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -20;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -21;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -22;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- return -23;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -24;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ipv6_ops.f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- int key_found;
- void *entry_ptr;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.key_offset = APP_METADATA_OFFSET(1);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -3;
-
- hash_params.key_offset = APP_METADATA_OFFSET(32);
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-int
-test_table_hash_lru(void)
-{
- int status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key8_lru_ops,
- 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key16_lru_ops,
- 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key32_lru_ops,
- 32);
- if (status < 0)
- return status;
-
- status = test_lru_update();
- if (status < 0)
- return status;
-
- return 0;
-}
-
-int
-test_table_hash_ext(void)
-{
- int status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops, 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32);
- if (status < 0)
- return status;
-
- return 0;
-}
-
-
-int
-test_table_hash_cuckoo(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = 1;
-
- /* Initialize params and create tables */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- cuckoo_params.key_size = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -2;
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -3;
-
- cuckoo_params.n_keys = 1 << 24;
- cuckoo_params.f_hash = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -4;
-
- cuckoo_params.f_hash = pipeline_test_hash_cuckoo;
- cuckoo_params.name = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -5;
-
- cuckoo_params.name = "CUCKOO";
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_hash_cuckoo_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_hash_cuckoo_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) &key_cuckoo;
-
- memset(key_cuckoo, 0, 32);
- kcuckoo[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 0, 1);
- if (table == NULL)
- return -9;
-
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- NULL, &key_found, &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -13;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -14;
-
- /* Delete */
- status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo,
- &key_found, NULL);
- if (status == 0)
- return -15;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, NULL,
- &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != 0)
- return -17;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != -ENOENT)
- return -18;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -19;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_hash_cuckoo_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -20;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_hash_cuckoo_ops.f_free(table);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_tables.h b/app/test/test_table_tables.h
deleted file mode 100644
index 530633a013..0000000000
--- a/app/test/test_table_tables.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_hash_cuckoo(void);
-int test_table_lpm(void);
-int test_table_lpm_ipv6(void);
-int test_table_array(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash_unoptimized(void);
-int test_table_hash_lru(void);
-int test_table_hash_ext(void);
-int test_table_stub(void);
-
-/* Extern variables */
-typedef int (*table_test)(void);
-
-extern table_test table_tests[];
-extern unsigned n_table_tests;
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC 2/6] app/test-pipeline: remove application
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
2026-07-24 16:43 ` [RFC 1/6] app/test: remove packet framework tests Stephen Hemminger
@ 2026-07-24 16:43 ` Stephen Hemminger
2026-07-24 16:43 ` [RFC 3/6] examples/ip_pipeline: remove example Stephen Hemminger
` (13 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-24 16:43 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The test-pipeline application is built on the legacy pipeline
library API (rte_pipeline_*), which was announced for removal
in the 24.11 release. Remove it before removing the library.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
app/meson.build | 1 -
app/test-pipeline/config.c | 230 ---------
app/test-pipeline/init.c | 273 ----------
app/test-pipeline/main.c | 188 -------
app/test-pipeline/main.h | 132 -----
app/test-pipeline/meson.build | 21 -
app/test-pipeline/pipeline_acl.c | 251 ----------
app/test-pipeline/pipeline_hash.c | 471 ------------------
app/test-pipeline/pipeline_lpm.c | 175 -------
app/test-pipeline/pipeline_lpm_ipv6.c | 168 -------
app/test-pipeline/pipeline_stub.c | 137 -----
app/test-pipeline/runtime.c | 160 ------
doc/guides/rel_notes/release_26_11.rst | 3 +
.../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/test_pipeline.rst | 237 ---------
17 files changed, 3 insertions(+), 2447 deletions(-)
delete mode 100644 app/test-pipeline/config.c
delete mode 100644 app/test-pipeline/init.c
delete mode 100644 app/test-pipeline/main.c
delete mode 100644 app/test-pipeline/main.h
delete mode 100644 app/test-pipeline/meson.build
delete mode 100644 app/test-pipeline/pipeline_acl.c
delete mode 100644 app/test-pipeline/pipeline_hash.c
delete mode 100644 app/test-pipeline/pipeline_lpm.c
delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
delete mode 100644 app/test-pipeline/pipeline_stub.c
delete mode 100644 app/test-pipeline/runtime.c
delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 77a41b3fcf..4c06f85706 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,8 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test-pipeline/
-F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
F: examples/pipeline/
F: doc/guides/sample_app_ug/ip_pipeline.rst
diff --git a/app/meson.build b/app/meson.build
index 1798db3ae4..4515688471 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -28,7 +28,6 @@ apps = [
'test-flow-perf',
'test-gpudev',
'test-mldev',
- 'test-pipeline',
'test-pmd',
'test-regex',
'test-sad',
diff --git a/app/test-pipeline/config.c b/app/test-pipeline/config.c
deleted file mode 100644
index daf838948b..0000000000
--- a/app/test-pipeline/config.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_string_fns.h>
-
-#include "main.h"
-
-static const char usage[] = "\n";
-
-void
-app_print_usage(void)
-{
- printf(usage);
-}
-
-static int
-app_parse_port_mask(const char *arg)
-{
- char *end = NULL;
- uint64_t port_mask;
- uint32_t i;
-
- if (arg[0] == '\0')
- return -1;
-
- port_mask = strtoul(arg, &end, 16);
- if ((end == NULL) || (*end != '\0'))
- return -2;
-
- if (port_mask == 0)
- return -3;
-
- app.n_ports = 0;
- for (i = 0; i < 64; i++) {
- if ((port_mask & (1LLU << i)) == 0)
- continue;
-
- if (app.n_ports >= APP_MAX_PORTS)
- return -4;
-
- app.ports[app.n_ports] = i;
- app.n_ports++;
- }
-
- if (!rte_is_power_of_2(app.n_ports))
- return -5;
-
- return 0;
-}
-
-struct {
- const char *name;
- uint32_t value;
-} app_args_table[] = {
- {"none", e_APP_PIPELINE_NONE},
- {"stub", e_APP_PIPELINE_STUB},
- {"hash-8-ext", e_APP_PIPELINE_HASH_KEY8_EXT},
- {"hash-8-lru", e_APP_PIPELINE_HASH_KEY8_LRU},
- {"hash-16-ext", e_APP_PIPELINE_HASH_KEY16_EXT},
- {"hash-16-lru", e_APP_PIPELINE_HASH_KEY16_LRU},
- {"hash-32-ext", e_APP_PIPELINE_HASH_KEY32_EXT},
- {"hash-32-lru", e_APP_PIPELINE_HASH_KEY32_LRU},
- {"hash-spec-8-ext", e_APP_PIPELINE_HASH_SPEC_KEY8_EXT},
- {"hash-spec-8-lru", e_APP_PIPELINE_HASH_SPEC_KEY8_LRU},
- {"hash-spec-16-ext", e_APP_PIPELINE_HASH_SPEC_KEY16_EXT},
- {"hash-spec-16-lru", e_APP_PIPELINE_HASH_SPEC_KEY16_LRU},
- {"hash-spec-32-ext", e_APP_PIPELINE_HASH_SPEC_KEY32_EXT},
- {"hash-spec-32-lru", e_APP_PIPELINE_HASH_SPEC_KEY32_LRU},
- {"acl", e_APP_PIPELINE_ACL},
- {"lpm", e_APP_PIPELINE_LPM},
- {"lpm-ipv6", e_APP_PIPELINE_LPM_IPV6},
- {"hash-cuckoo-8", e_APP_PIPELINE_HASH_CUCKOO_KEY8},
- {"hash-cuckoo-16", e_APP_PIPELINE_HASH_CUCKOO_KEY16},
- {"hash-cuckoo-32", e_APP_PIPELINE_HASH_CUCKOO_KEY32},
- {"hash-cuckoo-48", e_APP_PIPELINE_HASH_CUCKOO_KEY48},
- {"hash-cuckoo-64", e_APP_PIPELINE_HASH_CUCKOO_KEY64},
- {"hash-cuckoo-80", e_APP_PIPELINE_HASH_CUCKOO_KEY80},
- {"hash-cuckoo-96", e_APP_PIPELINE_HASH_CUCKOO_KEY96},
- {"hash-cuckoo-112", e_APP_PIPELINE_HASH_CUCKOO_KEY112},
- {"hash-cuckoo-128", e_APP_PIPELINE_HASH_CUCKOO_KEY128},
-};
-
-int
-app_parse_args(int argc, char **argv)
-{
- int opt, ret;
- char **argvopt;
- int option_index;
- char *prgname = argv[0];
- static struct option lgopts[] = {
- {"none", 0, 0, 0},
- {"stub", 0, 0, 0},
- {"hash-8-ext", 0, 0, 0},
- {"hash-8-lru", 0, 0, 0},
- {"hash-16-ext", 0, 0, 0},
- {"hash-16-lru", 0, 0, 0},
- {"hash-32-ext", 0, 0, 0},
- {"hash-32-lru", 0, 0, 0},
- {"hash-spec-8-ext", 0, 0, 0},
- {"hash-spec-8-lru", 0, 0, 0},
- {"hash-spec-16-ext", 0, 0, 0},
- {"hash-spec-16-lru", 0, 0, 0},
- {"hash-spec-32-ext", 0, 0, 0},
- {"hash-spec-32-lru", 0, 0, 0},
- {"acl", 0, 0, 0},
- {"lpm", 0, 0, 0},
- {"lpm-ipv6", 0, 0, 0},
- {"hash-cuckoo-8", 0, 0, 0},
- {"hash-cuckoo-16", 0, 0, 0},
- {"hash-cuckoo-32", 0, 0, 0},
- {"hash-cuckoo-48", 0, 0, 0},
- {"hash-cuckoo-64", 0, 0, 0},
- {"hash-cuckoo-80", 0, 0, 0},
- {"hash-cuckoo-96", 0, 0, 0},
- {"hash-cuckoo-112", 0, 0, 0},
- {"hash-cuckoo-128", 0, 0, 0},
- {NULL, 0, 0, 0}
- };
- uint32_t lcores[3], n_lcores, lcore_id, pipeline_type_provided;
-
- /* EAL args */
- n_lcores = 0;
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
- if (rte_lcore_is_enabled(lcore_id) == 0)
- continue;
-
- if (n_lcores >= 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- lcores[n_lcores] = lcore_id;
- n_lcores++;
- }
-
- if (n_lcores != 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- app.core_rx = lcores[0];
- app.core_worker = lcores[1];
- app.core_tx = lcores[2];
-
- /* Non-EAL args */
- argvopt = argv;
-
- app.pipeline_type = e_APP_PIPELINE_HASH_KEY16_LRU;
- pipeline_type_provided = 0;
-
- while ((opt = getopt_long(argc, argvopt, "p:",
- lgopts, &option_index)) != EOF) {
- switch (opt) {
- case 'p':
- if (app_parse_port_mask(optarg) < 0) {
- app_print_usage();
- return -1;
- }
- break;
-
- case 0: /* long options */
- if (!pipeline_type_provided) {
- uint32_t i;
-
- for (i = 0; i < e_APP_PIPELINES; i++) {
- if (!strcmp(lgopts[option_index].name,
- app_args_table[i].name)) {
- app.pipeline_type =
- app_args_table[i].value;
- pipeline_type_provided = 1;
- break;
- }
- }
-
- break;
- }
-
- app_print_usage();
- return -1;
-
- default:
- return -1;
- }
- }
-
- if (optind >= 0)
- argv[optind - 1] = prgname;
-
- ret = optind - 1;
- optind = 1; /* reset getopt lib */
- return ret;
-}
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
deleted file mode 100644
index 558f0e428d..0000000000
--- a/app/test-pipeline/init.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-struct app_params app = {
- /* Ports*/
- .n_ports = APP_MAX_PORTS,
- .port_rx_ring_size = 128,
- .port_tx_ring_size = 512,
-
- /* Rings */
- .ring_rx_size = 128,
- .ring_tx_size = 128,
-
- /* Buffer pool */
- .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
- .pool_size = 32 * 1024,
- .pool_cache_size = 256,
-
- /* Burst sizes */
- .burst_size_rx_read = 64,
- .burst_size_rx_write = 64,
- .burst_size_worker_read = 64,
- .burst_size_worker_write = 64,
- .burst_size_tx_read = 64,
- .burst_size_tx_write = 64,
-};
-
-static struct rte_eth_conf port_conf = {
- .rxmode = {
- .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM,
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_hf = RTE_ETH_RSS_IP,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
-};
-
-static struct rte_eth_rxconf rx_conf = {
- .rx_thresh = {
- .pthresh = 8,
- .hthresh = 8,
- .wthresh = 4,
- },
- .rx_free_thresh = 64,
- .rx_drop_en = 0,
-};
-
-static struct rte_eth_txconf tx_conf = {
- .tx_thresh = {
- .pthresh = 36,
- .hthresh = 0,
- .wthresh = 0,
- },
- .tx_free_thresh = 0,
- .tx_rs_thresh = 0,
-};
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
- app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
- app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
- if (app.pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
-
- app.rings_rx[i] = rte_ring_create(
- name,
- app.ring_rx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
-
- app.rings_tx[i] = rte_ring_create(
- name,
- app.ring_tx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static void
-app_ports_check_link(void)
-{
- uint32_t all_ports_up, i;
- char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
- all_ports_up = 1;
-
- for (i = 0; i < app.n_ports; i++) {
- struct rte_eth_link link;
- uint16_t port;
- int ret;
-
- port = app.ports[i];
- memset(&link, 0, sizeof(link));
- ret = rte_eth_link_get_nowait(port, &link);
- if (ret < 0) {
- RTE_LOG(INFO, USER1,
- "Failed to get port %u link status: %s\n",
- port, rte_strerror(-ret));
- all_ports_up = 0;
- continue;
- }
- rte_eth_link_to_str(link_status_text, sizeof(link_status_text),
- &link);
- RTE_LOG(INFO, USER1, "Port %u %s\n",
- port,
- link_status_text);
- if (link.link_status == RTE_ETH_LINK_DOWN)
- all_ports_up = 0;
- }
-
- if (all_ports_up == 0)
- rte_panic("Some NIC ports are DOWN\n");
-}
-
-static void
-app_init_ports(void)
-{
- uint32_t i;
- struct rte_eth_dev_info dev_info;
-
- /* Init NIC ports, then start the ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
- int ret;
- struct rte_eth_conf local_port_conf = port_conf;
-
- port = app.ports[i];
- RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port);
-
- ret = rte_eth_dev_info_get(port, &dev_info);
- if (ret != 0)
- rte_panic("Error during getting device (port %u) info: %s\n",
- port, rte_strerror(-ret));
-
- /* Init port */
- local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
- dev_info.flow_type_rss_offloads;
- if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
- port_conf.rx_adv_conf.rss_conf.rss_hf) {
- printf("Warning:"
- "Port %u modified RSS hash function based on hardware support,"
- "requested:%#"PRIx64" configured:%#"PRIx64"\n",
- port,
- port_conf.rx_adv_conf.rss_conf.rss_hf,
- local_port_conf.rx_adv_conf.rss_conf.rss_hf);
- }
-
- ret = rte_eth_dev_configure(
- port,
- 1,
- 1,
- &local_port_conf);
- if (ret < 0)
- rte_panic("Cannot init NIC port %u (%d)\n", port, ret);
-
- ret = rte_eth_promiscuous_enable(port);
- if (ret != 0)
- rte_panic("Cannot enable promiscuous mode for port %u: %s\n",
- port, rte_strerror(-ret));
-
- /* Init RX queues */
- ret = rte_eth_rx_queue_setup(
- port,
- 0,
- app.port_rx_ring_size,
- rte_eth_dev_socket_id(port),
- &rx_conf,
- app.pool);
- if (ret < 0)
- rte_panic("Cannot init RX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Init TX queues */
- ret = rte_eth_tx_queue_setup(
- port,
- 0,
- app.port_tx_ring_size,
- rte_eth_dev_socket_id(port),
- &tx_conf);
- if (ret < 0)
- rte_panic("Cannot init TX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Start port */
- ret = rte_eth_dev_start(port);
- if (ret < 0)
- rte_panic("Cannot start port %u (%d)\n", port, ret);
- }
-
- app_ports_check_link();
-}
-
-void
-app_init(void)
-{
- app_init_mbuf_pools();
- app_init_rings();
- app_init_ports();
-
- RTE_LOG(INFO, USER1, "Initialization completed\n");
-}
diff --git a/app/test-pipeline/main.c b/app/test-pipeline/main.c
deleted file mode 100644
index e5efafdf28..0000000000
--- a/app/test-pipeline/main.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <errno.h>
-#include <getopt.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-bool force_quit;
-
-static void
-signal_handler(int signum)
-{
- if (signum == SIGINT || signum == SIGTERM)
- force_quit = true;
-}
-
-int
-main(int argc, char **argv)
-{
- uint32_t lcore;
- uint32_t i;
- int ret;
-
- /* Init EAL */
- ret = rte_eal_init(argc, argv);
- if (ret < 0)
- return -1;
- argc -= ret;
- argv += ret;
-
- force_quit = false;
- signal(SIGINT, signal_handler);
- signal(SIGTERM, signal_handler);
-
- /* Parse application arguments (after the EAL ones) */
- ret = app_parse_args(argc, argv);
- if (ret < 0) {
- app_print_usage();
- return -1;
- }
-
- /* Init */
- app_init();
-
- /* Launch per-lcore init on every lcore */
- rte_eal_mp_remote_launch(app_lcore_main_loop, NULL, CALL_MAIN);
- RTE_LCORE_FOREACH_WORKER(lcore) {
- if (rte_eal_wait_lcore(lcore) < 0)
- return -1;
- }
-
- /* Close ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
-
- port = app.ports[i];
- printf("Closing port %d...", port);
- ret = rte_eth_dev_stop(port);
- if (ret != 0)
- printf("rte_eth_dev_stop: err=%d, port=%u\n",
- ret, port);
- rte_eth_dev_close(port);
- printf("Done\n");
- }
-
- /* Clean up the EAL */
- rte_eal_cleanup();
-
- return 0;
-}
-
-int
-app_lcore_main_loop(__rte_unused void *arg)
-{
- unsigned lcore;
-
- lcore = rte_lcore_id();
-
- if (lcore == app.core_rx) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_ACL:
- app_main_loop_rx();
- return 0;
-
- default:
- app_main_loop_rx_metadata();
- return 0;
- }
- }
-
- if (lcore == app.core_worker) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_STUB:
- app_main_loop_worker_pipeline_stub();
- return 0;
-
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- /* cases for cuckoo hash table types */
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- app_main_loop_worker_pipeline_hash();
- return 0;
-
- case e_APP_PIPELINE_ACL:
-#ifndef RTE_LIB_ACL
- rte_exit(EXIT_FAILURE, "ACL not present in build\n");
-#else
- app_main_loop_worker_pipeline_acl();
- return 0;
-#endif
-
- case e_APP_PIPELINE_LPM:
- app_main_loop_worker_pipeline_lpm();
- return 0;
-
- case e_APP_PIPELINE_LPM_IPV6:
- app_main_loop_worker_pipeline_lpm_ipv6();
- return 0;
-
- case e_APP_PIPELINE_NONE:
- default:
- app_main_loop_worker();
- return 0;
- }
- }
-
- if (lcore == app.core_tx) {
- app_main_loop_tx();
- return 0;
- }
-
- return 0;
-}
diff --git a/app/test-pipeline/main.h b/app/test-pipeline/main.h
deleted file mode 100644
index ee9c58ac4c..0000000000
--- a/app/test-pipeline/main.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-#ifndef APP_MBUF_ARRAY_SIZE
-#define APP_MBUF_ARRAY_SIZE 256
-#endif
-
-struct app_mbuf_array {
- struct rte_mbuf *array[APP_MBUF_ARRAY_SIZE];
- uint16_t n_mbufs;
-};
-
-#ifndef APP_MAX_PORTS
-#define APP_MAX_PORTS 4
-#endif
-
-struct __rte_cache_aligned app_params {
- /* CPU cores */
- uint32_t core_rx;
- uint32_t core_worker;
- uint32_t core_tx;
-
- /* Ports*/
- uint32_t ports[APP_MAX_PORTS];
- uint32_t n_ports;
- uint32_t port_rx_ring_size;
- uint32_t port_tx_ring_size;
-
- /* Rings */
- struct rte_ring *rings_rx[APP_MAX_PORTS];
- struct rte_ring *rings_tx[APP_MAX_PORTS];
- uint32_t ring_rx_size;
- uint32_t ring_tx_size;
-
- /* Internal buffers */
- struct app_mbuf_array mbuf_rx;
- struct app_mbuf_array mbuf_tx[APP_MAX_PORTS];
-
- /* Buffer pool */
- struct rte_mempool *pool;
- uint32_t pool_buffer_size;
- uint32_t pool_size;
- uint32_t pool_cache_size;
-
- /* Burst sizes */
- uint32_t burst_size_rx_read;
- uint32_t burst_size_rx_write;
- uint32_t burst_size_worker_read;
- uint32_t burst_size_worker_write;
- uint32_t burst_size_tx_read;
- uint32_t burst_size_tx_write;
-
- /* App behavior */
- uint32_t pipeline_type;
-};
-
-extern struct app_params app;
-
-extern bool force_quit;
-
-int app_parse_args(int argc, char **argv);
-void app_print_usage(void);
-void app_init(void);
-int app_lcore_main_loop(void *arg);
-
-/* Pipeline */
-enum {
- e_APP_PIPELINE_NONE = 0,
- e_APP_PIPELINE_STUB,
-
- e_APP_PIPELINE_HASH_KEY8_EXT,
- e_APP_PIPELINE_HASH_KEY8_LRU,
- e_APP_PIPELINE_HASH_KEY16_EXT,
- e_APP_PIPELINE_HASH_KEY16_LRU,
- e_APP_PIPELINE_HASH_KEY32_EXT,
- e_APP_PIPELINE_HASH_KEY32_LRU,
-
- e_APP_PIPELINE_HASH_SPEC_KEY8_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY8_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY16_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY16_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY32_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY32_LRU,
-
- e_APP_PIPELINE_ACL,
- e_APP_PIPELINE_LPM,
- e_APP_PIPELINE_LPM_IPV6,
-
- e_APP_PIPELINE_HASH_CUCKOO_KEY8,
- e_APP_PIPELINE_HASH_CUCKOO_KEY16,
- e_APP_PIPELINE_HASH_CUCKOO_KEY32,
- e_APP_PIPELINE_HASH_CUCKOO_KEY48,
- e_APP_PIPELINE_HASH_CUCKOO_KEY64,
- e_APP_PIPELINE_HASH_CUCKOO_KEY80,
- e_APP_PIPELINE_HASH_CUCKOO_KEY96,
- e_APP_PIPELINE_HASH_CUCKOO_KEY112,
- e_APP_PIPELINE_HASH_CUCKOO_KEY128,
- e_APP_PIPELINES
-};
-
-void app_main_loop_rx(void);
-void app_main_loop_rx_metadata(void);
-uint64_t test_hash(void *key,
- void *key_mask,
- uint32_t key_size,
- uint64_t seed);
-
-uint32_t test_hash_cuckoo(const void *key,
- uint32_t key_size,
- uint32_t seed);
-
-void app_main_loop_worker(void);
-void app_main_loop_worker_pipeline_stub(void);
-void app_main_loop_worker_pipeline_hash(void);
-void app_main_loop_worker_pipeline_acl(void);
-void app_main_loop_worker_pipeline_lpm(void);
-void app_main_loop_worker_pipeline_lpm_ipv6(void);
-
-void app_main_loop_tx(void);
-
-#define APP_FLUSH 0
-#ifndef APP_FLUSH
-#define APP_FLUSH 0x3FF
-#endif
-
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#endif /* _MAIN_H_ */
diff --git a/app/test-pipeline/meson.build b/app/test-pipeline/meson.build
deleted file mode 100644
index 3add6b637b..0000000000
--- a/app/test-pipeline/meson.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2019 Intel Corporation
-
-if is_windows
- build = false
- reason = 'not supported on Windows'
- subdir_done()
-endif
-
-sources = files(
- 'config.c',
- 'init.c',
- 'main.c',
- 'pipeline_acl.c',
- 'pipeline_hash.c',
- 'pipeline_lpm.c',
- 'pipeline_lpm_ipv6.c',
- 'pipeline_stub.c',
- 'runtime.c',
-)
-deps += ['pipeline', 'pci']
diff --git a/app/test-pipeline/pipeline_acl.c b/app/test-pipeline/pipeline_acl.c
deleted file mode 100644
index 9eb4053e23..0000000000
--- a/app/test-pipeline/pipeline_acl.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_acl.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-/*
- * Here we define the 'shape' of the data we're searching for,
- * by defining the meta-data of the ACL rules.
- * in this case, we're defining 5 tuples. IP addresses, ports,
- * and protocol.
- */
-struct rte_acl_field_def ipv4_field_formats[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, src_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, dst_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr) + sizeof(uint16_t),
- },
-};
-
-
-
-void
-app_main_loop_worker_pipeline_acl(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with ACL table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_acl_params table_acl_params = {
- .name = "test", /* unique identifier for acl contexts */
- .n_rules = 1 << 5,
- .n_rule_fields = DIM(ipv4_field_formats),
- };
-
- /* Copy in the rule meta-data defined above into the params */
- memcpy(table_acl_params.field_format, ipv4_field_formats,
- sizeof(ipv4_field_formats));
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_acl_ops,
- .arg_create = &table_acl_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the ACL table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_entry *entry_ptr;
- int key_found, ret;
-
- memset(&rule_params, 0, sizeof(rule_params));
-
- /* Set the rule values */
- rule_params.field_value[SRC_FIELD_IPV4].value.u32 = 0;
- rule_params.field_value[SRC_FIELD_IPV4].mask_range.u32 = 0;
- rule_params.field_value[DST_FIELD_IPV4].value.u32 =
- i << (24 - rte_popcount32(app.n_ports - 1));
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32 =
- 8 + rte_popcount32(app.n_ports - 1);
- rule_params.field_value[SRCP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[SRCP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[DSTP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[DSTP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[PROTO_FIELD_IPV4].value.u8 = 0;
- rule_params.field_value[PROTO_FIELD_IPV4].mask_range.u8 = 0;
-
- rule_params.priority = 0;
-
- uint32_t dst_addr = rule_params.field_value[DST_FIELD_IPV4].
- value.u32;
- uint32_t dst_mask =
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32;
-
- printf("Adding rule to ACL table (IPv4 destination = "
- "%u.%u.%u.%u/%u => port out = %u)\n",
- (dst_addr & 0xFF000000) >> 24,
- (dst_addr & 0x00FF0000) >> 16,
- (dst_addr & 0x0000FF00) >> 8,
- dst_addr & 0x000000FF,
- dst_mask,
- table_entry.port_id);
-
- /* For ACL, add needs an rte_table_acl_rule_add_params struct */
- ret = rte_pipeline_table_entry_add(p, table_id, &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, ret);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
deleted file mode 100644
index 194e5c5dcc..0000000000
--- a/app/test-pipeline/pipeline_hash.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_hash.h>
-#include <rte_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-static void
-translate_options(uint32_t *special, uint32_t *ext, uint32_t *key_size)
-{
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- *special = 0; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- *special = 0; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- *special = 0; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- *special = 0; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- *special = 1; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- *special = 1; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- *special = 1; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- *special = 1; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- *special = 1; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- *special = 1; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- *special = 0; *ext = 0; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- *special = 0; *ext = 0; *key_size = 48; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- *special = 0; *ext = 0; *key_size = 64; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- *special = 0; *ext = 0; *key_size = 80; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- *special = 0; *ext = 0; *key_size = 96; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- *special = 0; *ext = 0; *key_size = 112; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- *special = 0; *ext = 0; *key_size = 128; return;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-}
-void
-app_main_loop_worker_pipeline_hash(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
- uint32_t special, ext, key_size;
-
- translate_options(&special, &ext, &key_size);
-
- RTE_LOG(INFO, USER1, "Core %u is doing work "
- "(pipeline with hash table, %s, %s, %d-byte key)\n",
- rte_lcore_id(),
- special ? "specialized" : "non-specialized",
- ext ? "extendible bucket" : "LRU",
- key_size);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- struct rte_table_hash_params table_hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash,
- .seed = 0,
- };
-
- struct rte_table_hash_cuckoo_params table_hash_cuckoo_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash_cuckoo,
- .seed = 0,
- };
-
- /* Table configuration */
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table)\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_cuckoo_ops,
- .arg_create = &table_hash_cuckoo_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < (1 << 24); i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_pipeline_table_entry *entry_ptr;
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) key;
- int key_found, status;
-
- memset(key, 0, sizeof(key));
- k32[0] = rte_be_to_cpu_32(i);
-
- status = rte_pipeline_table_entry_add(p, table_id, key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
-
-uint64_t test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-uint32_t test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-void
-app_main_loop_rx_metadata(void) {
- uint32_t i, j;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX (with meta-data)\n",
- rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- for (j = 0; j < n_mbufs; j++) {
- struct rte_mbuf *m;
- uint8_t *m_data, *key;
- struct rte_ipv4_hdr *ip_hdr;
- struct rte_ipv6_hdr *ipv6_hdr;
- uint32_t ip_dst;
- uint32_t *signature, *k32;
-
- m = app.mbuf_rx.array[j];
- m_data = rte_pktmbuf_mtod(m, uint8_t *);
- signature = RTE_MBUF_METADATA_UINT32_PTR(m,
- APP_METADATA_OFFSET(0));
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
- ip_hdr = (struct rte_ipv4_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
- ip_dst = ip_hdr->dst_addr;
-
- k32 = (uint32_t *) key;
- k32[0] = ip_dst & 0xFFFFFF00;
- } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
- ipv6_hdr = (struct rte_ipv6_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
-
- memcpy(key, &ipv6_hdr->dst_addr, 16);
- } else
- continue;
-
- *signature = test_hash(key, NULL, 0, 0);
- }
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
diff --git a/app/test-pipeline/pipeline_lpm.c b/app/test-pipeline/pipeline_lpm.c
deleted file mode 100644
index 8a59bd0042..0000000000
--- a/app/test-pipeline/pipeline_lpm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-#ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s
-#define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256
-#endif
-
-void
-app_main_loop_worker_pipeline_lpm(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with "
- "LPM table)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_params table_lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s,
- .flags = 0,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ops,
- .arg_create = &table_lpm_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_key key = {
- .ip = i << (24 - rte_popcount32(app.n_ports - 1)),
- .depth = 8 + rte_popcount32(app.n_ports - 1),
- };
-
- struct rte_pipeline_table_entry *entry_ptr;
-
- int key_found, status;
-
- printf("Adding rule to LPM table (IPv4 destination = %"
- PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8
- " => port out = %" PRIu32 ")\n",
- (key.ip & 0xFF000000) >> 24,
- (key.ip & 0x00FF0000) >> 16,
- (key.ip & 0x0000FF00) >> 8,
- key.ip & 0x000000FF,
- key.depth,
- i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_lpm_ipv6.c b/app/test-pipeline/pipeline_lpm_ipv6.c
deleted file mode 100644
index 6558e887c8..0000000000
--- a/app/test-pipeline/pipeline_lpm_ipv6.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_lpm_ipv6(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with IPv6 LPM table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_ipv6_params table_lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 21,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ipv6_ops,
- .arg_create = &table_lpm_ipv6_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the IPv6 LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_ipv6_key key;
- struct rte_pipeline_table_entry *entry_ptr;
- uint32_t ip;
- int key_found, status;
-
- key.depth = 8 + rte_popcount32(app.n_ports - 1);
-
- ip = rte_bswap32(i << (24 -
- rte_popcount32(app.n_ports - 1)));
- memcpy(&key.ip, &ip, sizeof(uint32_t));
-
- printf("Adding rule to IPv6 LPM table (IPv6 destination = "
- RTE_IPV6_ADDR_FMT "/%u => port out = %u)\n",
- RTE_IPV6_ADDR_SPLIT(&key.ip),
- key.depth, i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_stub.c b/app/test-pipeline/pipeline_stub.c
deleted file mode 100644
index 48a638aad7..0000000000
--- a/app/test-pipeline/pipeline_stub.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_port_ring.h>
-#include <rte_table_stub.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_stub(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id[APP_MAX_PORTS];
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with stub "
- "tables)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i]))
- rte_panic("Unable to configure table %u\n", i);
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i]))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i ^ 1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (rte_pipeline_table_default_entry_add(p, table_id[i], &entry,
- &default_entry_ptr))
- rte_panic("Unable to add default entry to table %u\n",
- table_id[i]);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/runtime.c b/app/test-pipeline/runtime.c
deleted file mode 100644
index 752f783370..0000000000
--- a/app/test-pipeline/runtime.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_malloc.h>
-
-#include "main.h"
-
-void
-app_main_loop_rx(void) {
- uint32_t i;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs, NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_worker(void) {
- struct app_mbuf_array *worker_mbuf;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (no pipeline)\n",
- rte_lcore_id());
-
- worker_mbuf = rte_malloc_socket(NULL, sizeof(struct app_mbuf_array),
- RTE_CACHE_LINE_SIZE, rte_socket_id());
- if (worker_mbuf == NULL)
- rte_panic("Worker thread: cannot allocate buffer space\n");
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- int ret;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_rx[i],
- (void **) worker_mbuf->array,
- app.burst_size_worker_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_tx[i ^ 1],
- (void **) worker_mbuf->array,
- app.burst_size_worker_write,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_tx(void) {
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing TX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs, n_pkts;
- int ret;
-
- n_mbufs = app.mbuf_tx[i].n_mbufs;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_tx[i],
- (void **) &app.mbuf_tx[i].array[n_mbufs],
- app.burst_size_tx_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- n_mbufs += app.burst_size_tx_read;
-
- if (n_mbufs < app.burst_size_tx_write) {
- app.mbuf_tx[i].n_mbufs = n_mbufs;
- continue;
- }
-
- n_pkts = rte_eth_tx_burst(
- app.ports[i],
- 0,
- app.mbuf_tx[i].array,
- n_mbufs);
-
- if (n_pkts < n_mbufs) {
- uint16_t k;
-
- for (k = n_pkts; k < n_mbufs; k++) {
- struct rte_mbuf *pkt_to_free;
-
- pkt_to_free = app.mbuf_tx[i].array[k];
- rte_pktmbuf_free(pkt_to_free);
- }
- }
-
- app.mbuf_tx[i].n_mbufs = 0;
- }
- }
-}
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 938617ca75..10e4352cac 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -68,6 +68,9 @@ Removed Items
Also, make sure to start the actual text at the margin.
=======================================================
+* Removed the ``dpdk-test-pipeline`` application, which was based on
+ the legacy pipeline library API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/img/test_pipeline_app.png b/doc/guides/sample_app_ug/img/test_pipeline_app.png
deleted file mode 100644
index d322a9e46e5e714126988a76456c9eae41635879..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 67410
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%0D%V3H
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"Exg8HvZ0ke@W&Fw<
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
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index f12623bb66..c8b50b801c 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -45,7 +45,6 @@ Sample Applications User Guides
vhost_crypto
vdpa
ip_pipeline
- test_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/test_pipeline.rst b/doc/guides/sample_app_ug/test_pipeline.rst
deleted file mode 100644
index e53d77a170..0000000000
--- a/doc/guides/sample_app_ug/test_pipeline.rst
+++ /dev/null
@@ -1,237 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2010-2014 Intel Corporation.
-
-Test Pipeline Application
-=========================
-
-The Test Pipeline application illustrates the use of the DPDK Packet Framework tool suite.
-Its purpose is to demonstrate the performance of single-table DPDK pipelines.
-
-Overview
---------
-
-The application uses three CPU cores:
-
-* Core A ("RX core") receives traffic from the NIC ports and feeds core B with traffic through SW queues.
-
-* Core B ("Pipeline core") implements a single-table DPDK pipeline
- whose type is selectable through specific command line parameter.
- Core B receives traffic from core A through software queues,
- processes it according to the actions configured in the table entries that
- are hit by the input packets and feeds it to core C through another set of software queues.
-
-* Core C ("TX core") receives traffic from core B through software queues and sends it to the NIC ports for transmission.
-
-.. figure:: img/test_pipeline_app.*
-
- Test Pipeline Application
-
-Compiling the Application
--------------------------
-To compile the sample application see :doc:`compiling`
-
-The application is located in the ``dpdk/<build_dir>/app`` directory.
-
-
-Running the Application
------------------------
-
-Application Command Line
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The application execution command line is:
-
-.. code-block:: console
-
- ./dpdk-test-pipeline [EAL options] -- -p PORTMASK --TABLE_TYPE
-
-The ``-l/--lcores`` EAL CPU corelist option has to contain exactly 3 CPU cores.
-The first CPU core in the core mask is assigned for core A, the second for core B and the third for core C.
-
-The PORTMASK parameter must contain 2 or 4 ports.
-
-Table Types and Behavior
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-:numref:`test_pipeline_table_1` describes the table types used and how they are populated.
-
-The hash tables are pre-populated with 16 million keys.
-For hash tables, the following parameters can be selected:
-
-* **Configurable key size implementation or fixed (specialized) key size implementation (e.g. hash-8-ext or hash-spec-8-ext).**
- The key size specialized implementations are expected to provide better performance for 8-byte and 16-byte key sizes,
- while the key-size-non-specialized implementation is expected to provide better performance for larger key sizes;
-
-* **Key size (e.g. hash-spec-8-ext or hash-spec-16-ext).**
- The available options are 8, 16 and 32 bytes;
-
-* **Table type (e.g. hash-spec-16-ext or hash-spec-16-lru).**
- The available options are ext (extendable bucket) or lru (least recently used).
-
-.. _test_pipeline_table_1:
-
-.. table:: Table Types
-
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | **#** | **TABLE_TYPE** | **Description of Core B Table** | **Pre-added Table Entries** |
- | | | | |
- +=======+========================+==========================================================+=======================================================+
- | 1 | none | Core B is not implementing a DPDK pipeline. | N/A |
- | | | Core B is implementing a pass-through from its input set | |
- | | | of software queues to its output set of software queues. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 2 | stub | Stub table. Core B is implementing the same pass-through | N/A |
- | | | functionality as described for the "none" option by | |
- | | | using the DPDK Packet Framework by using one | |
- | | | stub table for each input NIC port. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 3 | hash-[spec]-8-lru | LRU hash table with 8-byte key size and 16 million | 16 million entries are successfully added to the |
- | | | entries. | hash table with the following key format: |
- | | | | |
- | | | | [4-byte index, 4 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Sendto output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | core B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 4 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 4 | hash-[spec]-8-ext | Extendable bucket hash table with 8-byte key size | Same as hash-[spec]-8-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 5 | hash-[spec]-16-lru | LRU hash table with 16-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 12 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for core |
- | | | | B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 12 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 6 | hash-[spec]-16-ext | Extendable bucket hash table with 16-byte key size | Same as hash-[spec]-16-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 7 | hash-[spec]-32-lru | LRU hash table with 32-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 28 bytes of 0]. |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | Lpmcore B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 28 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 8 | hash-[spec]-32-ext | Extendable bucket hash table with 32-byte key size | Same as hash-[spec]-32-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 9 | lpm | Longest Prefix Match (LPM) IPv4 table. | In the case of two ports, two routes |
- | | | | are added to the table: |
- | | | | |
- | | | | [0.0.0.0/9 => send to output port 0] |
- | | | | |
- | | | | [0.128.0.0/9 => send to output port 1] |
- | | | | |
- | | | | In case of four ports, four entries are added to the |
- | | | | table: |
- | | | | |
- | | | | [0.0.0.0/10 => send to output port 0] |
- | | | | |
- | | | | [0.64.0.0/10 => send to output port 1] |
- | | | | |
- | | | | [0.128.0.0/10 => send to output port 2] |
- | | | | |
- | | | | [0.192.0.0/10 => send to output port 3] |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is storing the IPv4 destination |
- | | | | within the packet meta data to be later used by core |
- | | | | B as the lookup key. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 10 | acl | Access Control List (ACL) table | In the case of two ports, two ACL rules are added to |
- | | | | the table: |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.0.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0] |
- | | | | |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.128.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0]. |
- | | | | |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
-
-Input Traffic
-~~~~~~~~~~~~~
-
-Regardless of the table type used for the core B pipeline,
-the same input traffic can be used to hit all table entries with uniform distribution,
-which results in uniform distribution of packets sent out on the set of output NIC ports.
-The profile for input traffic is TCP/IPv4 packets with:
-
-* destination IP address as A.B.C.D with A fixed to 0 and B, C,D random
-
-* source IP address fixed to 0.0.0.0
-
-* destination TCP port fixed to 0
-
-* source TCP port fixed to 0
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC 3/6] examples/ip_pipeline: remove example
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
2026-07-24 16:43 ` [RFC 1/6] app/test: remove packet framework tests Stephen Hemminger
2026-07-24 16:43 ` [RFC 2/6] app/test-pipeline: remove application Stephen Hemminger
@ 2026-07-24 16:43 ` Stephen Hemminger
2026-07-24 16:44 ` [RFC 4/6] pipeline: remove legacy API Stephen Hemminger
` (12 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-24 16:43 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon, Cristian Dumitrescu
The ip_pipeline example is built on the legacy pipeline library
API (rte_pipeline_*) and the associated port and table action
APIs, which were announced for removal in the 24.11 release.
The pipeline example covers the SWX pipeline API.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
doc/guides/nics/softnic.rst | 3 +-
doc/guides/rel_notes/release_26_11.rst | 4 +
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
examples/ip_pipeline/Makefile | 60 -
examples/ip_pipeline/action.c | 391 -
examples/ip_pipeline/action.h | 78 -
examples/ip_pipeline/cli.c | 6791 -----------------
examples/ip_pipeline/cli.h | 18 -
examples/ip_pipeline/common.h | 12 -
examples/ip_pipeline/conn.c | 330 -
examples/ip_pipeline/conn.h | 47 -
examples/ip_pipeline/cryptodev.c | 160 -
examples/ip_pipeline/cryptodev.h | 46 -
examples/ip_pipeline/examples/firewall.cli | 59 -
examples/ip_pipeline/examples/flow.cli | 60 -
examples/ip_pipeline/examples/flow_crypto.cli | 57 -
examples/ip_pipeline/examples/l2fwd.cli | 51 -
examples/ip_pipeline/examples/route.cli | 60 -
examples/ip_pipeline/examples/route_ecmp.cli | 57 -
| 112 -
examples/ip_pipeline/examples/tap.cli | 66 -
examples/ip_pipeline/link.c | 270 -
examples/ip_pipeline/link.h | 66 -
examples/ip_pipeline/main.c | 260 -
examples/ip_pipeline/mempool.c | 82 -
examples/ip_pipeline/mempool.h | 40 -
examples/ip_pipeline/meson.build | 30 -
examples/ip_pipeline/parser.c | 506 --
examples/ip_pipeline/parser.h | 56 -
examples/ip_pipeline/pipeline.c | 1078 ---
examples/ip_pipeline/pipeline.h | 425 --
examples/ip_pipeline/swq.c | 76 -
examples/ip_pipeline/swq.h | 37 -
examples/ip_pipeline/tap.c | 102 -
examples/ip_pipeline/tap.h | 29 -
examples/ip_pipeline/thread.c | 3137 --------
examples/ip_pipeline/thread.h | 24 -
examples/ip_pipeline/tmgr.c | 248 -
examples/ip_pipeline/tmgr.h | 74 -
examples/meson.build | 1 -
42 files changed, 5 insertions(+), 15532 deletions(-)
delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
delete mode 100644 examples/ip_pipeline/Makefile
delete mode 100644 examples/ip_pipeline/action.c
delete mode 100644 examples/ip_pipeline/action.h
delete mode 100644 examples/ip_pipeline/cli.c
delete mode 100644 examples/ip_pipeline/cli.h
delete mode 100644 examples/ip_pipeline/common.h
delete mode 100644 examples/ip_pipeline/conn.c
delete mode 100644 examples/ip_pipeline/conn.h
delete mode 100644 examples/ip_pipeline/cryptodev.c
delete mode 100644 examples/ip_pipeline/cryptodev.h
delete mode 100644 examples/ip_pipeline/examples/firewall.cli
delete mode 100644 examples/ip_pipeline/examples/flow.cli
delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
delete mode 100644 examples/ip_pipeline/examples/route.cli
delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
delete mode 100644 examples/ip_pipeline/examples/rss.cli
delete mode 100644 examples/ip_pipeline/examples/tap.cli
delete mode 100644 examples/ip_pipeline/link.c
delete mode 100644 examples/ip_pipeline/link.h
delete mode 100644 examples/ip_pipeline/main.c
delete mode 100644 examples/ip_pipeline/mempool.c
delete mode 100644 examples/ip_pipeline/mempool.h
delete mode 100644 examples/ip_pipeline/meson.build
delete mode 100644 examples/ip_pipeline/parser.c
delete mode 100644 examples/ip_pipeline/parser.h
delete mode 100644 examples/ip_pipeline/pipeline.c
delete mode 100644 examples/ip_pipeline/pipeline.h
delete mode 100644 examples/ip_pipeline/swq.c
delete mode 100644 examples/ip_pipeline/swq.h
delete mode 100644 examples/ip_pipeline/tap.c
delete mode 100644 examples/ip_pipeline/tap.h
delete mode 100644 examples/ip_pipeline/thread.c
delete mode 100644 examples/ip_pipeline/thread.h
delete mode 100644 examples/ip_pipeline/tmgr.c
delete mode 100644 examples/ip_pipeline/tmgr.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 4c06f85706..ae84e7f289 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,9 +1739,7 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: examples/ip_pipeline/
F: examples/pipeline/
-F: doc/guides/sample_app_ug/ip_pipeline.rst
Algorithms
diff --git a/doc/guides/nics/softnic.rst b/doc/guides/nics/softnic.rst
index 603fdb49c4..87f3e5adc0 100644
--- a/doc/guides/nics/softnic.rst
+++ b/doc/guides/nics/softnic.rst
@@ -10,8 +10,7 @@ is DIY and reconfigurable through ``firmware`` (DPDK Packet Framework script).
The Soft NIC leverages the DPDK Packet Framework libraries (librte_port,
librte_table and librte_pipeline) to make it modular, flexible and extensible
with new functionality.
-Please refer to :doc:`/prog_guide/packet_framework` and
-:doc:`/sample_app_ug/ip_pipeline` for more details.
+Please refer to :doc:`/prog_guide/packet_framework` for more details.
The Soft NIC is configured through the standard DPDK ethdev API (ethdev, flow,
QoS, security). The internal framework is not externally visible.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 10e4352cac..4cc1cec108 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -71,6 +71,10 @@ Removed Items
* Removed the ``dpdk-test-pipeline`` application, which was based on
the legacy pipeline library API.
+* Removed the ``ip_pipeline`` example application, which was based on
+ the legacy pipeline library API.
+ The ``pipeline`` example application covers the SWX pipeline API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index c8b50b801c..28c4c9a5b2 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -44,7 +44,6 @@ Sample Applications User Guides
vhost_blk
vhost_crypto
vdpa
- ip_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/ip_pipeline.rst b/doc/guides/sample_app_ug/ip_pipeline.rst
deleted file mode 100644
index 9a5cb517a2..0000000000
--- a/doc/guides/sample_app_ug/ip_pipeline.rst
+++ /dev/null
@@ -1,531 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2015-2018 Intel Corporation.
-
-Internet Protocol (IP) Pipeline Application
-===========================================
-
-Application overview
---------------------
-
-The *Internet Protocol (IP) Pipeline* application is intended to be a vehicle for rapid development of packet processing
-applications on multi-core CPUs.
-
-Following OpenFlow and P4 design principles, the application can be used to create functional blocks called pipelines out
-of input/output ports, tables and actions in a modular way. Multiple pipelines can be inter-connected through packet queues
-to create complete applications (super-pipelines).
-
-The pipelines are mapped to application threads, with each pipeline executed by a single thread and each thread able to run
-one or several pipelines. The possibilities of creating pipelines out of ports, tables and actions, connecting multiple
-pipelines together and mapping the pipelines to execution threads are endless, therefore this application can be seen as
-a true application generator.
-
-Pipelines are created and managed through Command Line Interface (CLI):
-
- * Any standard TCP client (e.g. telnet, netcat, custom script, etc) is typically able to connect to the application, send
- commands through the network and wait for the response before pushing the next command.
-
- * All the application objects are created and managed through CLI commands:
- * 'Primitive' objects used to create pipeline ports: memory pools, links (i.e. network interfaces), SW queues, traffic managers, etc.
- * Action profiles: used to define the actions to be executed by pipeline input/output ports and tables.
- * Pipeline components: input/output ports, tables, pipelines, mapping of pipelines to execution threads.
-
-Running the application
------------------------
-
-The application startup command line is::
-
- dpdk-ip_pipeline [EAL_ARGS] -- [-s SCRIPT_FILE] [-h HOST] [-p PORT]
-
-The application startup arguments are:
-
-``-s SCRIPT_FILE``
-
- * Optional: Yes
-
- * Default: Not present
-
- * Argument: Path to the CLI script file to be run at application startup.
- No CLI script file will run at startup if this argument is not present.
-
-``-h HOST``
-
- * Optional: Yes
-
- * Default: ``0.0.0.0``
-
- * Argument: IP Address of the host running ip pipeline application to be used by
- remote TCP based client (telnet, netcat, etc.) for connection.
-
-``-p PORT``
-
- * Optional: Yes
-
- * Default: ``8086``
-
- * Argument: TCP port number at which the ip pipeline is running.
- This port number should be used by remote TCP client (such as telnet, netcat, etc.) to connect to host application.
-
-Refer to *DPDK Getting Started Guide* for general information on running applications and the Environment Abstraction Layer (EAL) options.
-
-The following is an example command to run ip pipeline application configured for layer 2 forwarding:
-
-.. code-block:: console
-
- $ ./<build_dir>/examples/dpdk-ip_pipeline -l 0,1 -- -s examples/route_ecmp.cli
-
-The application should start successfully and display as follows:
-
-.. code-block:: console
-
- EAL: Detected 40 lcore(s)
- EAL: Detected 2 NUMA nodes
- EAL: Multi-process socket /var/run/.rte_unix
- EAL: Probing VFIO support...
- EAL: PCI device 0000:02:00.0 on NUMA socket 0
- EAL: probe driver: 8086:10fb net_ixgbe
- ...
-
-To run remote client (e.g. telnet) to communicate with the ip pipeline application:
-
-.. code-block:: console
-
- $ telnet 127.0.0.1 8086
-
-When running a telnet client as above, command prompt is displayed:
-
-.. code-block:: console
-
- Trying 127.0.0.1...
- Connected to 127.0.0.1.
- Escape character is '^]'.
-
- Welcome to IP Pipeline!
-
- pipeline>
-
-Once application and telnet client start running, messages can be sent from client to application.
-At any stage, telnet client can be terminated using the quit command.
-
-
-Application stages
-------------------
-
-Initialization
-~~~~~~~~~~~~~~
-
-During this stage, EAL layer is initialised and application specific arguments are parsed. Furthermore, the data structures
-(i.e. linked lists) for application objects are initialized. In case of any initialization error, an error message
-is displayed and the application is terminated.
-
-Run-time
-~~~~~~~~
-
-The main thread is creating and managing all the application objects based on CLI input.
-
-Each data plane thread runs one or several pipelines previously assigned to it in round-robin order. Each data plane thread
-executes two tasks in time-sharing mode:
-
-#. *Packet processing task*: Process bursts of input packets read from the pipeline input ports.
-
-#. *Message handling task*: Periodically, the data plane thread pauses the packet processing task and polls for request
- messages send by the main thread. Examples: add/remove pipeline to/from current data plane thread, add/delete rules
- to/from given table of a specific pipeline owned by the current data plane thread, read statistics, etc.
-
-Examples
---------
-
-.. tabularcolumns:: |p{3cm}|p{5cm}|p{4cm}|p{4cm}|
-
-.. table:: Pipeline examples provided with the application
-
- +-----------------------+----------------------+----------------+------------------------------------+
- | Name | Table(s) | Actions | Messages |
- +=======================+======================+================+====================================+
- | L2fwd | Stub | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | Note: Implemented | | | 3. Pipeline create |
- | using pipeline with | | | 4. Pipeline port in/out |
- | a simple pass-through | | | 5. Pipeline table |
- | connection between | | | 6. Pipeline port in table |
- | input and output | | | 7. Pipeline enable |
- | ports. | | | 8. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Flow classification | Exact match | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = byte array | | 3. Pipeline create |
- | | (16 bytes) | | 4. Pipeline port in/out |
- | | * Offset = 278 | | 5. Pipeline table |
- | | * Table size = 64K | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Firewall | ACL | Allow/Drop | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = n-tuple | | 3. Pipeline create |
- | | * Offset = 270 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | IP routing | LPM (IPv4) | Forward | 1. Mempool Create |
- | | | | 2. Link create |
- | | * Key = IP dest addr | | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Equal-cost multi-path | LPM (IPv4) | Forward, | 1. Mempool Create |
- | routing (ECMP) | | load balance, | 2. Link create |
- | | * Key = IP dest addr | encap ether | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table (LPM) |
- | | | | 6. Pipeline table (Array) |
- | | | | 7. Pipeline port in table (LPM) |
- | | Array | | 8. Pipeline enable |
- | | | | 9. Pipeline table rule add default |
- | | * Key = Array index | | 10. Pipeline table rule add(LPM) |
- | | * Offset = 256 | | 11. Pipeline table rule add(Array) |
- | | * Size = 64K | | |
- | | | | |
- +-----------------------+----------------------+----------------+------------------------------------+
-
-Command Line Interface (CLI)
-----------------------------
-
-Link
-~~~~
-
- Link configuration ::
-
- link <link_name>
- dev <device_name>|port <port_id>
- rxq <n_queues> <queue_size> <mempool_name>
- txq <n_queues> <queue_size> promiscuous on | off
- [rss <qid_0> ... <qid_n>]
-
- Note: The PCI device name must be specified in the Domain:Bus:Device.Function format.
-
-
-Mempool
-~~~~~~~
-
- Mempool create ::
-
- mempool <mempool_name> buffer <buffer_size>
- pool <pool_size> cache <cache_size> cpu <cpu_id>
-
-
-Software queue
-~~~~~~~~~~~~~~
-
- Create software queue ::
-
- swq <swq_name> size <size> cpu <cpu_id>
-
-
-Traffic manager
-~~~~~~~~~~~~~~~
-
- Add traffic manager subport profile ::
-
- tmgr subport profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
-
- Add traffic manager pipe profile ::
-
- tmgr pipe profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
- <tc_ov_weight>
- <wrr_weight0..3>
-
- Create traffic manager port ::
-
- tmgr <tmgr_name>
- rate <rate>
- spp <n_subports_per_port>
- pps <n_pipes_per_subport>
- fo <frame_overhead>
- mtu <mtu>
- cpu <cpu_id>
-
- Configure traffic manager subport ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- profile <subport_profile_id>
-
- Configure traffic manager pipe ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- pipe from <pipe_id_first> to <pipe_id_last>
- profile <pipe_profile_id>
-
-
-Tap
-~~~
-
- Create tap port ::
-
- tap <name>
-
-
-Cryptodev
-~~~~~~~~~
-
- Create cryptodev port ::
-
- cryptodev <cryptodev_name>
- dev <DPDK Cryptodev PMD name>
- queue <n_queues> <queue_size>
-
-Action profile
-~~~~~~~~~~~~~~
-
- Create action profile for pipeline input port ::
-
- port in action profile <profile_name>
- [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
- [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
-
- Create action profile for the pipeline table ::
-
- table action profile <profile_name>
- ipv4 | ipv6
- offset <ip_offset>
- fwd
- [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
- [meter srtcm | trtcm
- tc <n_tc>
- stats none | pkts | bytes | both]
- [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
- [encap ether | vlan | qinq | mpls | pppoe]
- [nat src | dst
- proto udp | tcp]
- [ttl drop | fwd
- stats none | pkts]
- [stats pkts | bytes | both]
- [sym_crypto cryptodev <cryptodev_name>
- mempool_create <mempool_name> mempool_init <mempool_name>]
- [time]
-
-
-Pipeline
-~~~~~~~~
-
-Create pipeline ::
-
- pipeline <pipeline_name>
- period <timer_period_ms>
- offset_port_id <offset_port_id>
- cpu <cpu_id>
-
-Create pipeline input port ::
-
- pipeline <pipeline_name> port in
- bsz <burst_size>
- link <link_name> rxq <queue_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name> mempool <mempool_name> mtu <mtu>
- | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
- [action <port_in_action_profile_name>]
- [disabled]
-
-Create pipeline output port ::
-
- pipeline <pipeline_name> port out
- bsz <burst_size>
- link <link_name> txq <txq_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name>
- | sink [file <file_name> pkts <max_n_pkts>]
-
-Create pipeline table ::
-
- pipeline <pipeline_name> table
- match
- acl
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | array
- offset <key_offset>
- size <n_keys>
- | hash
- ext | lru
- key <key_size>
- mask <key_mask>
- offset <key_offset>
- buckets <n_buckets>
- size <n_keys>
- | lpm
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | stub
- [action <table_action_profile_name>]
-
-Connect pipeline input port to table ::
-
- pipeline <pipeline_name> port in <port_id> table <table_id>
-
-Display statistics for specific pipeline input port, output port
-or table ::
-
- pipeline <pipeline_name> port in <port_id> stats read [clear]
- pipeline <pipeline_name> port out <port_id> stats read [clear]
- pipeline <pipeline_name> table <table_id> stats read [clear]
-
-Enable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Disable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Add default rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
- match
- default
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
-
-Add rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
-
- match
- acl
- priority <priority>
- ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- <sp0> <sp1> <dp0> <dp1> <proto>
- | array <pos>
- | hash
- raw <key>
- | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv4_addr <addr>
- | ipv6_addr <addr>
- | qinq <svlan> <cvlan>
- | lpm
- ipv4 | ipv6 <addr> <depth>
-
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
- [balance <out0> ... <out7>]
- [meter
- tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- [tm subport <subport_id> pipe <pipe_id>]
- [encap
- ether <da> <sa>
- | vlan <da> <sa> <pcp> <dei> <vid>
- | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- | mpls unicast | multicast
- <da> <sa>
- label0 <label> <tc> <ttl>
- [label1 <label> <tc> <ttl>
- [label2 <label> <tc> <ttl>
- [label3 <label> <tc> <ttl>]]]
- | pppoe <da> <sa> <session_id>]
- [nat ipv4 | ipv6 <addr> <port>]
- [ttl dec | keep]
- [stats]
- [time]
- [sym_crypto
- encrypt | decrypt
- type
- | cipher
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- | cipher_auth
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- auth_algo <algo> auth_key <key> digest_size <size>
- | aead
- aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- digest_size <size>
- data_offset <data_offset>]
-
- where:
- <pa> ::= g | y | r | drop
-
-Add bulk rules to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
-
- Where:
- - file_name = path to file
- - File line format = match <match> action <action>
-
-Delete table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match <match>
-
-Delete default table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match
- default
-
-Add meter profile to the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
- add srtcm cir <cir> cbs <cbs> ebs <ebs>
- | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
-
-Delete meter profile from the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id>
- meter profile <meter_profile_id> delete
-
-
-Update the dscp table for meter or traffic manager action for specific
-pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> dscp <file_name>
-
- Where:
- - file_name = path to file
- - exactly 64 lines
- - File line format = <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
-
-
-Pipeline enable/disable
-~~~~~~~~~~~~~~~~~~~~~~~
-
- Enable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> enable
-
-
- Disable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> disable
diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
deleted file mode 100644
index 438aa6b37f..0000000000
--- a/examples/ip_pipeline/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2010-2018 Intel Corporation
-
-# binary name
-APP = ip_pipeline
-
-# all source are stored in SRCS-y
-SRCS-y := action.c
-SRCS-y += cli.c
-SRCS-y += conn.c
-SRCS-y += link.c
-SRCS-y += main.c
-SRCS-y += mempool.c
-SRCS-y += parser.c
-SRCS-y += pipeline.c
-SRCS-y += swq.c
-SRCS-y += tap.c
-SRCS-y += thread.c
-SRCS-y += tmgr.c
-SRCS-y += cryptodev.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)
-
-CFLAGS += -I. -DALLOW_EXPERIMENTAL_API -D_GNU_SOURCE
-
-OBJS := $(patsubst %.c,build/%.o,$(SRCS-y))
-
-build/%.o: %.c Makefile $(PC_FILE) | build
- $(CC) $(CFLAGS) -c $< -o $@
-
-build/$(APP)-shared: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
-
-build/$(APP)-static: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
-
-build:
- @mkdir -p $@
-
-.PHONY: clean
-clean:
- rm -f build/$(APP)* build/*.o
- test -d build && rmdir -p build || true
diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
deleted file mode 100644
index d2104aad6e..0000000000
--- a/examples/ip_pipeline/action.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-#include <rte_table_hash_func.h>
-
-#include "action.h"
-
-/**
- * Input port
- */
-static struct port_in_action_profile_list port_in_action_profile_list;
-
-int
-port_in_action_profile_init(void)
-{
- TAILQ_INIT(&port_in_action_profile_list);
-
- return 0;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name)
-{
- struct port_in_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &port_in_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params)
-{
- struct port_in_action_profile *profile;
- struct rte_port_in_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- port_in_action_profile_find(name) ||
- (params == NULL))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
- /* Resource */
- ap = rte_port_in_action_profile_create(0);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_FLTR,
- ¶ms->fltr);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_port_in_action_profile_freeze(ap);
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct port_in_action_profile));
- if (profile == NULL) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&port_in_action_profile_list, profile, node);
-
- return profile;
-}
-
-/**
- * Table
- */
-static struct table_action_profile_list table_action_profile_list;
-
-int
-table_action_profile_init(void)
-{
- TAILQ_INIT(&table_action_profile_list);
-
- return 0;
-}
-
-struct table_action_profile *
-table_action_profile_find(const char *name)
-{
- struct table_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &table_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params)
-{
- struct table_action_profile *profile;
- struct rte_table_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- table_action_profile_find(name) ||
- (params == NULL) ||
- ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
-
- /* Resource */
- ap = rte_table_action_profile_create(¶ms->common);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_FWD,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_MTR,
- ¶ms->mtr);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TM,
- ¶ms->tm);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_ENCAP,
- ¶ms->encap);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_NAT,
- ¶ms->nat);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TTL,
- ¶ms->ttl);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_STATS,
- ¶ms->stats);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TIME,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- ¶ms->sym_crypto);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TAG,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_DECAP,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_table_action_profile_freeze(ap);
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct table_action_profile));
- if (profile == NULL) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node);
-
- return profile;
-}
diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
deleted file mode 100644
index cde17e69a3..0000000000
--- a/examples/ip_pipeline/action.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_ACTION_H_
-#define _INCLUDE_ACTION_H_
-
-#include <sys/queue.h>
-
-#include <rte_port_in_action.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-
-/**
- * Input port action
- */
-struct port_in_action_profile_params {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-struct port_in_action_profile {
- TAILQ_ENTRY(port_in_action_profile) node;
- char name[NAME_SIZE];
- struct port_in_action_profile_params params;
- struct rte_port_in_action_profile *ap;
-};
-
-TAILQ_HEAD(port_in_action_profile_list, port_in_action_profile);
-
-int
-port_in_action_profile_init(void);
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name);
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params);
-
-/**
- * Table action
- */
-struct table_action_profile_params {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-struct table_action_profile {
- TAILQ_ENTRY(table_action_profile) node;
- char name[NAME_SIZE];
- struct table_action_profile_params params;
- struct rte_table_action_profile *ap;
-};
-
-TAILQ_HEAD(table_action_profile_list, table_action_profile);
-
-int
-table_action_profile_init(void);
-
-struct table_action_profile *
-table_action_profile_find(const char *name);
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params);
-
-#endif /* _INCLUDE_ACTION_H_ */
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
deleted file mode 100644
index 935c9b39d5..0000000000
--- a/examples/ip_pipeline/cli.c
+++ /dev/null
@@ -1,6791 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-
-#include "cli.h"
-
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "parser.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-#ifndef CMD_MAX_TOKENS
-#define CMD_MAX_TOKENS 256
-#endif
-
-#define MSG_OUT_OF_MEMORY "Not enough memory.\n"
-#define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
-#define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
-#define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
-#define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
-#define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
-#define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
-#define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
-#define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
-#define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
-#define MSG_CMD_FAIL "Command \"%s\" failed.\n"
-
-static int
-is_comment(char *in)
-{
- if ((strlen(in) && index("!#%;", in[0])) ||
- (strncmp(in, "//", 2) == 0) ||
- (strncmp(in, "--", 2) == 0))
- return 1;
-
- return 0;
-}
-
-static const char cmd_mempool_help[] =
-"mempool <mempool_name>\n"
-" buffer <buffer_size>\n"
-" pool <pool_size>\n"
-" cache <cache_size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_mempool(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct mempool_params p;
- char *name;
- struct mempool *mempool;
-
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "buffer") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
- return;
- }
-
- if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
- return;
- }
-
- if (strcmp(tokens[4], "pool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
- return;
- }
-
- if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
- return;
- }
-
- if (strcmp(tokens[6], "cache") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
- return;
- }
-
- if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
- return;
- }
-
- if (strcmp(tokens[8], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- mempool = mempool_create(name, &p);
- if (mempool == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_link_help[] =
-"link <link_name>\n"
-" dev <device_name> | port <port_id>\n"
-" rxq <n_queues> <queue_size> <mempool_name>\n"
-" txq <n_queues> <queue_size>\n"
-" promiscuous on | off\n"
-" [rss <qid_0> ... <qid_n>]\n";
-
-static void
-cmd_link(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct link_params p;
- struct link_params_rss rss;
- struct link *link;
- char *name;
-
- memset(&p, 0, sizeof(p));
-
- if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- p.dev_name = tokens[3];
- else if (strcmp(tokens[2], "port") == 0) {
- p.dev_name = NULL;
-
- if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
- return;
- }
-
- if (strcmp(tokens[4], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
- if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- p.rx.mempool_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
-
- if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- if (strcmp(tokens[11], "promiscuous") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
- return;
- }
-
- if (strcmp(tokens[12], "on") == 0)
- p.promiscuous = 1;
- else if (strcmp(tokens[12], "off") == 0)
- p.promiscuous = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
- return;
- }
-
- /* RSS */
- p.rx.rss = NULL;
- if (n_tokens > 13) {
- uint32_t queue_id, i;
-
- if (strcmp(tokens[13], "rss") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
- return;
- }
-
- p.rx.rss = &rss;
-
- rss.n_queues = 0;
- for (i = 14; i < n_tokens; i++) {
- if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
-
- rss.queue_id[rss.n_queues] = queue_id;
- rss.n_queues++;
- }
- }
-
- link = link_create(name, &p);
- if (link == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-/* Print the link stats and info */
-static void
-print_link_info(struct link *link, char *out, size_t out_size)
-{
- struct rte_eth_stats stats;
- struct rte_ether_addr mac_addr;
- struct rte_eth_link eth_link;
- uint16_t mtu;
- int ret;
-
- memset(&stats, 0, sizeof(stats));
- rte_eth_stats_get(link->port_id, &stats);
-
- ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
- if (ret != 0) {
- snprintf(out, out_size, "\n%s: MAC address get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- ret = rte_eth_link_get(link->port_id, ð_link);
- if (ret < 0) {
- snprintf(out, out_size, "\n%s: link get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- rte_eth_dev_get_mtu(link->port_id, &mtu);
-
- snprintf(out, out_size,
- "\n"
- "%s: flags=<%s> mtu %u\n"
- "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
- "\tport# %u speed %s\n"
- "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
- "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tTX errors %" PRIu64"\n",
- link->name,
- eth_link.link_status == 0 ? "DOWN" : "UP",
- mtu,
- RTE_ETHER_ADDR_BYTES(&mac_addr),
- link->n_rxq,
- link->n_txq,
- link->port_id,
- rte_eth_link_speed_to_str(eth_link.link_speed),
- stats.ipackets,
- stats.ibytes,
- stats.ierrors,
- stats.imissed,
- stats.rx_nombuf,
- stats.opackets,
- stats.obytes,
- stats.oerrors);
-}
-
-/*
- * link show [<link_name>]
- */
-static void
-cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- struct link *link;
- char *link_name;
-
- if (n_tokens != 2 && n_tokens != 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (n_tokens == 2) {
- link = link_next(NULL);
-
- while (link != NULL) {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- print_link_info(link, out, out_size);
- link = link_next(link);
- }
- } else {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- link_name = tokens[2];
- link = link_find(link_name);
-
- if (link == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "Link does not exist");
- return;
- }
- print_link_info(link, out, out_size);
- }
-}
-
-static const char cmd_swq_help[] =
-"swq <swq_name>\n"
-" size <size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_swq(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct swq_params p;
- char *name;
- struct swq *swq;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "size");
- return;
- }
-
- if (strcmp(tokens[4], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- swq = swq_create(name, &p);
- if (swq == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_profile_help[] =
-"tmgr subport profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n";
-
-static void
-cmd_tmgr_subport_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_subport_profile_params subport_profile;
- int status, i;
-
- if (n_tokens != 19) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&subport_profile.tc_rate[i],
- tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- status = tmgr_subport_profile_add(&subport_profile);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_pipe_profile_help[] =
-"tmgr pipe profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n"
-" <tc_ov_weight>\n"
-" <wrr_weight0..3>\n";
-
-static void
-cmd_tmgr_pipe_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_pipe_params p;
- int status, i;
-
- if (n_tokens != 24) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&p.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&p.tc_rate[i], tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++)
- if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
- return;
- }
-
- status = tmgr_pipe_profile_add(&p);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_help[] =
-"tmgr <tmgr_name>\n"
-" rate <rate>\n"
-" spp <n_subports_per_port>\n"
-" pps <n_pipes_per_subport>\n"
-" fo <frame_overhead>\n"
-" mtu <mtu>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_tmgr(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct tmgr_port_params p;
- char *name;
- struct tmgr_port *tmgr_port;
-
- if (n_tokens != 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "rate") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
- return;
- }
-
- if (parser_read_uint64(&p.rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "rate");
- return;
- }
-
- if (strcmp(tokens[4], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[6], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
- return;
- }
-
- if (strcmp(tokens[8], "fo") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
- return;
- }
-
- if (parser_read_uint32(&p.frame_overhead, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
- return;
- }
-
- if (strcmp(tokens[10], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.mtu, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- if (strcmp(tokens[12], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- tmgr_port = tmgr_port_create(name, &p);
- if (tmgr_port == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_help[] =
-"tmgr <tmgr_name> subport <subport_id>\n"
-" profile <subport_profile_id>\n";
-
-static void
-cmd_tmgr_subport(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, subport_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
- return;
- }
-
- status = tmgr_subport_config(name, subport_id, subport_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tmgr_subport_pipe_help[] =
-"tmgr <tmgr_name> subport <subport_id> pipe\n"
-" from <pipe_id_first> to <pipe_id_last>\n"
-" profile <pipe_profile_id>\n";
-
-static void
-cmd_tmgr_subport_pipe(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (strcmp(tokens[4], "pipe") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
- return;
- }
-
- if (strcmp(tokens[5], "from") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
- return;
- }
-
- if (strcmp(tokens[7], "to") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
- return;
- }
-
- if (strcmp(tokens[9], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
- return;
- }
-
- status = tmgr_pipe_config(name, subport_id, pipe_id_first,
- pipe_id_last, pipe_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tap_help[] =
-"tap <tap_name>\n";
-
-static void
-cmd_tap(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *name;
- struct tap *tap;
-
- if (n_tokens != 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- tap = tap_create(name);
- if (tap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_cryptodev_help[] =
-"cryptodev <cryptodev_name>\n"
-" dev <device_name> | dev_id <device_id>\n"
-" queue <n_queues> <queue_size>\n"
-" max_sessions <n_sessions>";
-
-static void
-cmd_cryptodev(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct cryptodev_params params;
- char *name;
-
- memset(¶ms, 0, sizeof(params));
- if (n_tokens != 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- params.dev_name = tokens[3];
- else if (strcmp(tokens[2], "dev_id") == 0) {
- if (parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "dev_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cryptodev");
- return;
- }
-
- if (strcmp(tokens[4], "queue")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "queue");
- return;
- }
-
- if (parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "q");
- return;
- }
-
- if (parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (strcmp(tokens[7], "max_sessions")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "max_sessions");
- return;
- }
-
- if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (cryptodev_create(name, ¶ms) == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_port_in_action_profile_help[] =
-"port in action profile <profile_name>\n"
-" [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
-" [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
-
-static void
-cmd_port_in_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_action_profile_params p;
- struct port_in_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[2], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[3], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[4];
-
- t0 = 5;
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
- uint32_t size;
-
- if (n_tokens < t0 + 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "match") == 0)
- p.fltr.filter_on_match = 1;
- else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
- p.fltr.filter_on_match = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 6], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
- t0 += 10;
- } /* filter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- uint32_t i;
-
- if (n_tokens < t0 + 22) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "port in action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- for (i = 0; i < 16; i++)
- if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
- t0 += 22;
- } /* balance */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = port_in_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_table_action_profile_help[] =
-"table action profile <profile_name>\n"
-" ipv4 | ipv6\n"
-" offset <ip_offset>\n"
-" fwd\n"
-" [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
-" [meter srtcm | trtcm\n"
-" tc <n_tc>\n"
-" stats none | pkts | bytes | both]\n"
-" [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
-" [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
-" vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
-" [nat src | dst\n"
-" proto udp | tcp]\n"
-" [ttl drop | fwd\n"
-" stats none | pkts]\n"
-" [stats pkts | bytes | both]\n"
-" [time]\n"
-" [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
-" [tag]\n"
-" [decap]\n";
-
-static void
-cmd_table_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_action_profile_params p;
- struct table_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[2], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[3];
-
- if (strcmp(tokens[4], "ipv4") == 0)
- p.common.ip_version = 1;
- else if (strcmp(tokens[4], "ipv6") == 0)
- p.common.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[5], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
- return;
- }
-
- if (strcmp(tokens[7], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
-
- t0 = 8;
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- if (n_tokens < t0 + 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
- t0 += 7;
- } /* balance */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile meter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "srtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
- else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "srtcm or trtcm");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "tc") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
- return;
- }
-
- if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "none") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 5], "both") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
- t0 += 6;
- } /* meter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile tm");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_subports_per_port,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_pipes_per_subport,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_pipes_per_subport");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
- t0 += 5;
- } /* tm */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
- uint32_t n_extra_tokens = 0;
-
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "ether") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
- else if (strcmp(tokens[t0 + 1], "vlan") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
- else if (strcmp(tokens[t0 + 1], "qinq") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
- else if (strcmp(tokens[t0 + 1], "mpls") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
- else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
- else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
- if (n_tokens < t0 + 2 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap vxlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: offset");
- return;
- }
-
- if (parser_read_uint32(&p.encap.vxlan.data_offset,
- tokens[t0 + 2 + 1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ether_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
- p.encap.vxlan.ip_version = 1;
- else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
- p.encap.vxlan.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: vlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
- p.encap.vxlan.vlan = 1;
- else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
- p.encap.vxlan.vlan = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: on or off");
- return;
- }
-
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
- n_extra_tokens = 5;
- } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
- p.encap.encap_mask =
- 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
- t0 += 2 + n_extra_tokens;
- } /* encap */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile nat");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "src") == 0)
- p.nat.source_nat = 1;
- else if (strcmp(tokens[t0 + 1], "dst") == 0)
- p.nat.source_nat = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "src or dst");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "proto") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "tcp") == 0)
- p.nat.proto = 0x06;
- else if (strcmp(tokens[t0 + 3], "udp") == 0)
- p.nat.proto = 0x11;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "tcp or udp");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
- t0 += 4;
- } /* nat */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile ttl");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "drop") == 0)
- p.ttl.drop = 1;
- else if (strcmp(tokens[t0 + 1], "fwd") == 0)
- p.ttl.drop = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "drop or fwd");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "none") == 0)
- p.ttl.n_packets_enabled = 0;
- else if (strcmp(tokens[t0 + 3], "pkts") == 0)
- p.ttl.n_packets_enabled = 1;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
- t0 += 4;
- } /* ttl */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "pkts") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
- p.stats.n_packets_enabled = 0;
- p.stats.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 1], "both") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
- t0 += 2;
- } /* stats */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
- t0 += 1;
- } /* time */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
- struct cryptodev *cryptodev;
-
- if (n_tokens < t0 + 5 ||
- strcmp(tokens[t0 + 1], "dev") ||
- strcmp(tokens[t0 + 3], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile sym_crypto");
- return;
- }
-
- cryptodev = cryptodev_find(tokens[t0 + 2]);
- if (cryptodev == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.cryptodev_id = cryptodev->dev_id;
-
- if (parser_read_uint32(&p.sym_crypto.op_offset,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.mp_create = cryptodev->mp_create;
- p.sym_crypto.mp_init = cryptodev->mp_init;
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- t0 += 5;
- } /* sym_crypto */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
- t0 += 1;
- } /* tag */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "decap") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
- t0 += 1;
- } /* decap */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = table_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_help[] =
-"pipeline <pipeline_name>\n"
-" period <timer_period_ms>\n"
-" offset_port_id <offset_port_id>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_pipeline(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct pipeline_params p;
- char *name;
- struct pipeline *pipeline;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "period") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
- return;
- }
-
- if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
- return;
- }
-
- if (strcmp(tokens[4], "offset_port_id") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
- return;
- }
-
- if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
- return;
- }
-
- if (strcmp(tokens[6], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- pipeline = pipeline_create(name, &p);
- if (pipeline == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_help[] =
-"pipeline <pipeline_name> port in\n"
-" bsz <burst_size>\n"
-" link <link_name> rxq <queue_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
-" | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
-" | cryptodev <cryptodev_name> rxq <queue_id>\n"
-" [action <port_in_action_profile_name>]\n"
-" [disabled]\n";
-
-static void
-cmd_pipeline_port_in(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_params p;
- char *pipeline_name;
- uint32_t t0;
- int enabled, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- t0 = 6;
-
- if (strcmp(tokens[t0], "link") == 0) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in link");
- return;
- }
-
- p.type = PORT_IN_RXQ;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
- t0 += 4;
- } else if (strcmp(tokens[t0], "swq") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in swq");
- return;
- }
-
- p.type = PORT_IN_SWQ;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tmgr") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tmgr");
- return;
- }
-
- p.type = PORT_IN_TMGR;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tap") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tap");
- return;
- }
-
- p.type = PORT_IN_TAP;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.tap.mempool_name = tokens[t0 + 3];
-
- if (strcmp(tokens[t0 + 4], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "source") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in source");
- return;
- }
-
- p.type = PORT_IN_SOURCE;
-
- p.dev_name = NULL;
-
- if (strcmp(tokens[t0 + 1], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.source.mempool_name = tokens[t0 + 2];
-
- if (strcmp(tokens[t0 + 3], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.source.file_name = tokens[t0 + 4];
-
- if (strcmp(tokens[t0 + 5], "bpp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "bpp");
- return;
- }
-
- if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_bytes_per_pkt");
- return;
- }
-
- t0 += 7;
- } else if (strcmp(tokens[t0], "cryptodev") == 0) {
- if (n_tokens < t0 + 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in cryptodev");
- return;
- }
-
- p.type = PORT_IN_CRYPTODEV;
-
- p.dev_name = tokens[t0 + 1];
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "rxq");
- return;
- }
-
- p.cryptodev.arg_callback = NULL;
- p.cryptodev.f_callback = NULL;
-
- t0 += 4;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- enabled = 1;
- if ((n_tokens > t0) &&
- (strcmp(tokens[t0], "disabled") == 0)) {
- enabled = 0;
-
- t0 += 1;
- }
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_port_in_create(pipeline_name,
- &p, enabled);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_out_help[] =
-"pipeline <pipeline_name> port out\n"
-" bsz <burst_size>\n"
-" link <link_name> txq <txq_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name>\n"
-" | sink [file <file_name> pkts <max_n_pkts>]\n"
-" | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
-
-static void
-cmd_pipeline_port_out(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_out_params p;
- char *pipeline_name;
- int status;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- if (strcmp(tokens[6], "link") == 0) {
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out link");
- return;
- }
-
- p.type = PORT_OUT_TXQ;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else if (strcmp(tokens[6], "swq") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out swq");
- return;
- }
-
- p.type = PORT_OUT_SWQ;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tmgr") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tmgr");
- return;
- }
-
- p.type = PORT_OUT_TMGR;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tap") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tap");
- return;
- }
-
- p.type = PORT_OUT_TAP;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "sink") == 0) {
- if ((n_tokens != 7) && (n_tokens != 11)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out sink");
- return;
- }
-
- p.type = PORT_OUT_SINK;
-
- p.dev_name = NULL;
-
- if (n_tokens == 7) {
- p.sink.file_name = NULL;
- p.sink.max_n_pkts = 0;
- } else {
- if (strcmp(tokens[7], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.sink.file_name = tokens[8];
-
- if (strcmp(tokens[9], "pkts") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
- return;
- }
-
- if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
- return;
- }
- }
-
- } else if (strcmp(tokens[6], "cryptodev") == 0) {
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- p.type = PORT_OUT_CRYPTODEV;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
-
- if (strcmp(tokens[10], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_port_out_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_help[] =
-"pipeline <pipeline_name> table\n"
-" match\n"
-" acl\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | array\n"
-" offset <key_offset>\n"
-" size <n_keys>\n"
-" | hash\n"
-" ext | lru\n"
-" key <key_size>\n"
-" mask <key_mask>\n"
-" offset <key_offset>\n"
-" buckets <n_buckets>\n"
-" size <n_keys>\n"
-" | lpm\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | stub\n"
-" [action <table_action_profile_name>]\n";
-
-static void
-cmd_pipeline_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
- struct table_params p;
- char *pipeline_name;
- uint32_t t0;
- int status;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (strcmp(tokens[3], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- t0 = 4;
- if (strcmp(tokens[t0], "acl") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table acl");
- return;
- }
-
- p.match_type = TABLE_ACL;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.acl.ip_version = 1;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.acl.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.ip_header_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "ip_header_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "array") == 0) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table array");
- return;
- }
-
- p.match_type = TABLE_ARRAY;
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.key_offset,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.n_keys,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 5;
- } else if (strcmp(tokens[t0], "hash") == 0) {
- uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < t0 + 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table hash");
- return;
- }
-
- p.match_type = TABLE_HASH;
-
- if (strcmp(tokens[t0 + 1], "ext") == 0)
- p.match.hash.extendable_bucket = 1;
- else if (strcmp(tokens[t0 + 1], "lru") == 0)
- p.match.hash.extendable_bucket = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ext or lru");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- if ((parser_read_uint32(&p.match.hash.key_size,
- tokens[t0 + 3]) != 0) ||
- (p.match.hash.key_size == 0) ||
- (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- if ((parse_hex_string(tokens[t0 + 5],
- key_mask, &key_mask_size) != 0) ||
- (key_mask_size != p.match.hash.key_size)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
- p.match.hash.key_mask = key_mask;
-
- if (strcmp(tokens[t0 + 6], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.key_offset,
- tokens[t0 + 7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "buckets") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_buckets,
- tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
- return;
- }
-
- if (strcmp(tokens[t0 + 10], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_keys,
- tokens[t0 + 11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 12;
- } else if (strcmp(tokens[t0], "lpm") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table lpm");
- return;
- }
-
- p.match_type = TABLE_LPM;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.lpm.key_size = 4;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.lpm.key_size = 16;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.key_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "stub") == 0) {
- p.match_type = TABLE_STUB;
-
- t0 += 1;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- if (n_tokens > t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_table_help[] =
-"pipeline <pipeline_name> port in <port_id> table <table_id>\n";
-
-static void
-cmd_pipeline_port_in_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id, table_id;
- int status;
-
- if (n_tokens != 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- status = pipeline_port_in_connect_to_table(pipeline_name,
- port_id,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_stats_help[] =
-"pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_IN_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_in_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_in_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_in_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_port_in_enable_help[] =
-"pipeline <pipeline_name> port in <port_id> enable\n";
-
-static void
-cmd_pipeline_port_in_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = pipeline_port_in_enable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_disable_help[] =
-"pipeline <pipeline_name> port in <port_id> disable\n";
-
-static void
-cmd_pipeline_port_in_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = pipeline_port_in_disable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_out_stats_help[] =
-"pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_OUT_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_out_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_out_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_out_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_table_stats_help[] =
-"pipeline <pipeline_name> table <table_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_TABLE_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts in with lookup miss: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_table_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_table_stats stats;
- char *pipeline_name;
- uint32_t table_id;
- int clear, status;
-
- if ((n_tokens != 6) && (n_tokens != 7)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 7) {
- if (strcmp(tokens[6], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_table_stats_read(pipeline_name,
- table_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
- stats.stats.n_pkts_in,
- stats.stats.n_pkts_lookup_miss,
- stats.n_pkts_dropped_by_lkp_hit_ah,
- stats.n_pkts_dropped_lkp_hit,
- stats.n_pkts_dropped_by_lkp_miss_ah,
- stats.n_pkts_dropped_lkp_miss);
-}
-
-/**
- * <match> ::=
- *
- * match
- * acl
- * priority <priority>
- * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- * <sp0> <sp1> <dp0> <dp1> <proto>
- * | array <pos>
- * | hash
- * raw <key>
- * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv4_addr <addr>
- * | ipv6_addr <addr>
- * | qinq <svlan> <cvlan>
- * | lpm
- * ipv4 | ipv6 <addr> <depth>
- */
-struct pkt_key_qinq {
- uint16_t ethertype_svlan;
- uint16_t svlan;
- uint16_t ethertype_cvlan;
- uint16_t cvlan;
-};
-
-struct pkt_key_ipv4_5tuple {
- uint8_t time_to_live;
- uint8_t proto;
- uint16_t hdr_checksum;
- uint32_t sa;
- uint32_t da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv6_5tuple {
- uint16_t payload_length;
- uint8_t proto;
- uint8_t hop_limit;
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv4_addr {
- uint32_t addr;
-};
-
-struct pkt_key_ipv6_addr {
- struct rte_ipv6_addr addr;
-};
-
-static uint32_t
-parse_match(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_match *m)
-{
- memset(m, 0, sizeof(*m));
-
- if (n_tokens < 2)
- return 0;
-
- if (strcmp(tokens[0], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return 0;
- }
-
- if (strcmp(tokens[1], "acl") == 0) {
- if (n_tokens < 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ACL;
-
- if (strcmp(tokens[2], "priority") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.priority,
- tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "priority");
- return 0;
- }
-
- if (strcmp(tokens[4], "ipv4") == 0) {
- struct in_addr saddr, daddr;
-
- m->match.acl.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
-
- if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
- } else if (strcmp(tokens[4], "ipv6") == 0) {
- struct rte_ipv6_addr saddr, daddr;
-
- m->match.acl.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv6.sa = saddr;
-
- if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv6.da = daddr;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.sa_depth,
- tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.da_depth,
- tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "proto");
- return 0;
- }
-
- m->match.acl.proto_mask = 0xff;
-
- return 14;
- } /* acl */
-
- if (strcmp(tokens[1], "array") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ARRAY;
-
- if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pos");
- return 0;
- }
-
- return 3;
- } /* array */
-
- if (strcmp(tokens[1], "hash") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_HASH;
-
- if (strcmp(tokens[2], "raw") == 0) {
- uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_hex_string(tokens[3],
- m->match.hash.key, &key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key");
- return 0;
- }
-
- return 4;
- } /* hash raw */
-
- if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
- struct pkt_key_ipv4_5tuple *ipv4 =
- (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
- struct in_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv4->sa = saddr.s_addr;
- ipv4->da = daddr.s_addr;
- ipv4->sp = rte_cpu_to_be_16(sp);
- ipv4->dp = rte_cpu_to_be_16(dp);
- ipv4->proto = proto;
-
- return 8;
- } /* hash ipv4_5tuple */
-
- if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
- struct pkt_key_ipv6_5tuple *ipv6 =
- (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
- struct rte_ipv6_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv6->sa = saddr;
- ipv6->da = daddr;
- ipv6->sp = rte_cpu_to_be_16(sp);
- ipv6->dp = rte_cpu_to_be_16(dp);
- ipv6->proto = proto;
-
- return 8;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "ipv4_addr") == 0) {
- struct pkt_key_ipv4_addr *ipv4_addr =
- (struct pkt_key_ipv4_addr *) m->match.hash.key;
- struct in_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv4_addr->addr = addr.s_addr;
-
- return 4;
- } /* hash ipv4_addr */
-
- if (strcmp(tokens[2], "ipv6_addr") == 0) {
- struct pkt_key_ipv6_addr *ipv6_addr =
- (struct pkt_key_ipv6_addr *) m->match.hash.key;
- struct rte_ipv6_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv6_addr->addr = addr;
-
- return 4;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "qinq") == 0) {
- struct pkt_key_qinq *qinq =
- (struct pkt_key_qinq *) m->match.hash.key;
- uint16_t svlan, cvlan;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
- (svlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "svlan");
- return 0;
- }
-
- if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
- (cvlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cvlan");
- return 0;
- }
-
- qinq->svlan = rte_cpu_to_be_16(svlan);
- qinq->cvlan = rte_cpu_to_be_16(cvlan);
-
- return 5;
- } /* hash qinq */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- } /* hash */
-
- if (strcmp(tokens[1], "lpm") == 0) {
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_LPM;
-
- if (strcmp(tokens[2], "ipv4") == 0) {
- struct in_addr addr;
-
- m->match.lpm.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- } else if (strcmp(tokens[2], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
-
- m->match.lpm.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv6 = addr;
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "depth");
- return 0;
- }
-
- return 5;
- } /* lpm */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "acl or array or hash or lpm");
- return 0;
-}
-
-/**
- * table_action ::=
- *
- * action
- * fwd
- * drop
- * | port <port_id>
- * | meta
- * | table <table_id>
- * [balance <out0> ... <out7>]
- * [meter
- * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- * [tm subport <subport_id> pipe <pipe_id>]
- * [encap
- * ether <da> <sa>
- * | vlan <da> <sa> <pcp> <dei> <vid>
- * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
- * | mpls unicast | multicast
- * <da> <sa>
- * label0 <label> <tc> <ttl>
- * [label1 <label> <tc> <ttl>
- * [label2 <label> <tc> <ttl>
- * [label3 <label> <tc> <ttl>]]]
- * | pppoe <da> <sa> <session_id>
- * | vxlan ether <da> <sa>
- * [vlan <pcp> <dei> <vid>]
- * ipv4 <sa> <da> <dscp> <ttl>
- * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
- * udp <sp> <dp>
- * vxlan <vni>]
- * [nat ipv4 | ipv6 <addr> <port>]
- * [ttl dec | keep]
- * [stats]
- * [time]
- * [sym_crypto
- * encrypt | decrypt
- * type
- * | cipher
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * | cipher_auth
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * auth_algo <algo> auth_key <key> digest_size <size>
- * | aead
- * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- * digest_size <size>
- * data_offset <data_offset>]
- * [tag <tag>]
- * [decap <n>]
- *
- * where:
- * <pa> ::= g | y | r | drop
- */
-static uint32_t
-parse_table_action_fwd(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_DROP;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_PORT;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_balance(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t i;
-
- if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
- return 0;
-
- for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
- if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
- return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
-
-}
-
-static int
-parse_policer_action(char *token, enum rte_table_action_policer *a)
-{
- if (strcmp(token, "g") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
- return 0;
- }
-
- if (strcmp(token, "y") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
- return 0;
- }
-
- if (strcmp(token, "r") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
- return 0;
- }
-
- if (strcmp(token, "drop") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_DROP;
- return 0;
- }
-
- return -1;
-}
-
-static uint32_t
-parse_table_action_meter_tc(char **tokens,
- uint32_t n_tokens,
- struct rte_table_action_mtr_tc_params *mtr)
-{
- if ((n_tokens < 9) ||
- strcmp(tokens[0], "meter") ||
- parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
- strcmp(tokens[2], "policer") ||
- strcmp(tokens[3], "g") ||
- parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
- strcmp(tokens[5], "y") ||
- parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
- strcmp(tokens[7], "r") ||
- parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
- return 0;
-
- return 9;
-}
-
-static uint32_t
-parse_table_action_meter(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if ((n_tokens < 10) ||
- strcmp(tokens[0], "tc0") ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1,
- &a->mtr.mtr[0]) == 0))
- return 0;
-
- tokens += 10;
- n_tokens -= 10;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
- a->mtr.tc_mask = 1;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10;
- }
-
- if ((n_tokens < 30) ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
- strcmp(tokens[10], "tc2") ||
- (parse_table_action_meter_tc(tokens + 11,
- n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
- strcmp(tokens[20], "tc3") ||
- (parse_table_action_meter_tc(tokens + 21,
- n_tokens - 21, &a->mtr.mtr[3]) == 0))
- return 0;
-
- a->mtr.tc_mask = 0xF;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10 + 3 * 10;
-}
-
-static uint32_t
-parse_table_action_tm(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t subport_id, pipe_id;
-
- if ((n_tokens < 5) ||
- strcmp(tokens[0], "tm") ||
- strcmp(tokens[1], "subport") ||
- parser_read_uint32(&subport_id, tokens[2]) ||
- strcmp(tokens[3], "pipe") ||
- parser_read_uint32(&pipe_id, tokens[4]))
- return 0;
-
- a->tm.subport_id = subport_id;
- a->tm.pipe_id = pipe_id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
- return 5;
-}
-
-static uint32_t
-parse_table_action_encap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- /* ether */
- if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
- if ((n_tokens < 3) ||
- parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 3;
- }
-
- /* vlan */
- if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 6) ||
- parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
- parser_read_uint32(&pcp, tokens[3]) ||
- (pcp > 0x7) ||
- parser_read_uint32(&dei, tokens[4]) ||
- (dei > 0x1) ||
- parser_read_uint32(&vid, tokens[5]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vlan.vlan.pcp = pcp & 0x7;
- a->encap.vlan.vlan.dei = dei & 0x1;
- a->encap.vlan.vlan.vid = vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 6;
- }
-
- /* qinq */
- if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 9) ||
- parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF))
- return 0;
-
- a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 9;
- }
-
- /* qinq_pppoe */
- if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 10) ||
- parse_mac_addr(tokens[1],
- &a->encap.qinq_pppoe.ether.da) ||
- parse_mac_addr(tokens[2],
- &a->encap.qinq_pppoe.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF) ||
- parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
- tokens[9]))
- return 0;
-
- a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 10;
-
- }
-
- /* mpls */
- if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
- uint32_t label, tc, ttl;
-
- if (n_tokens < 8)
- return 0;
-
- if (strcmp(tokens[1], "unicast") == 0)
- a->encap.mpls.unicast = 1;
- else if (strcmp(tokens[1], "multicast") == 0)
- a->encap.mpls.unicast = 0;
- else
- return 0;
-
- if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
- parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
- strcmp(tokens[4], "label0") ||
- parser_read_uint32(&label, tokens[5]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[6]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[7]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[0].label = label;
- a->encap.mpls.mpls[0].tc = tc;
- a->encap.mpls.mpls[0].ttl = ttl;
-
- tokens += 8;
- n_tokens -= 8;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
- a->encap.mpls.mpls_count = 1;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[1].label = label;
- a->encap.mpls.mpls[1].tc = tc;
- a->encap.mpls.mpls[1].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
- a->encap.mpls.mpls_count = 2;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[2].label = label;
- a->encap.mpls.mpls[2].tc = tc;
- a->encap.mpls.mpls[2].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
- a->encap.mpls.mpls_count = 3;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[3].label = label;
- a->encap.mpls.mpls[3].tc = tc;
- a->encap.mpls.mpls[3].ttl = ttl;
-
- a->encap.mpls.mpls_count = 4;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4 + 4;
- }
-
- /* pppoe */
- if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
- if ((n_tokens < 4) ||
- parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
- parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
- tokens[3]))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 4;
- }
-
- /* vxlan */
- if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
- uint32_t n = 0;
-
- n_tokens--;
- tokens++;
- n++;
-
- /* ether <da> <sa> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "ether") ||
- parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* [vlan <pcp> <dei> <vid>] */
- if (strcmp(tokens[0], "vlan") == 0) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&pcp, tokens[1]) ||
- (pcp > 7) ||
- parser_read_uint32(&dei, tokens[2]) ||
- (dei > 1) ||
- parser_read_uint32(&vid, tokens[3]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vxlan.vlan.pcp = pcp;
- a->encap.vxlan.vlan.dei = dei;
- a->encap.vxlan.vlan.vid = vid;
-
- n_tokens -= 4;
- tokens += 4;
- n += 4;
- }
-
- /* ipv4 <sa> <da> <dscp> <ttl>
- | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
- if (strcmp(tokens[0], "ipv4") == 0) {
- struct in_addr sa, da;
- uint8_t dscp, ttl;
-
- if ((n_tokens < 5) ||
- parse_ipv4_addr(tokens[1], &sa) ||
- parse_ipv4_addr(tokens[2], &da) ||
- parser_read_uint8(&dscp, tokens[3]) ||
- (dscp > 64) ||
- parser_read_uint8(&ttl, tokens[4]))
- return 0;
-
- a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
- a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
- a->encap.vxlan.ipv4.dscp = dscp;
- a->encap.vxlan.ipv4.ttl = ttl;
-
- n_tokens -= 5;
- tokens += 5;
- n += 5;
- } else if (strcmp(tokens[0], "ipv6") == 0) {
- struct rte_ipv6_addr sa, da;
- uint32_t flow_label;
- uint8_t dscp, hop_limit;
-
- if ((n_tokens < 6) ||
- parse_ipv6_addr(tokens[1], &sa) ||
- parse_ipv6_addr(tokens[2], &da) ||
- parser_read_uint32(&flow_label, tokens[3]) ||
- parser_read_uint8(&dscp, tokens[4]) ||
- (dscp > 64) ||
- parser_read_uint8(&hop_limit, tokens[5]))
- return 0;
-
- a->encap.vxlan.ipv6.sa = sa;
- a->encap.vxlan.ipv6.da = da;
- a->encap.vxlan.ipv6.flow_label = flow_label;
- a->encap.vxlan.ipv6.dscp = dscp;
- a->encap.vxlan.ipv6.hop_limit = hop_limit;
-
- n_tokens -= 6;
- tokens += 6;
- n += 6;
- } else
- return 0;
-
- /* udp <sp> <dp> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "udp") ||
- parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
- parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* vxlan <vni> */
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "vxlan") ||
- parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
- (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
- return 0;
-
- n_tokens -= 2;
- tokens += 2;
- n += 2;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + n;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_nat(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 4) ||
- strcmp(tokens[0], "nat"))
- return 0;
-
- if (strcmp(tokens[1], "ipv4") == 0) {
- struct in_addr addr;
- uint16_t port;
-
- if (parse_ipv4_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 1;
- a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- if (strcmp(tokens[1], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
- uint16_t port;
-
- if (parse_ipv6_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 0;
- a->nat.addr.ipv6 = addr;
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_ttl(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "ttl"))
- return 0;
-
- if (strcmp(tokens[1], "dec") == 0)
- a->ttl.decrement = 1;
- else if (strcmp(tokens[1], "keep") == 0)
- a->ttl.decrement = 0;
- else
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
- return 2;
-}
-
-static uint32_t
-parse_table_action_stats(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "stats"))
- return 0;
-
- a->stats.n_packets = 0;
- a->stats.n_bytes = 0;
- a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
- return 1;
-}
-
-static uint32_t
-parse_table_action_time(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "time"))
- return 0;
-
- a->time.time = rte_rdtsc();
- a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
- return 1;
-}
-
-static void
-parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
-{
- struct rte_crypto_sym_xform *xform[2] = {NULL};
- uint32_t i;
-
- xform[0] = p->xform;
- if (xform[0])
- xform[1] = xform[0]->next;
-
- for (i = 0; i < 2; i++) {
- if (xform[i] == NULL)
- continue;
-
- switch (xform[i]->type) {
- case RTE_CRYPTO_SYM_XFORM_CIPHER:
- free(p->cipher_auth.cipher_iv.val);
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AUTH:
- if (p->cipher_auth.auth_iv.val)
- free(p->cipher_auth.cipher_iv.val);
- if (p->cipher_auth.auth_iv_update.val)
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AEAD:
- free(p->aead.iv.val);
- free(p->aead.aad.val);
- break;
- default:
- continue;
- }
- }
-
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- int status;
- size_t len;
-
- if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
- strcmp(tokens[3], "cipher_key") ||
- strcmp(tokens[5], "cipher_iv"))
- return NULL;
-
- xform_cipher = calloc(1, sizeof(*xform_cipher));
- if (xform_cipher == NULL)
- return NULL;
-
- xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
- xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- /* cipher_algo */
- status = rte_cryptodev_get_cipher_algo_enum(
- &xform_cipher->cipher.algo, tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* cipher_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.key.data = key;
- xform_cipher->cipher.key.length = (uint16_t)len;
-
- /* cipher_iv */
- len = strlen(tokens[6]);
-
- p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
- if (p->cipher_auth.cipher_iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6],
- p->cipher_auth.cipher_iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.iv.length = (uint16_t)len;
- xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->cipher_auth.cipher_iv.length = (uint32_t)len;
- *used_n_tokens = 7;
-
- return xform_cipher;
-
-error_exit:
- if (p->cipher_auth.cipher_iv.val) {
- free(p->cipher_auth.cipher_iv.val);
- p->cipher_auth.cipher_iv.val = NULL;
- }
-
- free(xform_cipher);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- struct rte_crypto_sym_xform *xform_auth;
- int status;
- size_t len;
-
- if (n_tokens < 13 ||
- strcmp(tokens[7], "auth_algo") ||
- strcmp(tokens[9], "auth_key") ||
- strcmp(tokens[11], "digest_size"))
- return NULL;
-
- xform_auth = calloc(1, sizeof(*xform_auth));
- if (xform_auth == NULL)
- return NULL;
-
- xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
- xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
- RTE_CRYPTO_AUTH_OP_VERIFY;
-
- /* auth_algo */
- status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
- tokens[8]);
- if (status < 0)
- goto error_exit;
-
- /* auth_key */
- len = strlen(tokens[10]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_auth->auth.key.data = key;
- xform_auth->auth.key.length = (uint16_t)len;
-
- key += xform_auth->auth.key.length;
- max_key_len -= xform_auth->auth.key.length;
-
- if (strcmp(tokens[11], "digest_size"))
- goto error_exit;
-
- status = parser_read_uint16(&xform_auth->auth.digest_length,
- tokens[12]);
- if (status < 0)
- goto error_exit;
-
- xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
- 7, encrypt, used_n_tokens);
- if (xform_cipher == NULL)
- goto error_exit;
-
- *used_n_tokens += 6;
-
- if (encrypt) {
- xform_cipher->next = xform_auth;
- return xform_cipher;
- } else {
- xform_auth->next = xform_cipher;
- return xform_auth;
- }
-
-error_exit:
- if (p->cipher_auth.auth_iv.val) {
- free(p->cipher_auth.auth_iv.val);
- p->cipher_auth.auth_iv.val = 0;
- }
-
- free(xform_auth);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_aead;
- int status;
- size_t len;
-
- if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
- strcmp(tokens[3], "aead_key") ||
- strcmp(tokens[5], "aead_iv") ||
- strcmp(tokens[7], "aead_aad") ||
- strcmp(tokens[9], "digest_size"))
- return NULL;
-
- xform_aead = calloc(1, sizeof(*xform_aead));
- if (xform_aead == NULL)
- return NULL;
-
- xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
- xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
- RTE_CRYPTO_AEAD_OP_DECRYPT;
-
- /* aead_algo */
- status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
- tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* aead_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.key.data = key;
- xform_aead->aead.key.length = (uint16_t)len;
-
- /* aead_iv */
- len = strlen(tokens[6]);
- p->aead.iv.val = calloc(1, len / 2 + 1);
- if (p->aead.iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6], p->aead.iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.iv.length = (uint16_t)len;
- xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->aead.iv.length = (uint32_t)len;
-
- /* aead_aad */
- len = strlen(tokens[8]);
- p->aead.aad.val = calloc(1, len / 2 + 1);
- if (p->aead.aad.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.aad_length = (uint16_t)len;
- p->aead.aad.length = (uint32_t)len;
-
- /* digest_size */
- status = parser_read_uint16(&xform_aead->aead.digest_length,
- tokens[10]);
- if (status < 0)
- goto error_exit;
-
- *used_n_tokens = 11;
-
- return xform_aead;
-
-error_exit:
- if (p->aead.iv.val) {
- free(p->aead.iv.val);
- p->aead.iv.val = NULL;
- }
- if (p->aead.aad.val) {
- free(p->aead.aad.val);
- p->aead.aad.val = NULL;
- }
-
- free(xform_aead);
-
- return NULL;
-}
-
-
-static uint32_t
-parse_table_action_sym_crypto(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
- struct rte_crypto_sym_xform *xform = NULL;
- uint8_t *key = a->sym_crypto_key;
- uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
- uint32_t used_n_tokens;
- uint32_t encrypt;
- int status;
-
- if ((n_tokens < 12) ||
- strcmp(tokens[0], "sym_crypto") ||
- strcmp(tokens[2], "type"))
- return 0;
-
- memset(p, 0, sizeof(*p));
-
- if (strcmp(tokens[1], "encrypt") == 0)
- encrypt = 1;
- else
- encrypt = 0;
-
- status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
- if (status < 0)
- return 0;
-
- if (strcmp(tokens[3], "cipher") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "cipher_auth") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher_auth(p, key, max_key_len,
- tokens, n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "aead") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_aead(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- }
-
- if (xform == NULL)
- return 0;
-
- p->xform = xform;
-
- if (strcmp(tokens[used_n_tokens], "data_offset")) {
- parse_free_sym_crypto_param_data(p);
- return 0;
- }
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- return used_n_tokens + 5;
-}
-
-static uint32_t
-parse_table_action_tag(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "tag"))
- return 0;
-
- if (parser_read_uint32(&a->tag.tag, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
- return 2;
-}
-
-static uint32_t
-parse_table_action_decap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "decap"))
- return 0;
-
- if (parser_read_uint16(&a->decap.n, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
- return 2;
-}
-
-static uint32_t
-parse_table_action(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_action *a)
-{
- uint32_t n_tokens0 = n_tokens;
-
- memset(a, 0, sizeof(*a));
-
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "action"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
- uint32_t n;
-
- n = parse_table_action_fwd(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action fwd");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
- uint32_t n;
-
- n = parse_table_action_balance(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action balance");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
- uint32_t n;
-
- n = parse_table_action_meter(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action meter");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tm(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tm");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_encap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action encap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
- uint32_t n;
-
- n = parse_table_action_nat(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action nat");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
- uint32_t n;
-
- n = parse_table_action_ttl(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action ttl");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
- uint32_t n;
-
- n = parse_table_action_stats(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action stats");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
- uint32_t n;
-
- n = parse_table_action_time(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action time");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
- uint32_t n;
-
- n = parse_table_action_sym_crypto(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action sym_crypto");
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tag(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tag");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_decap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action decap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens0 - n_tokens == 1) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return 0;
- }
-
- return n_tokens0 - n_tokens;
-}
-
-
-static const char cmd_pipeline_table_rule_add_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match <match>\n"
-" action <table_action>\n";
-
-static void
-cmd_pipeline_table_rule_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct table_rule_action a;
- char *pipeline_name;
- uint32_t table_id, t0, n_tokens_parsed;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- /* action */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &a);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (t0 != n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
- parse_free_sym_crypto_param_data(&a.sym_crypto);
-}
-
-
-static const char cmd_pipeline_table_rule_add_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match\n"
-" default\n"
-" action\n"
-" fwd\n"
-" drop\n"
-" | port <port_id>\n"
-" | meta\n"
-" | table <table_id>\n";
-
-static void
-cmd_pipeline_table_rule_add_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_action action;
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if ((n_tokens != 11) && (n_tokens != 12)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- if (strcmp(tokens[8], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return;
- }
-
- if (strcmp(tokens[9], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
- return;
- }
-
- action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
-
- if (strcmp(tokens[10], "drop") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_DROP;
- } else if (strcmp(tokens[10], "port") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT;
- action.fwd.id = id;
- } else if (strcmp(tokens[10], "meta") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- } else if (strcmp(tokens[10], "table") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
- action.fwd.id = id;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "drop or port or meta or table");
- return;
- }
-
- status = pipeline_table_rule_add_default(pipeline_name,
- table_id,
- &action);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_add_bulk_help[] =
-"pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - line format: match <match> action <action>\n";
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size);
-
-static void
-cmd_pipeline_table_rule_add_bulk(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *pipeline_name, *file_name;
- uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "bulk") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
- return;
- }
-
- file_name = tokens[7];
-
- /* Load rules from file. */
- status = cli_rule_file_process(file_name,
- 1024,
- &list,
- &n_rules,
- &line_number,
- out,
- out_size);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- /* Rule bulk add */
- status = pipeline_table_rule_add_bulk(pipeline_name,
- table_id,
- list,
- &n_rules_added,
- &n_rules_not_added);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, "Added %u rules out of %u.\n",
- n_rules_added,
- n_rules);
-}
-
-
-static const char cmd_pipeline_table_rule_delete_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed, t0;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_delete(pipeline_name,
- table_id,
- &m);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_delete_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match\n"
-" default\n";
-
-static void
-cmd_pipeline_table_rule_delete_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- status = pipeline_table_rule_delete_default(pipeline_name,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static void
-ether_addr_show(FILE *f, struct rte_ether_addr *addr)
-{
- fprintf(f, RTE_ETHER_ADDR_PRT_FMT, RTE_ETHER_ADDR_BYTES(addr));
-}
-
-static void
-ipv4_addr_show(FILE *f, uint32_t addr)
-{
- fprintf(f, "%u.%u.%u.%u",
- addr >> 24,
- (addr >> 16) & 0xFF,
- (addr >> 8) & 0xFF,
- addr & 0xFF);
-}
-
-static void
-ipv6_addr_show(FILE *f, const struct rte_ipv6_addr *ip)
-{
- fprintf(f, RTE_IPV6_ADDR_FMT ":", RTE_IPV6_ADDR_SPLIT(ip));
-}
-
-static const char *
-policer_action_string(enum rte_table_action_policer action) {
- switch (action) {
- case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
- case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
- case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
- case RTE_TABLE_ACTION_POLICER_DROP: return "D";
- default: return "?";
- }
-}
-
-static int
-table_rule_show(const char *pipeline_name,
- uint32_t table_id,
- const char *file_name)
-{
- struct pipeline *pipeline;
- struct table *table;
- struct table_rule *rule;
- FILE *f = NULL;
- uint32_t i;
-
- /* Check input params. */
- if ((pipeline_name == NULL) ||
- (file_name == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL || table_id >= pipeline->n_tables)
- return -1;
-
- table = &pipeline->table[table_id];
-
- /* Open file. */
- f = fopen(file_name, "w");
- if (f == NULL)
- return -1;
-
- /* Write table rules to file. */
- TAILQ_FOREACH(rule, &table->rules, node) {
- struct table_rule_match *m = &rule->match;
- struct table_rule_action *a = &rule->action;
-
- fprintf(f, "match ");
- switch (m->match_type) {
- case TABLE_ACL:
- fprintf(f, "acl priority %u ",
- m->match.acl.priority);
-
- fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.sa);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.sa);
-
- fprintf(f, "%u", m->match.acl.sa_depth);
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.da);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.da);
-
- fprintf(f, "%u", m->match.acl.da_depth);
-
- fprintf(f, "%u %u %u %u %u ",
- (uint32_t)m->match.acl.sp0,
- (uint32_t)m->match.acl.sp1,
- (uint32_t)m->match.acl.dp0,
- (uint32_t)m->match.acl.dp1,
- (uint32_t)m->match.acl.proto);
- break;
-
- case TABLE_ARRAY:
- fprintf(f, "array %u ",
- m->match.array.pos);
- break;
-
- case TABLE_HASH:
- fprintf(f, "hash raw ");
- for (i = 0; i < table->params.match.hash.key_size; i++)
- fprintf(f, "%02x", m->match.hash.key[i]);
- fprintf(f, " ");
- break;
-
- case TABLE_LPM:
- fprintf(f, "lpm ");
-
- fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.lpm.ipv4);
- else
- ipv6_addr_show(f, &m->match.lpm.ipv6);
-
- fprintf(f, "%u ",
- (uint32_t)m->match.lpm.depth);
- break;
-
- default:
- fprintf(f, "unknown ");
- }
-
- fprintf(f, "action ");
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- fprintf(f, "fwd ");
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- fprintf(f, "balance ");
- for (i = 0; i < RTE_DIM(a->lb.out); i++)
- fprintf(f, "%u ", a->lb.out[i]);
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- fprintf(f, "mtr ");
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
- if (a->mtr.tc_mask & (1 << i)) {
- struct rte_table_action_mtr_tc_params *p =
- &a->mtr.mtr[i];
- enum rte_table_action_policer ga =
- p->policer[RTE_COLOR_GREEN];
- enum rte_table_action_policer ya =
- p->policer[RTE_COLOR_YELLOW];
- enum rte_table_action_policer ra =
- p->policer[RTE_COLOR_RED];
-
- fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
- i,
- a->mtr.mtr[i].meter_profile_id,
- policer_action_string(ga),
- policer_action_string(ya),
- policer_action_string(ra));
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
- fprintf(f, "tm subport %u pipe %u ",
- a->tm.subport_id,
- a->tm.pipe_id);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- fprintf(f, "encap ");
- switch (a->encap.type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- fprintf(f, "ether ");
- ether_addr_show(f, &a->encap.ether.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.ether.ether.sa);
- fprintf(f, " ");
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- fprintf(f, "vlan ");
- ether_addr_show(f, &a->encap.vlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vlan.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u ",
- a->encap.vlan.vlan.pcp,
- a->encap.vlan.vlan.dei,
- a->encap.vlan.vlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- fprintf(f, "qinq ");
- ether_addr_show(f, &a->encap.qinq.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.qinq.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
- a->encap.qinq.svlan.pcp,
- a->encap.qinq.svlan.dei,
- a->encap.qinq.svlan.vid,
- a->encap.qinq.cvlan.pcp,
- a->encap.qinq.cvlan.dei,
- a->encap.qinq.cvlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
- "unicast " : "multicast ");
- ether_addr_show(f, &a->encap.mpls.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.mpls.ether.sa);
- fprintf(f, " ");
- for (i = 0; i < a->encap.mpls.mpls_count; i++) {
- struct rte_table_action_mpls_hdr *l =
- &a->encap.mpls.mpls[i];
-
- fprintf(f, "label%u %u %u %u ",
- i,
- l->label,
- l->tc,
- l->ttl);
- }
- break;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- fprintf(f, "pppoe ");
- ether_addr_show(f, &a->encap.pppoe.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.pppoe.ether.sa);
- fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- fprintf(f, "vxlan ether ");
- ether_addr_show(f, &a->encap.vxlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vxlan.ether.sa);
- if (table->ap->params.encap.vxlan.vlan)
- fprintf(f, " vlan pcp %u dei %u vid %u ",
- a->encap.vxlan.vlan.pcp,
- a->encap.vxlan.vlan.dei,
- a->encap.vxlan.vlan.vid);
- if (table->ap->params.encap.vxlan.ip_version) {
- fprintf(f, " ipv4 ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
- fprintf(f, " ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
- fprintf(f, " %u %u ",
- (uint32_t)a->encap.vxlan.ipv4.dscp,
- (uint32_t)a->encap.vxlan.ipv4.ttl);
- } else {
- fprintf(f, " ipv6 ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.sa);
- fprintf(f, " ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.da);
- fprintf(f, " %u %u %u ",
- a->encap.vxlan.ipv6.flow_label,
- (uint32_t)a->encap.vxlan.ipv6.dscp,
- (uint32_t)a->encap.vxlan.ipv6.hop_limit);
- fprintf(f, " udp %u %u vxlan %u ",
- a->encap.vxlan.udp.sp,
- a->encap.vxlan.udp.dp,
- a->encap.vxlan.vxlan.vni);
- }
- break;
-
- default:
- fprintf(f, "unknown ");
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
- if (a->nat.ip_version)
- ipv4_addr_show(f, a->nat.addr.ipv4);
- else
- ipv6_addr_show(f, &a->nat.addr.ipv6);
- fprintf(f, " %u ", (uint32_t)(a->nat.port));
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
- fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
- fprintf(f, "stats ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
- fprintf(f, "time ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
- fprintf(f, "sym_crypto ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
- fprintf(f, "tag %u ", a->tag.tag);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
- fprintf(f, "decap %u ", a->decap.n);
-
- /* end */
- fprintf(f, "\n");
- }
-
- /* Write table default rule to file. */
- if (table->rule_default) {
- struct table_rule_action *a = &table->rule_default->action;
-
- fprintf(f, "# match default action fwd ");
-
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- } else
- fprintf(f, "# match default action fwd drop ");
-
- fprintf(f, "\n");
-
- /* Close file. */
- fclose(f);
-
- return 0;
-}
-
-static const char cmd_pipeline_table_rule_show_help[] =
-"pipeline <pipeline_name> table <table_id> rule show\n"
-" file <file_name>\n";
-
-static void
-cmd_pipeline_table_rule_show(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *file_name = NULL, *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "show") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
- return;
- }
-
- if (strcmp(tokens[6], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
- return;
- }
-
- file_name = tokens[7];
-
- status = table_rule_show(pipeline_name, table_id, file_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_rule_stats_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_stats_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_stats_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule stats. */
- status = pipeline_table_rule_stats_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- if (stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
- stats.n_packets,
- stats.n_bytes);
-
- if (stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
- stats.n_packets);
-
- if (!stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
- stats.n_bytes);
-
- if (!stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
-}
-
-static const char cmd_pipeline_table_meter_profile_add_help[] =
-"pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
-" add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
-" | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
-
-static void
-cmd_pipeline_table_meter_profile_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_meter_profile p;
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens < 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[8], "srtcm") == 0) {
- if (n_tokens != 15) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_SRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[13], "ebs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
- return;
- }
- } else if (strcmp(tokens[8], "trtcm") == 0) {
- if (n_tokens != 17) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_TRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "pir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pir");
- return;
- }
- if (strcmp(tokens[13], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[15], "pbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_mtr_profile_add(pipeline_name,
- table_id,
- meter_profile_id,
- &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_meter_profile_delete_help[] =
-"pipeline <pipeline_name> table <table_id>\n"
-" meter profile <meter_profile_id> delete\n";
-
-static void
-cmd_pipeline_table_meter_profile_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- status = pipeline_table_mtr_profile_delete(pipeline_name,
- table_id,
- meter_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_meter_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_meter_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_mtr_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule meter stats. */
- status = pipeline_table_rule_mtr_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
-}
-
-
-static const char cmd_pipeline_table_dscp_help[] =
-"pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - exactly 64 lines\n"
-" - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
-
-static int
-load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
- const char *file_name,
- uint32_t *line_number)
-{
- FILE *f = NULL;
- uint32_t dscp, l;
-
- /* Check input arguments */
- if ((dscp_table == NULL) ||
- (file_name == NULL) ||
- (line_number == NULL)) {
- if (line_number)
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Read file */
- for (dscp = 0, l = 1; ; l++) {
- char line[64];
- char *tokens[3];
- enum rte_color color;
- uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
-
- if (fgets(line, sizeof(line), f) == NULL)
- break;
-
- if (is_comment(line))
- continue;
-
- if (parse_tokenize_string(line, tokens, &n_tokens)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- if (n_tokens == 0)
- continue;
-
- if ((dscp >= RTE_DIM(dscp_table->entry)) ||
- (n_tokens != RTE_DIM(tokens)) ||
- parser_read_uint32(&tc_id, tokens[0]) ||
- (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
- parser_read_uint32(&tc_queue_id, tokens[1]) ||
- (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
- (strlen(tokens[2]) != 1)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- switch (tokens[2][0]) {
- case 'g':
- case 'G':
- color = RTE_COLOR_GREEN;
- break;
-
- case 'y':
- case 'Y':
- color = RTE_COLOR_YELLOW;
- break;
-
- case 'r':
- case 'R':
- color = RTE_COLOR_RED;
- break;
-
- default:
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- dscp_table->entry[dscp].tc_id = tc_id;
- dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
- dscp_table->entry[dscp].color = color;
- dscp++;
- }
-
- /* Close file */
- fclose(f);
- return 0;
-}
-
-static void
-cmd_pipeline_table_dscp(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_dscp_table dscp_table;
- char *pipeline_name, *file_name;
- uint32_t table_id, line_number;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "dscp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
- return;
- }
-
- file_name = tokens[5];
-
- status = load_dscp_table(&dscp_table, file_name, &line_number);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- status = pipeline_table_dscp_table_update(pipeline_name,
- table_id,
- UINT64_MAX,
- &dscp_table);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_ttl_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_ttl_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_ttl_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "ttl") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule TTL stats. */
- status = pipeline_table_rule_ttl_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n",
- stats.n_packets);
-}
-
-static const char cmd_pipeline_table_rule_time_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read time\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_time_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint64_t timestamp;
- uint32_t table_id, n_tokens_parsed;
- int status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "time") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule timestamp. */
- status = pipeline_table_rule_time_read(pipeline_name,
- table_id,
- &m,
- ×tamp);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
-}
-
-static const char cmd_thread_pipeline_enable_help[] =
-"thread <thread_id> pipeline <pipeline_name> enable\n";
-
-static void
-cmd_thread_pipeline_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = thread_pipeline_enable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
- return;
- }
-}
-
-
-static const char cmd_thread_pipeline_disable_help[] =
-"thread <thread_id> pipeline <pipeline_name> disable\n";
-
-static void
-cmd_thread_pipeline_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = thread_pipeline_disable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL,
- "thread pipeline disable");
- return;
- }
-}
-
-static void
-cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- tokens++;
- n_tokens--;
-
- if (n_tokens == 0) {
- snprintf(out, out_size,
- "Type 'help <command>' for details on each command.\n\n"
- "List of commands:\n"
- "\tmempool\n"
- "\tlink\n"
- "\tswq\n"
- "\ttmgr subport profile\n"
- "\ttmgr pipe profile\n"
- "\ttmgr\n"
- "\ttmgr subport\n"
- "\ttmgr subport pipe\n"
- "\ttap\n"
- "\tport in action profile\n"
- "\ttable action profile\n"
- "\tpipeline\n"
- "\tpipeline port in\n"
- "\tpipeline port out\n"
- "\tpipeline table\n"
- "\tpipeline port in table\n"
- "\tpipeline port in stats\n"
- "\tpipeline port in enable\n"
- "\tpipeline port in disable\n"
- "\tpipeline port out stats\n"
- "\tpipeline table stats\n"
- "\tpipeline table rule add\n"
- "\tpipeline table rule add default\n"
- "\tpipeline table rule add bulk\n"
- "\tpipeline table rule delete\n"
- "\tpipeline table rule delete default\n"
- "\tpipeline table rule show\n"
- "\tpipeline table rule stats read\n"
- "\tpipeline table meter profile add\n"
- "\tpipeline table meter profile delete\n"
- "\tpipeline table rule meter read\n"
- "\tpipeline table dscp\n"
- "\tpipeline table rule ttl read\n"
- "\tpipeline table rule time read\n"
- "\tthread pipeline enable\n"
- "\tthread pipeline disable\n\n");
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_link_help);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_swq_help);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if (n_tokens == 1) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
- return;
- }
-
- if ((n_tokens == 2) &&
- (strcmp(tokens[1], "subport")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_tmgr_subport_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "pipe") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
- return;
- }
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tap_help);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[0], "port") == 0) &&
- (strcmp(tokens[1], "in") == 0) &&
- (strcmp(tokens[2], "action") == 0) &&
- (strcmp(tokens[3], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "table") == 0) &&
- (strcmp(tokens[1], "action") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "port") == 0)) {
- if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
- return;
- }
-
- if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "table") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_table_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_stats_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "enable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_enable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "disable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_disable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "out") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_out_stats_help);
- return;
- }
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "table") == 0)) {
- if (n_tokens == 2) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_stats_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_dscp_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_default_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "bulk") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_bulk_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_default_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "show") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_show_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "stats") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_stats_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "meter") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_meter_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "ttl") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_ttl_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "time") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_time_read_help);
- return;
- }
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "thread") == 0) &&
- (strcmp(tokens[1], "pipeline") == 0)) {
- if (strcmp(tokens[2], "enable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_enable_help);
- return;
- }
-
- if (strcmp(tokens[2], "disable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_disable_help);
- return;
- }
- }
-
- snprintf(out, out_size, "Invalid command\n");
-}
-
-void
-cli_process(char *in, char *out, size_t out_size)
-{
- char *tokens[CMD_MAX_TOKENS];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- if (is_comment(in))
- return;
-
- status = parse_tokenize_string(in, tokens, &n_tokens);
- if (status) {
- snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
- return;
- }
-
- if (n_tokens == 0)
- return;
-
- if (strcmp(tokens[0], "help") == 0) {
- cmd_help(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- cmd_mempool(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- if (strcmp(tokens[1], "show") == 0) {
- cmd_link_show(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_link(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- cmd_swq(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_subport_profile(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "profile") == 0)) {
- cmd_tmgr_subport(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "pipe") == 0)) {
- cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_tmgr(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- cmd_tap(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- cmd_cryptodev(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "port") == 0) {
- cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "table") == 0) {
- cmd_table_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "pipeline") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[2], "period") == 0)) {
- cmd_pipeline(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 4) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[3], "match") == 0)) {
- cmd_pipeline_table(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "table") == 0)) {
- cmd_pipeline_port_in_table(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_in_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "enable") == 0)) {
- cmd_pipeline_port_in_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "disable") == 0)) {
- cmd_pipeline_port_in_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_out_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "stats") == 0)) {
- cmd_pipeline_table_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_add_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "bulk") == 0)) {
- cmd_pipeline_table_rule_add_bulk(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "delete") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_delete_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_delete(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "show") == 0)) {
- cmd_pipeline_table_rule_show(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "stats") == 0)) {
- cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "add") == 0)) {
- cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "delete") == 0)) {
- cmd_pipeline_table_meter_profile_delete(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "meter") == 0)) {
- cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "dscp") == 0)) {
- cmd_pipeline_table_dscp(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "ttl") == 0)) {
- cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "time") == 0)) {
- cmd_pipeline_table_rule_time_read(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- if (strcmp(tokens[0], "thread") == 0) {
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "enable") == 0)) {
- cmd_thread_pipeline_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "disable") == 0)) {
- cmd_thread_pipeline_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
-}
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max)
-{
- char *msg_in = NULL, *msg_out = NULL;
- FILE *f = NULL;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (msg_in_len_max == 0) ||
- (msg_out_len_max == 0))
- return -EINVAL;
-
- msg_in = malloc(msg_in_len_max + 1);
- msg_out = malloc(msg_out_len_max + 1);
- if ((msg_in == NULL) ||
- (msg_out == NULL)) {
- free(msg_out);
- free(msg_in);
- return -ENOMEM;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- free(msg_out);
- free(msg_in);
- return -EIO;
- }
-
- /* Read file */
- for ( ; ; ) {
- if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
- break;
-
- printf("%s", msg_in);
- msg_out[0] = 0;
-
- cli_process(msg_in,
- msg_out,
- msg_out_len_max);
-
- if (strlen(msg_out))
- printf("%s", msg_out);
- }
-
- /* Close file */
- fclose(f);
- free(msg_out);
- free(msg_in);
- return 0;
-}
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *line = NULL;
- FILE *f = NULL;
- uint32_t rule_id = 0, line_id = 0;
- int status = 0;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (line_len_max == 0) ||
- (rule_list == NULL) ||
- (n_rules == NULL) ||
- (line_number == NULL) ||
- (out == NULL)) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Memory allocation */
- list = malloc(sizeof(struct table_rule_list));
- if (list == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INIT(list);
-
- line = malloc(line_len_max + 1);
- if (line == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- /* Open file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- status = -EIO;
- goto cli_rule_file_process_free;
- }
-
- /* Read file */
- for (line_id = 1, rule_id = 0; ; line_id++) {
- char *tokens[CMD_MAX_TOKENS];
- struct table_rule *rule = NULL;
- uint32_t n_tokens, n_tokens_parsed, t0;
-
- /* Read next line from file. */
- if (fgets(line, line_len_max + 1, f) == NULL)
- break;
-
- /* Comment. */
- if (is_comment(line))
- continue;
-
- /* Parse line. */
- n_tokens = RTE_DIM(tokens);
- status = parse_tokenize_string(line, tokens, &n_tokens);
- if (status) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Empty line. */
- if (n_tokens == 0)
- continue;
- t0 = 0;
-
- /* Rule alloc and insert. */
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INSERT_TAIL(list, rule, node);
-
- /* Rule match. */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->match);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Rule action. */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->action);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Line completed. */
- if (t0 < n_tokens) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Increment rule count */
- rule_id++;
- }
-
- /* Close file */
- fclose(f);
-
- /* Memory free */
- free(line);
-
- *rule_list = list;
- *n_rules = rule_id;
- *line_number = line_id;
- return 0;
-
-cli_rule_file_process_free:
- if (rule_list != NULL)
- *rule_list = NULL;
-
- if (n_rules != NULL)
- *n_rules = rule_id;
-
- if (line_number != NULL)
- *line_number = line_id;
-
- if (list != NULL)
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- }
-
- if (f)
- fclose(f);
- free(line);
- free(list);
-
- return status;
-}
diff --git a/examples/ip_pipeline/cli.h b/examples/ip_pipeline/cli.h
deleted file mode 100644
index 992e4c3a4a..0000000000
--- a/examples/ip_pipeline/cli.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CLI_H__
-#define __INCLUDE_CLI_H__
-
-#include <stddef.h>
-
-void
-cli_process(char *in, char *out, size_t out_size);
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max);
-
-#endif
diff --git a/examples/ip_pipeline/common.h b/examples/ip_pipeline/common.h
deleted file mode 100644
index 0886dfbe95..0000000000
--- a/examples/ip_pipeline/common.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_COMMON_H_
-#define _INCLUDE_COMMON_H_
-
-#ifndef NAME_SIZE
-#define NAME_SIZE 64
-#endif
-
-#endif /* _INCLUDE_COMMON_H_ */
diff --git a/examples/ip_pipeline/conn.c b/examples/ip_pipeline/conn.c
deleted file mode 100644
index b2406b7af1..0000000000
--- a/examples/ip_pipeline/conn.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <sys/socket.h>
-
-#include <sys/epoll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#include <rte_string_fns.h>
-
-#include "conn.h"
-
-#define MSG_CMD_TOO_LONG "Command too long."
-
-struct conn {
- char *welcome;
- char *prompt;
- char *buf;
- char *msg_in;
- char *msg_out;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- size_t msg_in_len;
- int fd_server;
- int fd_client_group;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p)
-{
- struct sockaddr_in server_address;
- struct conn *conn;
- int fd_server, fd_client_group, status;
-
- memset(&server_address, 0, sizeof(server_address));
-
- /* Check input arguments */
- if ((p == NULL) ||
- (p->welcome == NULL) ||
- (p->prompt == NULL) ||
- (p->addr == NULL) ||
- (p->buf_size == 0) ||
- (p->msg_in_len_max == 0) ||
- (p->msg_out_len_max == 0) ||
- (p->msg_handle == NULL))
- return NULL;
-
- status = inet_aton(p->addr, &server_address.sin_addr);
- if (status == 0)
- return NULL;
-
- /* Memory allocation */
- conn = calloc(1, sizeof(struct conn));
- if (conn == NULL)
- return NULL;
-
- conn->welcome = calloc(1, CONN_WELCOME_LEN_MAX + 1);
- conn->prompt = calloc(1, CONN_PROMPT_LEN_MAX + 1);
- conn->buf = calloc(1, p->buf_size);
- conn->msg_in = calloc(1, p->msg_in_len_max + 1);
- conn->msg_out = calloc(1, p->msg_out_len_max + 1);
-
- if ((conn->welcome == NULL) ||
- (conn->prompt == NULL) ||
- (conn->buf == NULL) ||
- (conn->msg_in == NULL) ||
- (conn->msg_out == NULL)) {
- conn_free(conn);
- return NULL;
- }
-
- /* Server socket */
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(p->port);
-
- fd_server = socket(AF_INET,
- SOCK_STREAM | SOCK_NONBLOCK,
- 0);
- if (fd_server == -1) {
- conn_free(conn);
- return NULL;
- }
-
- status = bind(fd_server,
- (struct sockaddr *) &server_address,
- sizeof(server_address));
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- status = listen(fd_server, 16);
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Client group */
- fd_client_group = epoll_create(1);
- if (fd_client_group == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Fill in */
- strlcpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX + 1);
- strlcpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX + 1);
- conn->buf_size = p->buf_size;
- conn->msg_in_len_max = p->msg_in_len_max;
- conn->msg_out_len_max = p->msg_out_len_max;
- conn->msg_in_len = 0;
- conn->fd_server = fd_server;
- conn->fd_client_group = fd_client_group;
- conn->msg_handle = p->msg_handle;
-
- return conn;
-}
-
-void
-conn_free(struct conn *conn)
-{
- if (conn == NULL)
- return;
-
- if (conn->fd_client_group)
- close(conn->fd_client_group);
-
- if (conn->fd_server)
- close(conn->fd_server);
-
- free(conn->msg_out);
- free(conn->msg_in);
- free(conn->prompt);
- free(conn->welcome);
- free(conn);
-}
-
-int
-conn_poll_for_conn(struct conn *conn)
-{
- struct sockaddr_in client_address;
- struct epoll_event event;
- socklen_t client_address_length;
- int fd_client, status;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Server socket */
- client_address_length = sizeof(client_address);
- fd_client = accept4(conn->fd_server,
- (struct sockaddr *) &client_address,
- &client_address_length,
- SOCK_NONBLOCK);
- if (fd_client == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
-
- /* Client group */
- event.events = EPOLLIN | EPOLLRDHUP | EPOLLHUP;
- event.data.fd = fd_client;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_ADD,
- fd_client,
- &event);
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- /* Client */
- status = write(fd_client,
- conn->welcome,
- strlen(conn->welcome));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- return 0;
-}
-
-static int
-data_event_handle(struct conn *conn,
- int fd_client)
-{
- ssize_t len, i, status;
-
- /* Read input message */
-
- len = read(fd_client,
- conn->buf,
- conn->buf_size);
- if (len == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
- if (len == 0)
- return 0;
-
- /* Handle input messages */
- for (i = 0; i < len; i++) {
- if (conn->buf[i] == '\n') {
- size_t n;
-
- conn->msg_in[conn->msg_in_len] = 0;
- conn->msg_out[0] = 0;
-
- conn->msg_handle(conn->msg_in,
- conn->msg_out,
- conn->msg_out_len_max);
-
- n = strlen(conn->msg_out);
- if (n) {
- status = write(fd_client,
- conn->msg_out,
- n);
- if (status == -1)
- return status;
- }
-
- conn->msg_in_len = 0;
- } else if (conn->msg_in_len < conn->msg_in_len_max) {
- conn->msg_in[conn->msg_in_len] = conn->buf[i];
- conn->msg_in_len++;
- } else {
- status = write(fd_client,
- MSG_CMD_TOO_LONG,
- strlen(MSG_CMD_TOO_LONG));
- if (status == -1)
- return status;
-
- conn->msg_in_len = 0;
- }
- }
-
- /* Write prompt */
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1)
- return status;
-
- return 0;
-}
-
-static int
-control_event_handle(struct conn *conn,
- int fd_client)
-{
- int status;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_DEL,
- fd_client,
- NULL);
- if (status == -1)
- return -1;
-
- status = close(fd_client);
- if (status == -1)
- return -1;
-
- return 0;
-}
-
-int
-conn_poll_for_msg(struct conn *conn)
-{
- struct epoll_event event;
- int fd_client, status, status_data = 0, status_control = 0;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Client group */
- status = epoll_wait(conn->fd_client_group,
- &event,
- 1,
- 0);
- if (status == -1)
- return -1;
- if (status == 0)
- return 0;
-
- fd_client = event.data.fd;
-
- /* Data available */
- if (event.events & EPOLLIN)
- status_data = data_event_handle(conn, fd_client);
-
- /* Control events */
- if (event.events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP))
- status_control = control_event_handle(conn, fd_client);
-
- if (status_data || status_control)
- return -1;
-
- return 0;
-}
diff --git a/examples/ip_pipeline/conn.h b/examples/ip_pipeline/conn.h
deleted file mode 100644
index 46f9f95e9c..0000000000
--- a/examples/ip_pipeline/conn.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CONN_H__
-#define __INCLUDE_CONN_H__
-
-#include <stdint.h>
-
-struct conn;
-
-#ifndef CONN_WELCOME_LEN_MAX
-#define CONN_WELCOME_LEN_MAX 1024
-#endif
-
-#ifndef CONN_PROMPT_LEN_MAX
-#define CONN_PROMPT_LEN_MAX 16
-#endif
-
-typedef void (*conn_msg_handle_t)(char *msg_in,
- char *msg_out,
- size_t msg_out_len_max);
-
-struct conn_params {
- const char *welcome;
- const char *prompt;
- const char *addr;
- uint16_t port;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p);
-
-void
-conn_free(struct conn *conn);
-
-int
-conn_poll_for_conn(struct conn *conn);
-
-int
-conn_poll_for_msg(struct conn *conn);
-
-#endif
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
deleted file mode 100644
index cd0f9c3d4e..0000000000
--- a/examples/ip_pipeline/cryptodev.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <rte_cryptodev.h>
-#include <rte_string_fns.h>
-
-#include "cryptodev.h"
-
-#define PIPELINE_CRYPTO_SESSION_CACHE_SIZE 128
-
-static struct cryptodev_list cryptodev_list;
-
-int
-cryptodev_init(void)
-{
- TAILQ_INIT(&cryptodev_list);
-
- return 0;
-}
-
-struct cryptodev *
-cryptodev_find(const char *name)
-{
- struct cryptodev *cryptodev;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(cryptodev, &cryptodev_list, node)
- if (strcmp(cryptodev->name, name) == 0)
- return cryptodev;
-
- return NULL;
-}
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev)
-{
- return (cryptodev == NULL) ?
- TAILQ_FIRST(&cryptodev_list) :
- TAILQ_NEXT(cryptodev, node);
-}
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params)
-{
- struct rte_cryptodev_info dev_info;
- struct rte_cryptodev_config dev_conf;
- struct rte_cryptodev_qp_conf queue_conf;
- struct cryptodev *cryptodev;
- uint32_t dev_id, i;
- uint32_t socket_id;
- uint32_t cache_size;
- char mp_name[NAME_SIZE];
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- cryptodev_find(name) ||
- (params->n_queues == 0) ||
- (params->queue_size == 0) ||
- (params->session_pool_size == 0))
- return NULL;
-
- if (params->dev_name) {
- status = rte_cryptodev_get_dev_id(params->dev_name);
- if (status == -1)
- return NULL;
-
- dev_id = (uint32_t)status;
- } else {
- if (rte_cryptodev_is_valid_dev(params->dev_id) == 0)
- return NULL;
-
- dev_id = params->dev_id;
- }
-
- cache_size = (params->session_pool_size / 2 <
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE) ?
- (params->session_pool_size / 2) :
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE;
-
- socket_id = rte_cryptodev_socket_id(dev_id);
- rte_cryptodev_info_get(dev_id, &dev_info);
-
- if (dev_info.max_nb_queue_pairs < params->n_queues)
- return NULL;
-
- dev_conf.socket_id = socket_id;
- dev_conf.nb_queue_pairs = params->n_queues;
- dev_conf.ff_disable = 0;
-
- status = rte_cryptodev_configure(dev_id, &dev_conf);
- if (status < 0)
- return NULL;
-
- queue_conf.nb_descriptors = params->queue_size;
- for (i = 0; i < params->n_queues; i++) {
- status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id);
- if (status < 0)
- return NULL;
- }
-
- if (rte_cryptodev_start(dev_id) < 0)
- return NULL;
-
- cryptodev = calloc(1, sizeof(struct cryptodev));
- if (cryptodev == NULL) {
- rte_cryptodev_stop(dev_id);
- return NULL;
- }
-
- strlcpy(cryptodev->name, name, sizeof(cryptodev->name));
- cryptodev->dev_id = dev_id;
- cryptodev->n_queues = params->n_queues;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id);
- cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(
- mp_name,
- params->session_pool_size,
- 0,
- cache_size,
- 0,
- socket_id);
- if (!cryptodev->mp_create)
- goto error_exit;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp_priv%u", name, dev_id);
- cryptodev->mp_init = rte_mempool_create(
- NULL,
- params->session_pool_size,
- rte_cryptodev_sym_get_private_session_size(dev_id),
- cache_size,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- socket_id,
- 0);
- if (!cryptodev->mp_init)
- goto error_exit;
-
- TAILQ_INSERT_TAIL(&cryptodev_list, cryptodev, node);
-
- return cryptodev;
-
-error_exit:
- rte_mempool_free(cryptodev->mp_create);
- rte_mempool_free(cryptodev->mp_init);
-
- free(cryptodev);
-
- return NULL;
-}
diff --git a/examples/ip_pipeline/cryptodev.h b/examples/ip_pipeline/cryptodev.h
deleted file mode 100644
index d00434379e..0000000000
--- a/examples/ip_pipeline/cryptodev.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SYM_C_H_
-#define _INCLUDE_SYM_C_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_cryptodev.h>
-
-#include "common.h"
-
-struct cryptodev {
- TAILQ_ENTRY(cryptodev) node;
- char name[NAME_SIZE];
- uint16_t dev_id;
- uint32_t n_queues;
- struct rte_mempool *mp_create;
- struct rte_mempool *mp_init;
-};
-
-TAILQ_HEAD(cryptodev_list, cryptodev);
-
-int
-cryptodev_init(void);
-
-struct cryptodev *
-cryptodev_find(const char *name);
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev);
-
-struct cryptodev_params {
- const char *dev_name;
- uint32_t dev_id; /**< Valid only when *dev_name* is NULL. */
- uint32_t n_queues;
- uint32_t queue_size;
- uint32_t session_pool_size;
-};
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params);
-
-#endif
diff --git a/examples/ip_pipeline/examples/firewall.cli b/examples/ip_pipeline/examples/firewall.cli
deleted file mode 100644
index 269256c161..0000000000
--- a/examples/ip_pipeline/examples/firewall.cli
+++ /dev/null
@@ -1,59 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Firewall |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; -+-
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match acl ipv4 offset 270 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd drop
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow.cli b/examples/ip_pipeline/examples/flow.cli
deleted file mode 100644
index 426ff90255..0000000000
--- a/examples/ip_pipeline/examples/flow.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Flow |
-; LINK2 RXQ0 --->| Classification |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 16 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF offset 278 buckets 16K size 65K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.10 200.0.0.10 100 200 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.11 200.0.0.11 101 201 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.12 200.0.0.12 102 202 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.13 200.0.0.13 103 203 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow_crypto.cli b/examples/ip_pipeline/examples/flow_crypto.cli
deleted file mode 100644
index 849f9d5fec..0000000000
--- a/examples/ip_pipeline/examples/flow_crypto.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> CRYPTO0 TXQ0
-; | Flow |
-; CRYPTO0 RXQ0-->| Classification |---> LINK0 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 280 20
-; 4 Packet 256 1536
-; 5 Crypto Operation 1792 160
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 1
-
-link LINK0 dev 81:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-#Cryptodev
-cryptodev CRYPTO0 dev crypto_aesni_gcm0 queue 1 1024 max_sessions 512
-
-table action profile AP0 ipv4 offset 270 fwd sym_crypto dev CRYPTO0 offset 1792
-table action profile AP1 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 1
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 cryptodev CRYPTO0 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 cryptodev CRYPTO0 txq 0 offset 1792
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 8 mask FFFFFFFF00000000 offset 282 buckets 1K size 4K action AP0
-pipeline PIPELINE0 table match stub action AP1
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-
-thread 2 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 2
-
-#AES-GCM encrypt
-pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto encrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-#AES-GCM decrypt
-#pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto decrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
diff --git a/examples/ip_pipeline/examples/l2fwd.cli b/examples/ip_pipeline/examples/l2fwd.cli
deleted file mode 100644
index 35e77cc968..0000000000
--- a/examples/ip_pipeline/examples/l2fwd.cli
+++ /dev/null
@@ -1,51 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; The pipeline below implements a simple pass-through connection between the
-; input ports to the output ports, as in this diagram:
-; ________________
-; LINK0 RXQ0 --->|................|---> LINK1 TXQ0
-; | |
-; LINK1 RXQ0 --->|................|---> LINK0 TXQ0
-; | PIPELINE0 |
-; LINK2 RXQ0 --->|................|---> LINK3 TXQ0
-; | |
-; LINK3 RXQ0 --->|................|---> LINK2 TXQ0
-; |________________|
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 1
-pipeline PIPELINE0 table 1 rule add match default action fwd port 0
-pipeline PIPELINE0 table 2 rule add match default action fwd port 3
-pipeline PIPELINE0 table 3 rule add match default action fwd port 2
diff --git a/examples/ip_pipeline/examples/route.cli b/examples/ip_pipeline/examples/route.cli
deleted file mode 100644
index 579b36a659..0000000000
--- a/examples/ip_pipeline/examples/route.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Routing |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; +-----------> SINK0 (route miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/route_ecmp.cli b/examples/ip_pipeline/examples/route_ecmp.cli
deleted file mode 100644
index 06434a2560..0000000000
--- a/examples/ip_pipeline/examples/route_ecmp.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; Equal Cost Multi-Path (ECMP) Routing
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile APRT ipv4 offset 270 fwd balance offset 278 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF outoffset 256
-table action profile APNH ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action APRT
-pipeline PIPELINE0 table match array offset 256 size 64K action APNH
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd table 1 balance 0 0 0 0 1 1 2 2
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd table 1 balance 1 1 1 1 2 2 3 3
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd table 1 balance 2 2 2 2 3 3 0 0
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd table 1 balance 3 3 3 3 0 0 1 1
-
-pipeline PIPELINE0 table 1 rule add match array 0 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 1 rule add match array 1 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 1 rule add match array 2 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 1 rule add match array 3 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/rss.cli b/examples/ip_pipeline/examples/rss.cli
deleted file mode 100644
index 29c0a91392..0000000000
--- a/examples/ip_pipeline/examples/rss.cli
+++ /dev/null
@@ -1,112 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; This setup demonstrates the usage of NIC Receive Side Scaling (RSS) feature.
-; Each NIC splits the input traffic into 4 RX queues, with each of its RX queues
-; being handled by a different pipeline:
-;
-; +-----------+ +----------+
-; +--------------------------->| | | |
-; | +------------------->| PIPELINE0 +--->| LINK 0 |--->
-; | | +------------->| (CORE A) | | TX |
-; | | | +------->| | | |
-; | | | | +-----------+ +----------+
-; +----------+ | | | |
-; | |-------+ | | |
-;--->| LINK 0 |-----------+ | | |
-; | RX |---------+ | | | |
-; | |-------+ | | | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | | +---|-----|-----|------->| | | |
-; +----------+ | | | +---|-----|------->| PIPELINE1 +--->| LINK 1 |--->
-; | |-------|-|-----+ | | +---|------->| (CORE B) | | TX |
-;--->| LINK 1 |-------|-|-------+ | | | +----->| | | |
-; | RX |-------|-|-------+ | | | | +-----------+ +----------+
-; | |-------|-|-----+ | | | | |
-; +----------+ | | | | | | | |
-; | | | | | | | |
-; +----------+ | | | | | | | |
-; | |-------|-|-----|-|---+ | | |
-;--->| LINK 2 |-------|-|-----|-|-----+ | | +-----------+ +----------+
-; | RX |-----+ | +-----|-|---------|-|----->| | | |
-; | |---+ | | | +---------|-|----->| PIPELINE2 +--->| LINK 2 |--->
-; +----------+ | +-|-------|-----------|-|----->| (CORE C) | | TX |
-; | | | | | +--->| | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | |---|---|-------|-----------+ | |
-;--->| LINK 3 |---|---|-------|-------------+ |
-; | RX |---|---|-------|---------------+
-; | |---|---|-------|-----------+
-; +----------+ | | | |
-; | | | | +-----------+ +----------+
-; | +-------|-----------|------->| | | |
-; | +-----------|------->| PIPELINE3 +--->| LINK 3 |--->
-; +-----------------------|------->| (CORE D) | | TX |
-; +------->| | | |
-; +-----------+ +----------+
-;
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK1 dev 0000:02:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK2 dev 0000:06:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK3 dev 0000:06:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE1 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE1 port in bsz 32 link LINK0 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK1 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK2 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK3 rxq 1
-pipeline PIPELINE1 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE1 table match stub
-pipeline PIPELINE1 port in 0 table 0
-pipeline PIPELINE1 port in 1 table 0
-pipeline PIPELINE1 port in 2 table 0
-pipeline PIPELINE1 port in 3 table 0
-pipeline PIPELINE1 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE2 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE2 port in bsz 32 link LINK0 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK1 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK2 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK3 rxq 2
-pipeline PIPELINE2 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE2 table match stub
-pipeline PIPELINE2 port in 0 table 0
-pipeline PIPELINE2 port in 1 table 0
-pipeline PIPELINE2 port in 2 table 0
-pipeline PIPELINE2 port in 3 table 0
-pipeline PIPELINE2 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE3 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE3 port in bsz 32 link LINK0 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK1 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK2 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK3 rxq 3
-pipeline PIPELINE3 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE3 table match stub
-pipeline PIPELINE3 port in 0 table 0
-pipeline PIPELINE3 port in 1 table 0
-pipeline PIPELINE3 port in 2 table 0
-pipeline PIPELINE3 port in 3 table 0
-pipeline PIPELINE3 table 0 rule add match default action fwd port 0
-
-thread 1 pipeline PIPELINE0 enable
-thread 2 pipeline PIPELINE1 enable
-thread 3 pipeline PIPELINE2 enable
-thread 4 pipeline PIPELINE3 enable
diff --git a/examples/ip_pipeline/examples/tap.cli b/examples/ip_pipeline/examples/tap.cli
deleted file mode 100644
index 600cea2643..0000000000
--- a/examples/ip_pipeline/examples/tap.cli
+++ /dev/null
@@ -1,66 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________ ______________________
-; | | TAP0 | |
-; LINK0 RXQ0 --->|...............|------->|--+ |
-; | | TAP1 | | br0 |
-; LINK1 TXQ0 <---|...............|<-------|<-+ |
-; | | | Linux Kernel |
-; | PIPELINE0 | | Network Stack |
-; | | TAP1 | |
-; LINK1 RXQ0 --->|...............|------->|--+ |
-; | | TAP0 | | br0 |
-; LINK0 TXQ0 <---|...............|<-------|<-+ |
-; |_______________| |______________________|
-;
-; Configure Linux kernel bridge between TAP0 and TAP1 interfaces:
-; [Linux]$ brctl addbr br0
-; [Linux]$ brctl addif br0 TAP0
-; [Linux]$ brctl addif br0 TAP1
-; [Linux]$ ifconfig TAP0 up
-; [Linux]$ ifconfig TAP1 up
-; [Linux]$ ifconfig br0 up
-;
-; Monitor packet forwarding performed by Linux kernel between TAP0 and TAP1:
-; [Linux]$ tcpdump -i TAP0
-; [Linux]$ tcpdump -i TAP1
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-tap TAP0
-tap TAP1
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP1 mempool MEMPOOL0 mtu 1500
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP0 mempool MEMPOOL0 mtu 1500
-
-pipeline PIPELINE0 port out bsz 32 tap TAP0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 tap TAP1
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
-pipeline PIPELINE0 table 2 rule add match default action fwd port 2
-pipeline PIPELINE0 table 3 rule add match default action fwd port 3
diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
deleted file mode 100644
index 4d69ebebfb..0000000000
--- a/examples/ip_pipeline/link.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_ethdev.h>
-#include <rte_string_fns.h>
-
-#include "link.h"
-#include "mempool.h"
-
-static struct link_list link_list;
-
-int
-link_init(void)
-{
- TAILQ_INIT(&link_list);
-
- return 0;
-}
-
-struct link *
-link_find(const char *name)
-{
- struct link *link;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(link, &link_list, node)
- if (strcmp(link->name, name) == 0)
- return link;
-
- return NULL;
-}
-
-struct link *
-link_next(struct link *link)
-{
- return (link == NULL) ? TAILQ_FIRST(&link_list) : TAILQ_NEXT(link, node);
-}
-
-static struct rte_eth_conf port_conf_default = {
- .link_speeds = 0,
- .rxmode = {
- .mq_mode = RTE_ETH_MQ_RX_NONE,
- .mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_key_len = 40,
- .rss_hf = 0,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
- .lpbk_mode = 0,
-};
-
-#define RETA_CONF_SIZE (RTE_ETH_RSS_RETA_SIZE_512 / RTE_ETH_RETA_GROUP_SIZE)
-
-static int
-rss_setup(uint16_t port_id,
- uint16_t reta_size,
- struct link_params_rss *rss)
-{
- struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
- uint32_t i;
- int status;
-
- /* RETA setting */
- memset(reta_conf, 0, sizeof(reta_conf));
-
- for (i = 0; i < reta_size; i++)
- reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX;
-
- for (i = 0; i < reta_size; i++) {
- uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE;
- uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE;
- uint32_t rss_qs_pos = i % rss->n_queues;
-
- reta_conf[reta_id].reta[reta_pos] =
- (uint16_t) rss->queue_id[rss_qs_pos];
- }
-
- /* RETA update */
- status = rte_eth_dev_rss_reta_update(port_id,
- reta_conf,
- reta_size);
-
- return status;
-}
-
-struct link *
-link_create(const char *name, struct link_params *params)
-{
- struct rte_eth_dev_info port_info;
- struct rte_eth_conf port_conf;
- struct link *link;
- struct link_params_rss *rss;
- struct mempool *mempool;
- uint32_t cpu_id, i;
- int status;
- uint16_t port_id;
-
- /* Check input params */
- if ((name == NULL) ||
- link_find(name) ||
- (params == NULL) ||
- (params->rx.n_queues == 0) ||
- (params->rx.queue_size == 0) ||
- (params->tx.n_queues == 0) ||
- (params->tx.queue_size == 0))
- return NULL;
-
- port_id = params->port_id;
- if (params->dev_name) {
- status = rte_eth_dev_get_port_by_name(params->dev_name,
- &port_id);
-
- if (status)
- return NULL;
- } else
- if (!rte_eth_dev_is_valid_port(port_id))
- return NULL;
-
- if (rte_eth_dev_info_get(port_id, &port_info) != 0)
- return NULL;
-
- mempool = mempool_find(params->rx.mempool_name);
- if (mempool == NULL)
- return NULL;
-
- rss = params->rx.rss;
- if (rss) {
- if ((port_info.reta_size == 0) ||
- (port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512))
- return NULL;
-
- if ((rss->n_queues == 0) ||
- (rss->n_queues >= LINK_RXQ_RSS_MAX))
- return NULL;
-
- for (i = 0; i < rss->n_queues; i++)
- if (rss->queue_id[i] >= port_info.max_rx_queues)
- return NULL;
- }
-
- /**
- * Resource create
- */
- /* Port */
- memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
- if (rss) {
- port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
- port_conf.rx_adv_conf.rss_conf.rss_hf =
- (RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP) &
- port_info.flow_type_rss_offloads;
- }
-
- cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
- if (cpu_id == (uint32_t) SOCKET_ID_ANY)
- cpu_id = 0;
-
- status = rte_eth_dev_configure(
- port_id,
- params->rx.n_queues,
- params->tx.n_queues,
- &port_conf);
-
- if (status < 0)
- return NULL;
-
- if (params->promiscuous) {
- status = rte_eth_promiscuous_enable(port_id);
- if (status != 0)
- return NULL;
- }
-
- /* Port RX */
- for (i = 0; i < params->rx.n_queues; i++) {
- status = rte_eth_rx_queue_setup(
- port_id,
- i,
- params->rx.queue_size,
- cpu_id,
- NULL,
- mempool->m);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port TX */
- for (i = 0; i < params->tx.n_queues; i++) {
- status = rte_eth_tx_queue_setup(
- port_id,
- i,
- params->tx.queue_size,
- cpu_id,
- NULL);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port start */
- status = rte_eth_dev_start(port_id);
- if (status < 0)
- return NULL;
-
- if (rss) {
- status = rss_setup(port_id, port_info.reta_size, rss);
-
- if (status) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
- }
-
- /* Port link up */
- status = rte_eth_dev_set_link_up(port_id);
- if ((status < 0) && (status != -ENOTSUP)) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node allocation */
- link = calloc(1, sizeof(struct link));
- if (link == NULL) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(link->name, name, sizeof(link->name));
- link->port_id = port_id;
- link->n_rxq = params->rx.n_queues;
- link->n_txq = params->tx.n_queues;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&link_list, link, node);
-
- return link;
-}
-
-int
-link_is_up(const char *name)
-{
- struct rte_eth_link link_params;
- struct link *link;
-
- /* Check input params */
- if (name == NULL)
- return 0;
-
- link = link_find(name);
- if (link == NULL)
- return 0;
-
- /* Resource */
- if (rte_eth_link_get(link->port_id, &link_params) < 0)
- return 0;
-
- return (link_params.link_status == RTE_ETH_LINK_DOWN) ? 0 : 1;
-}
diff --git a/examples/ip_pipeline/link.h b/examples/ip_pipeline/link.h
deleted file mode 100644
index 34ff1149e0..0000000000
--- a/examples/ip_pipeline/link.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_LINK_H_
-#define _INCLUDE_LINK_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include "common.h"
-
-#ifndef LINK_RXQ_RSS_MAX
-#define LINK_RXQ_RSS_MAX 16
-#endif
-
-struct link {
- TAILQ_ENTRY(link) node;
- char name[NAME_SIZE];
- uint16_t port_id;
- uint32_t n_rxq;
- uint32_t n_txq;
-};
-
-TAILQ_HEAD(link_list, link);
-
-int
-link_init(void);
-
-struct link *
-link_find(const char *name);
-
-struct link *
-link_next(struct link *link);
-
-struct link_params_rss {
- uint32_t queue_id[LINK_RXQ_RSS_MAX];
- uint32_t n_queues;
-};
-
-struct link_params {
- const char *dev_name;
- uint16_t port_id; /**< Valid only when *dev_name* is NULL. */
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- const char *mempool_name;
- struct link_params_rss *rss;
- } rx;
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- } tx;
-
- int promiscuous;
-};
-
-struct link *
-link_create(const char *name, struct link_params *params);
-
-int
-link_is_up(const char *name);
-
-#endif /* _INCLUDE_LINK_H_ */
diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c
deleted file mode 100644
index 663f538f02..0000000000
--- a/examples/ip_pipeline/main.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include <rte_launch.h>
-#include <rte_eal.h>
-
-#include "cli.h"
-#include "conn.h"
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-static const char usage[] =
- "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n";
-
-static const char welcome[] =
- "\n"
- "Welcome to IP Pipeline!\n"
- "\n";
-
-static const char prompt[] = "pipeline> ";
-
-static struct app_params {
- struct conn_params conn;
- char *script_name;
-} app = {
- .conn = {
- .welcome = welcome,
- .prompt = prompt,
- .addr = "0.0.0.0",
- .port = 8086,
- .buf_size = 1024 * 1024,
- .msg_in_len_max = 1024,
- .msg_out_len_max = 1024 * 1024,
- .msg_handle = cli_process,
- },
- .script_name = NULL,
-};
-
-static int
-parse_args(int argc, char **argv)
-{
- char *app_name = argv[0];
- struct option lgopts[] = {
- { NULL, 0, 0, 0 }
- };
- int opt, option_index;
- int h_present, p_present, s_present, n_args, i;
-
- /* Skip EAL input args */
- n_args = argc;
- for (i = 0; i < n_args; i++)
- if (strcmp(argv[i], "--") == 0) {
- argc -= i;
- argv += i;
- break;
- }
-
- if (i == n_args)
- return 0;
-
- /* Parse args */
- h_present = 0;
- p_present = 0;
- s_present = 0;
-
- while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index))
- != EOF)
- switch (opt) {
- case 'h':
- if (h_present) {
- printf("Error: Multiple -h arguments\n");
- return -1;
- }
- h_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -h not provided\n");
- return -1;
- }
-
- app.conn.addr = strdup(optarg);
- if (app.conn.addr == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- case 'p':
- if (p_present) {
- printf("Error: Multiple -p arguments\n");
- return -1;
- }
- p_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -p not provided\n");
- return -1;
- }
-
- app.conn.port = (uint16_t) atoi(optarg);
- break;
-
- case 's':
- if (s_present) {
- printf("Error: Multiple -s arguments\n");
- return -1;
- }
- s_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -s not provided\n");
- return -1;
- }
-
- app.script_name = strdup(optarg);
- if (app.script_name == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- default:
- printf(usage, app_name);
- return -1;
- }
-
- optind = 1; /* reset getopt lib */
-
- return 0;
-}
-
-int
-main(int argc, char **argv)
-{
- struct conn *conn;
- int status;
-
- /* Parse application arguments */
- status = parse_args(argc, argv);
- if (status < 0)
- return status;
-
- /* EAL */
- status = rte_eal_init(argc, argv);
- if (status < 0) {
- printf("Error: EAL initialization failed (%d)\n", status);
- return status;
- };
-
- /* Connectivity */
- conn = conn_init(&app.conn);
- if (conn == NULL) {
- printf("Error: Connectivity initialization failed (%d)\n",
- status);
- return status;
- };
-
- /* Mempool */
- status = mempool_init();
- if (status) {
- printf("Error: Mempool initialization failed (%d)\n", status);
- return status;
- }
-
- /* Link */
- status = link_init();
- if (status) {
- printf("Error: Link initialization failed (%d)\n", status);
- return status;
- }
-
- /* SWQ */
- status = swq_init();
- if (status) {
- printf("Error: SWQ initialization failed (%d)\n", status);
- return status;
- }
-
- /* Traffic Manager */
- status = tmgr_init();
- if (status) {
- printf("Error: TMGR initialization failed (%d)\n", status);
- return status;
- }
-
- /* TAP */
- status = tap_init();
- if (status) {
- printf("Error: TAP initialization failed (%d)\n", status);
- return status;
- }
-
- /* Sym Crypto */
- status = cryptodev_init();
- if (status) {
- printf("Error: Cryptodev initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Action */
- status = port_in_action_profile_init();
- if (status) {
- printf("Error: Input port action profile initialization failed (%d)\n", status);
- return status;
- }
-
- status = table_action_profile_init();
- if (status) {
- printf("Error: Action profile initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Pipeline */
- status = pipeline_init();
- if (status) {
- printf("Error: Pipeline initialization failed (%d)\n", status);
- return status;
- }
-
- /* Thread */
- status = thread_init();
- if (status) {
- printf("Error: Thread initialization failed (%d)\n", status);
- return status;
- }
-
- rte_eal_mp_remote_launch(
- thread_main,
- NULL,
- SKIP_MAIN);
-
- /* Script */
- if (app.script_name)
- cli_script_process(app.script_name,
- app.conn.msg_in_len_max,
- app.conn.msg_out_len_max);
-
- /* Dispatch loop */
- for ( ; ; ) {
- conn_poll_for_conn(conn);
-
- conn_poll_for_msg(conn);
- }
-}
diff --git a/examples/ip_pipeline/mempool.c b/examples/ip_pipeline/mempool.c
deleted file mode 100644
index f5d2a7d108..0000000000
--- a/examples/ip_pipeline/mempool.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-
-#include "mempool.h"
-
-#define BUFFER_SIZE_MIN (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-
-static struct mempool_list mempool_list;
-
-int
-mempool_init(void)
-{
- TAILQ_INIT(&mempool_list);
-
- return 0;
-}
-
-struct mempool *
-mempool_find(const char *name)
-{
- struct mempool *mempool;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(mempool, &mempool_list, node)
- if (strcmp(mempool->name, name) == 0)
- return mempool;
-
- return NULL;
-}
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params)
-{
- struct mempool *mempool;
- struct rte_mempool *m;
-
- /* Check input params */
- if ((name == NULL) ||
- mempool_find(name) ||
- (params == NULL) ||
- (params->buffer_size < BUFFER_SIZE_MIN) ||
- (params->pool_size == 0))
- return NULL;
-
- /* Resource create */
- m = rte_pktmbuf_pool_create(
- name,
- params->pool_size,
- params->cache_size,
- 0,
- params->buffer_size - sizeof(struct rte_mbuf),
- params->cpu_id);
-
- if (m == NULL)
- return NULL;
-
- /* Node allocation */
- mempool = calloc(1, sizeof(struct mempool));
- if (mempool == NULL) {
- rte_mempool_free(m);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(mempool->name, name, sizeof(mempool->name));
- mempool->m = m;
- mempool->buffer_size = params->buffer_size;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&mempool_list, mempool, node);
-
- return mempool;
-}
diff --git a/examples/ip_pipeline/mempool.h b/examples/ip_pipeline/mempool.h
deleted file mode 100644
index bd46a11ca0..0000000000
--- a/examples/ip_pipeline/mempool.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_MEMPOOL_H_
-#define _INCLUDE_MEMPOOL_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_mempool.h>
-
-#include "common.h"
-
-struct mempool {
- TAILQ_ENTRY(mempool) node;
- char name[NAME_SIZE];
- struct rte_mempool *m;
- uint32_t buffer_size;
-};
-
-TAILQ_HEAD(mempool_list, mempool);
-
-int
-mempool_init(void);
-
-struct mempool *
-mempool_find(const char *name);
-
-struct mempool_params {
- uint32_t buffer_size;
- uint32_t pool_size;
- uint32_t cache_size;
- uint32_t cpu_id;
-};
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params);
-
-#endif /* _INCLUDE_MEMPOOL_H_ */
diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build
deleted file mode 100644
index 68049157e4..0000000000
--- a/examples/ip_pipeline/meson.build
+++ /dev/null
@@ -1,30 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017-2018 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'
-
-build = cc.has_header('sys/epoll.h')
-if not build
- subdir_done()
-endif
-
-deps += ['pipeline', 'bus_pci']
-allow_experimental_apis = true
-sources = files(
- 'action.c',
- 'cli.c',
- 'conn.c',
- 'cryptodev.c',
- 'link.c',
- 'main.c',
- 'mempool.c',
- 'parser.c',
- 'pipeline.c',
- 'swq.c',
- 'tap.c',
- 'thread.c',
- 'tmgr.c',
-)
diff --git a/examples/ip_pipeline/parser.c b/examples/ip_pipeline/parser.c
deleted file mode 100644
index 8baa70e1f4..0000000000
--- a/examples/ip_pipeline/parser.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation.
- * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
- * All rights reserved.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <libgen.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include <rte_errno.h>
-#include <rte_string_fns.h>
-
-#include "parser.h"
-
-static uint32_t
-get_hex_val(char c)
-{
- switch (c) {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- return c - '0';
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- return c - 'A' + 10;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- return c - 'a' + 10;
- default:
- return 0;
- }
-}
-
-int
-parser_read_arg_bool(const char *p)
-{
- p = rte_str_skip_leading_spaces(p);
- int result = -EINVAL;
-
- if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
- ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
- p += 3;
- result = 1;
- }
-
- if (((p[0] == 'o') && (p[1] == 'n')) ||
- ((p[0] == 'O') && (p[1] == 'N'))) {
- p += 2;
- result = 1;
- }
-
- if (((p[0] == 'n') && (p[1] == 'o')) ||
- ((p[0] == 'N') && (p[1] == 'O'))) {
- p += 2;
- result = 0;
- }
-
- if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
- ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
- p += 3;
- result = 0;
- }
-
- p = rte_str_skip_leading_spaces(p);
-
- if (p[0] != '\0')
- return -EINVAL;
-
- return result;
-}
-
-int
-parser_read_uint64(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
- if (!isdigit(*p))
- return -EINVAL;
-
- val = strtoul(p, &next, 10);
- if (p == next)
- return -EINVAL;
-
- p = next;
- switch (*p) {
- case 'T':
- val *= 1024ULL;
- /* fall through */
- case 'G':
- val *= 1024ULL;
- /* fall through */
- case 'M':
- val *= 1024ULL;
- /* fall through */
- case 'k':
- case 'K':
- val *= 1024ULL;
- p++;
- break;
- }
-
- p = rte_str_skip_leading_spaces(p);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint64_hex(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
-
- val = strtoul(p, &next, 16);
- if (p == next)
- return -EINVAL;
-
- p = rte_str_skip_leading_spaces(next);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32_hex(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16_hex(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8_hex(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
-{
- uint32_t i;
-
- if ((string == NULL) ||
- (tokens == NULL) ||
- (*n_tokens < 1))
- return -EINVAL;
-
- for (i = 0; i < *n_tokens; i++) {
- tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
- if (tokens[i] == NULL)
- break;
- }
-
- if ((i == *n_tokens) &&
- (NULL != strtok_r(string, PARSE_DELIMITER, &string)))
- return -E2BIG;
-
- *n_tokens = i;
- return 0;
-}
-
-int
-parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
-{
- char *c;
- uint32_t len, i;
-
- /* Check input parameters */
- if ((src == NULL) ||
- (dst == NULL) ||
- (size == NULL) ||
- (*size == 0))
- return -1;
-
- len = strlen(src);
- if (((len & 3) != 0) ||
- (len > (*size) * 2))
- return -1;
- *size = len / 2;
-
- for (c = src; *c != 0; c++) {
- if ((((*c) >= '0') && ((*c) <= '9')) ||
- (((*c) >= 'A') && ((*c) <= 'F')) ||
- (((*c) >= 'a') && ((*c) <= 'f')))
- continue;
-
- return -1;
- }
-
- /* Convert chars to bytes */
- for (i = 0; i < *size; i++)
- dst[i] = get_hex_val(src[2 * i]) * 16 +
- get_hex_val(src[2 * i + 1]);
-
- return 0;
-}
-
-int
-parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels)
-{
- uint32_t n_max_labels = *n_labels, count = 0;
-
- /* Check for void list of labels */
- if (strcmp(string, "<void>") == 0) {
- *n_labels = 0;
- return 0;
- }
-
- /* At least one label should be present */
- for ( ; (*string != '\0'); ) {
- char *next;
- int value;
-
- if (count >= n_max_labels)
- return -1;
-
- if (count > 0) {
- if (string[0] != ':')
- return -1;
-
- string++;
- }
-
- value = strtol(string, &next, 10);
- if (next == string)
- return -1;
- string = next;
-
- labels[count++] = (uint32_t) value;
- }
-
- *n_labels = count;
- return 0;
-}
-
-static struct rte_ether_addr *
-my_ether_aton(const char *a)
-{
- int i;
- char *end;
- unsigned long o[RTE_ETHER_ADDR_LEN];
- static struct rte_ether_addr ether_addr;
-
- i = 0;
- do {
- errno = 0;
- o[i] = strtoul(a, &end, 16);
- if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
- return NULL;
- a = end + 1;
- } while (++i != RTE_DIM(o) && end[0] != 0);
-
- /* Junk at the end of line */
- if (end[0] != 0)
- return NULL;
-
- /* Support the format XX:XX:XX:XX:XX:XX */
- if (i == RTE_ETHER_ADDR_LEN) {
- while (i-- != 0) {
- if (o[i] > UINT8_MAX)
- return NULL;
- ether_addr.addr_bytes[i] = (uint8_t)o[i];
- }
- /* Support the format XXXX:XXXX:XXXX */
- } else if (i == RTE_ETHER_ADDR_LEN / 2) {
- while (i-- != 0) {
- if (o[i] > UINT16_MAX)
- return NULL;
- ether_addr.addr_bytes[i * 2] = (uint8_t)(o[i] >> 8);
- ether_addr.addr_bytes[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
- }
- /* unknown format */
- } else
- return NULL;
-
- return (struct rte_ether_addr *)ðer_addr;
-}
-
-int
-parse_ipv4_addr(const char *token, struct in_addr *ipv4)
-{
- if (strlen(token) >= INET_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET, token, ipv4) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6)
-{
- if (strlen(token) >= INET6_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET6, token, ipv6) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_mac_addr(const char *token, struct rte_ether_addr *addr)
-{
- struct rte_ether_addr *tmp;
-
- tmp = my_ether_aton(token);
- if (tmp == NULL)
- return -1;
-
- *addr = *tmp;
- return 0;
-}
-
-int
-parse_cpu_core(const char *entry,
- struct cpu_core_params *p)
-{
- size_t num_len;
- char num[8];
-
- uint32_t s = 0, c = 0, h = 0, val;
- uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
- const char *next = rte_str_skip_leading_spaces(entry);
- char type;
-
- if (p == NULL)
- return -EINVAL;
-
- /* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
- while (*next != '\0') {
- /* If everything parsed nothing should left */
- if (s_parsed && c_parsed && h_parsed)
- return -EINVAL;
-
- type = *next;
- switch (type) {
- case 's':
- case 'S':
- if (s_parsed || c_parsed || h_parsed)
- return -EINVAL;
- s_parsed = 1;
- next++;
- break;
- case 'c':
- case 'C':
- if (c_parsed || h_parsed)
- return -EINVAL;
- c_parsed = 1;
- next++;
- break;
- case 'h':
- case 'H':
- if (h_parsed)
- return -EINVAL;
- h_parsed = 1;
- next++;
- break;
- default:
- /* If it start from digit it must be only core id. */
- if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
- return -EINVAL;
-
- type = 'C';
- }
-
- for (num_len = 0; *next != '\0'; next++, num_len++) {
- if (num_len == RTE_DIM(num))
- return -EINVAL;
-
- if (!isdigit(*next))
- break;
-
- num[num_len] = *next;
- }
-
- if (num_len == 0 && type != 'h' && type != 'H')
- return -EINVAL;
-
- if (num_len != 0 && (type == 'h' || type == 'H'))
- return -EINVAL;
-
- num[num_len] = '\0';
- val = strtol(num, NULL, 10);
-
- h = 0;
- switch (type) {
- case 's':
- case 'S':
- s = val;
- break;
- case 'c':
- case 'C':
- c = val;
- break;
- case 'h':
- case 'H':
- h = 1;
- break;
- }
- }
-
- p->socket_id = s;
- p->core_id = c;
- p->thread_id = h;
- return 0;
-}
diff --git a/examples/ip_pipeline/parser.h b/examples/ip_pipeline/parser.h
deleted file mode 100644
index c8f0187d71..0000000000
--- a/examples/ip_pipeline/parser.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_PARSER_H__
-#define __INCLUDE_PARSER_H__
-
-#include <ctype.h>
-#include <stdint.h>
-
-#include <rte_ip.h>
-#include <rte_ether.h>
-
-#define PARSE_DELIMITER " \f\n\r\t\v"
-
-static inline size_t
-skip_digits(const char *src)
-{
- size_t i;
-
- for (i = 0; isdigit(src[i]); i++)
- ;
-
- return i;
-}
-
-int parser_read_arg_bool(const char *p);
-
-int parser_read_uint64(uint64_t *value, const char *p);
-int parser_read_uint32(uint32_t *value, const char *p);
-int parser_read_uint16(uint16_t *value, const char *p);
-int parser_read_uint8(uint8_t *value, const char *p);
-
-int parser_read_uint64_hex(uint64_t *value, const char *p);
-int parser_read_uint32_hex(uint32_t *value, const char *p);
-int parser_read_uint16_hex(uint16_t *value, const char *p);
-int parser_read_uint8_hex(uint8_t *value, const char *p);
-
-int parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
-
-int parse_ipv4_addr(const char *token, struct in_addr *ipv4);
-int parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6);
-int parse_mac_addr(const char *token, struct rte_ether_addr *addr);
-int parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels);
-
-struct cpu_core_params {
- uint32_t socket_id;
- uint32_t core_id;
- uint32_t thread_id;
-};
-
-int parse_cpu_core(const char *entry, struct cpu_core_params *p);
-
-int parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens);
-
-#endif
diff --git a/examples/ip_pipeline/pipeline.c b/examples/ip_pipeline/pipeline.c
deleted file mode 100644
index 792aab0059..0000000000
--- a/examples/ip_pipeline/pipeline.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-
-#include <rte_string_fns.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_ring.h>
-#include <rte_port_source_sink.h>
-#include <rte_port_fd.h>
-#include <rte_port_sched.h>
-#include <rte_port_sym_crypto.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_func.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_stub.h>
-
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "tap.h"
-#include "tmgr.h"
-#include "swq.h"
-#include "cryptodev.h"
-
-#ifndef PIPELINE_MSGQ_SIZE
-#define PIPELINE_MSGQ_SIZE 64
-#endif
-
-#ifndef TABLE_LPM_NUMBER_TBL8
-#define TABLE_LPM_NUMBER_TBL8 256
-#endif
-
-static struct pipeline_list pipeline_list;
-
-int
-pipeline_init(void)
-{
- TAILQ_INIT(&pipeline_list);
-
- return 0;
-}
-
-struct pipeline *
-pipeline_find(const char *name)
-{
- struct pipeline *pipeline;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(pipeline, &pipeline_list, node)
- if (strcmp(name, pipeline->name) == 0)
- return pipeline;
-
- return NULL;
-}
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params)
-{
- char msgq_name[NAME_MAX];
- struct rte_pipeline_params pp;
- struct pipeline *pipeline;
- struct rte_pipeline *p;
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- /* Check input params */
- if ((name == NULL) ||
- pipeline_find(name) ||
- (params == NULL) ||
- (params->timer_period_ms == 0))
- return NULL;
-
- /* Resource create */
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-REQ", name);
-
- msgq_req = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_req == NULL)
- return NULL;
-
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-RSP", name);
-
- msgq_rsp = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_rsp == NULL) {
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- pp.name = name;
- pp.socket_id = (int) params->cpu_id;
- pp.offset_port_id = params->offset_port_id;
-
- p = rte_pipeline_create(&pp);
- if (p == NULL) {
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node allocation */
- pipeline = calloc(1, sizeof(struct pipeline));
- if (pipeline == NULL) {
- rte_pipeline_free(p);
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(pipeline->name, name, sizeof(pipeline->name));
- pipeline->p = p;
- pipeline->n_ports_in = 0;
- pipeline->n_ports_out = 0;
- pipeline->n_tables = 0;
- pipeline->msgq_req = msgq_req;
- pipeline->msgq_rsp = msgq_rsp;
- pipeline->timer_period_ms = params->timer_period_ms;
- pipeline->enabled = 0;
- pipeline->cpu_id = params->cpu_id;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&pipeline_list, pipeline, node);
-
- return pipeline;
-}
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled)
-{
- struct rte_pipeline_port_in_params p;
-
- union {
- struct rte_port_ethdev_reader_params ethdev;
- struct rte_port_ring_reader_params ring;
- struct rte_port_sched_reader_params sched;
- struct rte_port_fd_reader_params fd;
- struct rte_port_source_params source;
- struct rte_port_sym_crypto_reader_params sym_crypto;
- } pp;
-
- struct pipeline *pipeline;
- struct port_in *port_in;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *action;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = port_in_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- switch (params->type) {
- case PORT_IN_RXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->rxq.queue_id >= link->n_rxq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->rxq.queue_id;
-
- p.ops = &rte_port_ethdev_reader_ops;
- p.arg_create = &pp.ethdev;
- break;
- }
-
- case PORT_IN_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
-
- p.ops = &rte_port_ring_reader_ops;
- p.arg_create = &pp.ring;
- break;
- }
-
- case PORT_IN_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
-
- p.ops = &rte_port_sched_reader_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_IN_TAP:
- {
- struct tap *tap;
- struct mempool *mempool;
-
- tap = tap_find(params->dev_name);
- mempool = mempool_find(params->tap.mempool_name);
- if ((tap == NULL) || (mempool == NULL))
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.mempool = mempool->m;
- pp.fd.mtu = params->tap.mtu;
-
- p.ops = &rte_port_fd_reader_ops;
- p.arg_create = &pp.fd;
- break;
- }
-
-
- case PORT_IN_SOURCE:
- {
- struct mempool *mempool;
-
- mempool = mempool_find(params->source.mempool_name);
- if (mempool == NULL)
- return -1;
-
- pp.source.mempool = mempool->m;
- pp.source.file_name = params->source.file_name;
- pp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;
-
- p.ops = &rte_port_source_ops;
- p.arg_create = &pp.source;
- break;
- }
-
- case PORT_IN_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->rxq.queue_id > cryptodev->n_queues - 1)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.f_callback = params->cryptodev.f_callback;
- pp.sym_crypto.arg_callback = params->cryptodev.arg_callback;
- p.ops = &rte_port_sym_crypto_reader_ops;
- p.arg_create = &pp.sym_crypto;
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.burst_size = params->burst_size;
-
- /* Resource create */
- action = NULL;
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_port_in_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_port_in_action_params_get(
- action,
- &p);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
- }
-
- status = rte_pipeline_port_in_create(pipeline->p,
- &p,
- &port_id);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
-
- if (enabled)
- rte_pipeline_port_in_enable(pipeline->p, port_id);
-
- /* Pipeline */
- port_in = &pipeline->port_in[pipeline->n_ports_in];
- memcpy(&port_in->params, params, sizeof(*params));
- port_in->ap = ap;
- port_in->a = action;
- pipeline->n_ports_in++;
-
- return 0;
-}
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct pipeline *pipeline;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (port_id >= pipeline->n_ports_in) ||
- (table_id >= pipeline->n_tables))
- return -1;
-
- /* Resource */
- status = rte_pipeline_port_in_connect_to_table(pipeline->p,
- port_id,
- table_id);
-
- return status;
-
-}
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params)
-{
- struct rte_pipeline_port_out_params p;
-
- union {
- struct rte_port_ethdev_writer_params ethdev;
- struct rte_port_ring_writer_params ring;
- struct rte_port_sched_writer_params sched;
- struct rte_port_fd_writer_params fd;
- struct rte_port_sink_params sink;
- struct rte_port_sym_crypto_writer_params sym_crypto;
- } pp;
-
- union {
- struct rte_port_ethdev_writer_nodrop_params ethdev;
- struct rte_port_ring_writer_nodrop_params ring;
- struct rte_port_fd_writer_nodrop_params fd;
- struct rte_port_sym_crypto_writer_nodrop_params sym_crypto;
- } pp_nodrop;
-
- struct pipeline *pipeline;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
- memset(&pp_nodrop, 0, sizeof(pp_nodrop));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- switch (params->type) {
- case PORT_OUT_TXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->txq.queue_id >= link->n_txq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->txq.queue_id;
- pp.ethdev.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ethdev.port_id = link->port_id;
- pp_nodrop.ethdev.queue_id = params->txq.queue_id;
- pp_nodrop.ethdev.tx_burst_sz = params->burst_size;
- pp_nodrop.ethdev.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ethdev_writer_ops;
- p.arg_create = &pp.ethdev;
- } else {
- p.ops = &rte_port_ethdev_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ethdev;
- }
- break;
- }
-
- case PORT_OUT_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
- pp.ring.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ring.ring = swq->r;
- pp_nodrop.ring.tx_burst_sz = params->burst_size;
- pp_nodrop.ring.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ring_writer_ops;
- p.arg_create = &pp.ring;
- } else {
- p.ops = &rte_port_ring_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ring;
- }
- break;
- }
-
- case PORT_OUT_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
- pp.sched.tx_burst_sz = params->burst_size;
-
- p.ops = &rte_port_sched_writer_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_OUT_TAP:
- {
- struct tap *tap;
-
- tap = tap_find(params->dev_name);
- if (tap == NULL)
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.tx_burst_sz = params->burst_size;
-
- pp_nodrop.fd.fd = tap->fd;
- pp_nodrop.fd.tx_burst_sz = params->burst_size;
- pp_nodrop.fd.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_fd_writer_ops;
- p.arg_create = &pp.fd;
- } else {
- p.ops = &rte_port_fd_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.fd;
- }
- break;
- }
-
-
- case PORT_OUT_SINK:
- {
- pp.sink.file_name = params->sink.file_name;
- pp.sink.max_n_pkts = params->sink.max_n_pkts;
-
- p.ops = &rte_port_sink_ops;
- p.arg_create = &pp.sink;
- break;
- }
-
- case PORT_OUT_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->cryptodev.queue_id >= cryptodev->n_queues)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.tx_burst_sz = params->burst_size;
- pp.sym_crypto.crypto_op_offset = params->cryptodev.op_offset;
-
- pp_nodrop.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp_nodrop.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp_nodrop.sym_crypto.tx_burst_sz = params->burst_size;
- pp_nodrop.sym_crypto.n_retries = params->retry;
- pp_nodrop.sym_crypto.crypto_op_offset =
- params->cryptodev.op_offset;
-
- if (params->retry == 0) {
- p.ops = &rte_port_sym_crypto_writer_ops;
- p.arg_create = &pp.sym_crypto;
- } else {
- p.ops = &rte_port_sym_crypto_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.sym_crypto;
- }
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- /* Resource create */
- status = rte_pipeline_port_out_create(pipeline->p,
- &p,
- &port_id);
-
- if (status)
- return -1;
-
- /* Pipeline */
- pipeline->n_ports_out++;
-
- return 0;
-}
-
-static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
-
- /* Source IP address (IPv4) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv4_hdr, src_addr),
- },
-
- /* Destination IP address (IPv4) */
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv4_hdr, dst_addr),
- },
-
- /* Source Port */
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 3,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 4,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv6_hdr, proto),
- },
-
- /* Source IP address (IPv6) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[0]),
- },
-
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[4]),
- },
-
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 3,
- .input_index = 3,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[8]),
- },
-
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 4,
- .input_index = 4,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[12]),
- },
-
- /* Destination IP address (IPv6) */
- [5] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 5,
- .input_index = 5,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[0]),
- },
-
- [6] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 6,
- .input_index = 6,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[4]),
- },
-
- [7] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 7,
- .input_index = 7,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[8]),
- },
-
- [8] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 8,
- .input_index = 8,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[12]),
- },
-
- /* Source Port */
- [9] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 9,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [10] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 10,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params)
-{
- char name[NAME_MAX];
- struct rte_pipeline_table_params p;
-
- union {
- struct rte_table_acl_params acl;
- struct rte_table_array_params array;
- struct rte_table_hash_params hash;
- struct rte_table_lpm_params lpm;
- struct rte_table_lpm_ipv6_params lpm_ipv6;
- } pp;
-
- struct pipeline *pipeline;
- struct table *table;
- struct table_action_profile *ap;
- struct rte_table_action *action;
- uint32_t table_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX))
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = table_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- snprintf(name, NAME_MAX, "%s_table%u",
- pipeline_name, pipeline->n_tables);
-
- switch (params->match_type) {
- case TABLE_ACL:
- {
- uint32_t ip_header_offset = params->match.acl.ip_header_offset -
- (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
- uint32_t i;
-
- if (params->match.acl.n_rules == 0)
- return -1;
-
- pp.acl.name = name;
- pp.acl.n_rules = params->match.acl.n_rules;
- if (params->match.acl.ip_version) {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv4,
- sizeof(table_acl_field_format_ipv4));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv4);
- } else {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv6,
- sizeof(table_acl_field_format_ipv6));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv6);
- }
-
- for (i = 0; i < pp.acl.n_rule_fields; i++)
- pp.acl.field_format[i].offset += ip_header_offset;
-
- p.ops = &rte_table_acl_ops;
- p.arg_create = &pp.acl;
- break;
- }
-
- case TABLE_ARRAY:
- {
- if (params->match.array.n_keys == 0)
- return -1;
-
- pp.array.n_entries = params->match.array.n_keys;
- pp.array.offset = params->match.array.key_offset;
-
- p.ops = &rte_table_array_ops;
- p.arg_create = &pp.array;
- break;
- }
-
- case TABLE_HASH:
- {
- struct rte_table_ops *ops;
- rte_table_hash_op_hash f_hash;
-
- if (params->match.hash.n_keys == 0)
- return -1;
-
- switch (params->match.hash.key_size) {
- case 8:
- f_hash = rte_table_hash_crc_key8;
- break;
- case 16:
- f_hash = rte_table_hash_crc_key16;
- break;
- case 24:
- f_hash = rte_table_hash_crc_key24;
- break;
- case 32:
- f_hash = rte_table_hash_crc_key32;
- break;
- case 40:
- f_hash = rte_table_hash_crc_key40;
- break;
- case 48:
- f_hash = rte_table_hash_crc_key48;
- break;
- case 56:
- f_hash = rte_table_hash_crc_key56;
- break;
- case 64:
- f_hash = rte_table_hash_crc_key64;
- break;
- default:
- return -1;
- }
-
- pp.hash.name = name;
- pp.hash.key_size = params->match.hash.key_size;
- pp.hash.key_offset = params->match.hash.key_offset;
- pp.hash.key_mask = params->match.hash.key_mask;
- pp.hash.n_keys = params->match.hash.n_keys;
- pp.hash.n_buckets = params->match.hash.n_buckets;
- pp.hash.f_hash = f_hash;
- pp.hash.seed = 0;
-
- if (params->match.hash.extendable_bucket)
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_ext_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_ext_ops;
- break;
- default:
- ops = &rte_table_hash_ext_ops;
- }
- else
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_lru_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_lru_ops;
- break;
- default:
- ops = &rte_table_hash_lru_ops;
- }
-
- p.ops = ops;
- p.arg_create = &pp.hash;
- break;
- }
-
- case TABLE_LPM:
- {
- if (params->match.lpm.n_rules == 0)
- return -1;
-
- switch (params->match.lpm.key_size) {
- case 4:
- {
- pp.lpm.name = name;
- pp.lpm.n_rules = params->match.lpm.n_rules;
- pp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm.flags = 0;
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ops;
- p.arg_create = &pp.lpm;
- break;
- }
-
- case 16:
- {
- pp.lpm_ipv6.name = name;
- pp.lpm_ipv6.n_rules = params->match.lpm.n_rules;
- pp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm_ipv6.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ipv6_ops;
- p.arg_create = &pp.lpm_ipv6;
- break;
- }
-
- default:
- return -1;
- }
-
- break;
- }
-
- case TABLE_STUB:
- {
- p.ops = &rte_table_stub_ops;
- p.arg_create = NULL;
- break;
- }
-
- default:
- return -1;
- }
-
- /* Resource create */
- action = NULL;
- p.f_action_hit = NULL;
- p.f_action_miss = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_table_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_table_action_table_params_get(
- action,
- &p);
- if (status ||
- ((p.action_data_size +
- sizeof(struct rte_pipeline_table_entry)) >
- TABLE_RULE_ACTION_SIZE_MAX)) {
- rte_table_action_free(action);
- return -1;
- }
- }
-
- if (params->match_type == TABLE_LPM) {
- if (params->match.lpm.key_size == 4)
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
-
- if (params->match.lpm.key_size == 16)
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- }
-
- status = rte_pipeline_table_create(pipeline->p,
- &p,
- &table_id);
- if (status) {
- rte_table_action_free(action);
- return -1;
- }
-
- /* Pipeline */
- table = &pipeline->table[pipeline->n_tables];
- memcpy(&table->params, params, sizeof(*params));
- table->ap = ap;
- table->a = action;
- TAILQ_INIT(&table->rules);
- table->rule_default = NULL;
-
- pipeline->n_tables++;
-
- return 0;
-}
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- TAILQ_FOREACH(rule, &table->rules, node)
- if (memcmp(&rule->match, match, sizeof(*match)) == 0)
- return rule;
-
- return NULL;
-}
-
-void
-table_rule_add(struct table *table,
- struct table_rule *new_rule)
-{
- struct table_rule *existing_rule;
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
-}
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules)
-{
- uint32_t i;
-
- for (i = 0; i < n_rules; i++) {
- struct table_rule *existing_rule, *new_rule;
-
- new_rule = TAILQ_FIRST(list);
- if (new_rule == NULL)
- break;
-
- TAILQ_REMOVE(list, new_rule, node);
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
- }
-}
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return;
-
- TAILQ_REMOVE(&table->rules, rule, node);
- free(rule);
-}
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule)
-{
- free(table->rule_default);
- table->rule_default = rule;
-}
-
-void
-table_rule_default_delete(struct table *table)
-{
- free(table->rule_default);
- table->rule_default = NULL;
-}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
deleted file mode 100644
index 89696480fc..0000000000
--- a/examples/ip_pipeline/pipeline.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_PIPELINE_H_
-#define _INCLUDE_PIPELINE_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_pipeline.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-#include "action.h"
-
-struct pipeline_params {
- uint32_t timer_period_ms;
- uint32_t offset_port_id;
- uint32_t cpu_id;
-};
-
-enum port_in_type {
- PORT_IN_RXQ,
- PORT_IN_SWQ,
- PORT_IN_TMGR,
- PORT_IN_TAP,
- PORT_IN_SOURCE,
- PORT_IN_CRYPTODEV,
-};
-
-struct port_in_params {
- /* Read */
- enum port_in_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } rxq;
-
- struct {
- const char *mempool_name;
- uint32_t mtu;
- } tap;
-
- struct {
- const char *mempool_name;
- const char *file_name;
- uint32_t n_bytes_per_pkt;
- } source;
-
- struct {
- uint16_t queue_id;
- void *f_callback;
- void *arg_callback;
- } cryptodev;
- };
- uint32_t burst_size;
-
- /* Action */
- const char *action_profile_name;
-};
-
-enum port_out_type {
- PORT_OUT_TXQ,
- PORT_OUT_SWQ,
- PORT_OUT_TMGR,
- PORT_OUT_TAP,
- PORT_OUT_SINK,
- PORT_OUT_CRYPTODEV,
-};
-
-struct port_out_params {
- enum port_out_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } txq;
-
- struct {
- const char *file_name;
- uint32_t max_n_pkts;
- } sink;
-
- struct {
- uint16_t queue_id;
- uint32_t op_offset;
- } cryptodev;
- };
- uint32_t burst_size;
- int retry;
- uint32_t n_retries;
-};
-
-enum table_type {
- TABLE_ACL,
- TABLE_ARRAY,
- TABLE_HASH,
- TABLE_LPM,
- TABLE_STUB,
-};
-
-struct table_acl_params {
- uint32_t n_rules;
- uint32_t ip_header_offset;
- int ip_version;
-};
-
-struct table_array_params {
- uint32_t n_keys;
- uint32_t key_offset;
-};
-
-struct table_hash_params {
- uint32_t n_keys;
- uint32_t key_offset;
- uint32_t key_size;
- uint8_t *key_mask;
- uint32_t n_buckets;
- int extendable_bucket;
-};
-
-struct table_lpm_params {
- uint32_t n_rules;
- uint32_t key_offset;
- uint32_t key_size;
-};
-
-struct table_params {
- /* Match */
- enum table_type match_type;
- union {
- struct table_acl_params acl;
- struct table_array_params array;
- struct table_hash_params hash;
- struct table_lpm_params lpm;
- } match;
-
- /* Action */
- const char *action_profile_name;
-};
-
-struct table_rule;
-
-TAILQ_HEAD(table_rule_list, table_rule);
-
-struct port_in {
- struct port_in_params params;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *a;
-};
-
-struct table {
- struct table_params params;
- struct table_action_profile *ap;
- struct rte_table_action *a;
- struct table_rule_list rules;
- struct table_rule *rule_default;
-};
-
-struct pipeline {
- TAILQ_ENTRY(pipeline) node;
- char name[NAME_SIZE];
-
- struct rte_pipeline *p;
- struct port_in port_in[RTE_PIPELINE_PORT_IN_MAX];
- struct table table[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
-
- int enabled;
- uint32_t thread_id;
- uint32_t cpu_id;
-};
-
-TAILQ_HEAD(pipeline_list, pipeline);
-
-int
-pipeline_init(void);
-
-struct pipeline *
-pipeline_find(const char *name);
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params);
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled);
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id);
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params);
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params);
-
-struct table_rule_match_acl {
- int ip_version;
-
- union {
- struct {
- uint32_t sa;
- uint32_t da;
- } ipv4;
-
- struct {
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- } ipv6;
- };
-
- uint32_t sa_depth;
- uint32_t da_depth;
- uint16_t sp0;
- uint16_t sp1;
- uint16_t dp0;
- uint16_t dp1;
- uint8_t proto;
- uint8_t proto_mask;
- uint32_t priority;
-};
-
-struct table_rule_match_array {
- uint32_t pos;
-};
-
-#ifndef TABLE_RULE_MATCH_SIZE_MAX
-#define TABLE_RULE_MATCH_SIZE_MAX 256
-#endif
-
-#ifndef TABLE_RULE_ACTION_SIZE_MAX
-#define TABLE_RULE_ACTION_SIZE_MAX 2048
-#endif
-
-struct table_rule_match_hash {
- uint8_t key[TABLE_RULE_MATCH_SIZE_MAX];
-};
-
-struct table_rule_match_lpm {
- int ip_version;
-
- union {
- uint32_t ipv4;
- struct rte_ipv6_addr ipv6;
- };
-
- uint8_t depth;
-};
-
-struct table_rule_match {
- enum table_type match_type;
-
- union {
- struct table_rule_match_acl acl;
- struct table_rule_match_array array;
- struct table_rule_match_hash hash;
- struct table_rule_match_lpm lpm;
- } match;
-};
-
-#ifndef SYM_CRYPTO_MAX_KEY_SIZE
-#define SYM_CRYPTO_MAX_KEY_SIZE (256)
-#endif
-
-struct table_rule_action {
- uint64_t action_mask;
- struct rte_table_action_fwd_params fwd;
- struct rte_table_action_lb_params lb;
- struct rte_table_action_mtr_params mtr;
- struct rte_table_action_tm_params tm;
- struct rte_table_action_encap_params encap;
- struct rte_table_action_nat_params nat;
- struct rte_table_action_ttl_params ttl;
- struct rte_table_action_stats_params stats;
- struct rte_table_action_time_params time;
- struct rte_table_action_sym_crypto_params sym_crypto;
- uint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];
- struct rte_table_action_tag_params tag;
- struct rte_table_action_decap_params decap;
-
-};
-
-struct table_rule {
- TAILQ_ENTRY(table_rule) node;
- struct table_rule_match match;
- struct table_rule_action action;
- void *data;
-};
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear);
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear);
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear);
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added);
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match);
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id);
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id);
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table);
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp);
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules);
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_default_delete(struct table *table);
-
-#endif /* _INCLUDE_PIPELINE_H_ */
diff --git a/examples/ip_pipeline/swq.c b/examples/ip_pipeline/swq.c
deleted file mode 100644
index 7e54a1dbfe..0000000000
--- a/examples/ip_pipeline/swq.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-
-#include "swq.h"
-
-static struct swq_list swq_list;
-
-int
-swq_init(void)
-{
- TAILQ_INIT(&swq_list);
-
- return 0;
-}
-
-struct swq *
-swq_find(const char *name)
-{
- struct swq *swq;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(swq, &swq_list, node)
- if (strcmp(swq->name, name) == 0)
- return swq;
-
- return NULL;
-}
-
-struct swq *
-swq_create(const char *name, struct swq_params *params)
-{
- struct swq *swq;
- struct rte_ring *r;
- unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ;
-
- /* Check input params */
- if ((name == NULL) ||
- swq_find(name) ||
- (params == NULL) ||
- (params->size == 0))
- return NULL;
-
- /* Resource create */
- r = rte_ring_create(
- name,
- params->size,
- params->cpu_id,
- flags);
-
- if (r == NULL)
- return NULL;
-
- /* Node allocation */
- swq = calloc(1, sizeof(struct swq));
- if (swq == NULL) {
- rte_ring_free(r);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(swq->name, name, sizeof(swq->name));
- swq->r = r;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&swq_list, swq, node);
-
- return swq;
-}
diff --git a/examples/ip_pipeline/swq.h b/examples/ip_pipeline/swq.h
deleted file mode 100644
index c8440ee3cd..0000000000
--- a/examples/ip_pipeline/swq.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SWQ_H_
-#define _INCLUDE_SWQ_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_ring.h>
-
-#include "common.h"
-
-struct swq {
- TAILQ_ENTRY(swq) node;
- char name[NAME_SIZE];
- struct rte_ring *r;
-};
-
-TAILQ_HEAD(swq_list, swq);
-
-int
-swq_init(void);
-
-struct swq *
-swq_find(const char *name);
-
-struct swq_params {
- uint32_t size;
- uint32_t cpu_id;
-};
-
-struct swq *
-swq_create(const char *name, struct swq_params *params);
-
-#endif /* _INCLUDE_SWQ_H_ */
diff --git a/examples/ip_pipeline/tap.c b/examples/ip_pipeline/tap.c
deleted file mode 100644
index adae640c1e..0000000000
--- a/examples/ip_pipeline/tap.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <netinet/in.h>
-#ifdef RTE_EXEC_ENV_LINUX
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <rte_string_fns.h>
-
-#include "tap.h"
-
-#define TAP_DEV "/dev/net/tun"
-
-static struct tap_list tap_list;
-
-int
-tap_init(void)
-{
- TAILQ_INIT(&tap_list);
-
- return 0;
-}
-
-struct tap *
-tap_find(const char *name)
-{
- struct tap *tap;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tap, &tap_list, node)
- if (strcmp(tap->name, name) == 0)
- return tap;
-
- return NULL;
-}
-
-#ifndef RTE_EXEC_ENV_LINUX
-
-struct tap *
-tap_create(const char *name __rte_unused)
-{
- return NULL;
-}
-
-#else
-
-struct tap *
-tap_create(const char *name)
-{
- struct tap *tap;
- struct ifreq ifr;
- int fd, status;
-
- /* Check input params */
- if ((name == NULL) ||
- tap_find(name))
- return NULL;
-
- /* Resource create */
- fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
- if (fd < 0)
- return NULL;
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
- strlcpy(ifr.ifr_name, name, IFNAMSIZ);
-
- status = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (status < 0) {
- close(fd);
- return NULL;
- }
-
- /* Node allocation */
- tap = calloc(1, sizeof(struct tap));
- if (tap == NULL) {
- close(fd);
- return NULL;
- }
- /* Node fill in */
- strlcpy(tap->name, name, sizeof(tap->name));
- tap->fd = fd;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tap_list, tap, node);
-
- return tap;
-}
-
-#endif
diff --git a/examples/ip_pipeline/tap.h b/examples/ip_pipeline/tap.h
deleted file mode 100644
index 0dce72fe3c..0000000000
--- a/examples/ip_pipeline/tap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TAP_H_
-#define _INCLUDE_TAP_H_
-
-#include <sys/queue.h>
-
-#include "common.h"
-
-struct tap {
- TAILQ_ENTRY(tap) node;
- char name[NAME_SIZE];
- int fd;
-};
-
-TAILQ_HEAD(tap_list, tap);
-
-int
-tap_init(void);
-
-struct tap *
-tap_find(const char *name);
-
-struct tap *
-tap_create(const char *name);
-
-#endif /* _INCLUDE_TAP_H_ */
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
deleted file mode 100644
index 0a44bddd90..0000000000
--- a/examples/ip_pipeline/thread.c
+++ /dev/null
@@ -1,3137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_lcore.h>
-#include <rte_ring.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-
-#include "common.h"
-#include "thread.h"
-#include "pipeline.h"
-
-#ifndef THREAD_PIPELINES_MAX
-#define THREAD_PIPELINES_MAX 256
-#endif
-
-#ifndef THREAD_MSGQ_SIZE
-#define THREAD_MSGQ_SIZE 64
-#endif
-
-#ifndef THREAD_TIMER_PERIOD_MS
-#define THREAD_TIMER_PERIOD_MS 100
-#endif
-
-/**
- * Main thread: data plane thread context
- */
-struct thread {
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- uint32_t enabled;
-};
-
-static struct thread thread[RTE_MAX_LCORE];
-
-/**
- * Data plane threads: context
- */
-struct table_data {
- struct rte_table_action *a;
-};
-
-struct pipeline_data {
- struct rte_pipeline *p;
- struct table_data table_data[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
-
- uint8_t buffer[TABLE_RULE_ACTION_SIZE_MAX];
-};
-
-struct __rte_cache_aligned thread_data {
- struct rte_pipeline *p[THREAD_PIPELINES_MAX];
- uint32_t n_pipelines;
-
- struct pipeline_data pipeline_data[THREAD_PIPELINES_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
- uint64_t time_next_min;
-};
-
-static struct thread_data thread_data[RTE_MAX_LCORE];
-
-/**
- * Main thread: data plane thread init
- */
-static void
-thread_free(void)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- struct thread *t = &thread[i];
-
- if (!rte_lcore_is_enabled(i))
- continue;
-
- /* MSGQs */
- rte_ring_free(t->msgq_req);
-
- rte_ring_free(t->msgq_rsp);
- }
-}
-
-int
-thread_init(void)
-{
- uint32_t i;
-
- RTE_LCORE_FOREACH_WORKER(i) {
- char name[NAME_MAX];
- struct rte_ring *msgq_req, *msgq_rsp;
- struct thread *t = &thread[i];
- struct thread_data *t_data = &thread_data[i];
- uint32_t cpu_id = rte_lcore_to_socket_id(i);
-
- /* MSGQs */
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-REQ", i);
-
- msgq_req = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_req == NULL) {
- thread_free();
- return -1;
- }
-
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-RSP", i);
-
- msgq_rsp = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_rsp == NULL) {
- thread_free();
- return -1;
- }
-
- /* Main thread records */
- t->msgq_req = msgq_req;
- t->msgq_rsp = msgq_rsp;
- t->enabled = 1;
-
- /* Data plane thread records */
- t_data->n_pipelines = 0;
- t_data->msgq_req = msgq_req;
- t_data->msgq_rsp = msgq_rsp;
- t_data->timer_period =
- (rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;
- t_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;
- t_data->time_next_min = t_data->time_next;
- }
-
- return 0;
-}
-
-static inline int
-thread_is_running(uint32_t thread_id)
-{
- enum rte_lcore_state_t thread_state;
-
- thread_state = rte_eal_get_lcore_state(thread_id);
- return (thread_state == RUNNING) ? 1 : 0;
-}
-
-/**
- * Pipeline is running when:
- * (A) Pipeline is mapped to a data plane thread AND
- * (B) Its data plane thread is in RUNNING state.
- */
-static inline int
-pipeline_is_running(struct pipeline *p)
-{
- if (p->enabled == 0)
- return 0;
-
- return thread_is_running(p->thread_id);
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum thread_req_type {
- THREAD_REQ_PIPELINE_ENABLE = 0,
- THREAD_REQ_PIPELINE_DISABLE,
- THREAD_REQ_MAX
-};
-
-struct thread_msg_req {
- enum thread_req_type type;
-
- union {
- struct {
- struct rte_pipeline *p;
- struct {
- struct rte_table_action *a;
- } table[RTE_PIPELINE_TABLE_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
- uint32_t n_tables;
- } pipeline_enable;
-
- struct {
- struct rte_pipeline *p;
- } pipeline_disable;
- };
-};
-
-struct thread_msg_rsp {
- int status;
-};
-
-/**
- * Main thread
- */
-static struct thread_msg_req *
-thread_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct thread_msg_req),
- sizeof(struct thread_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-thread_msg_free(struct thread_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct thread_msg_rsp *
-thread_msg_send_recv(uint32_t thread_id,
- struct thread_msg_req *req)
-{
- struct thread *t = &thread[thread_id];
- struct rte_ring *msgq_req = t->msgq_req;
- struct rte_ring *msgq_rsp = t->msgq_rsp;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- uint32_t i;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL) ||
- (p->n_ports_in == 0) ||
- (p->n_ports_out == 0) ||
- (p->n_tables == 0))
- return -1;
-
- t = &thread[thread_id];
- if ((t->enabled == 0) ||
- p->enabled)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- struct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];
-
- if (td->n_pipelines >= THREAD_PIPELINES_MAX)
- return -1;
-
- /* Data plane thread */
- td->p[td->n_pipelines] = p->p;
-
- tdp->p = p->p;
- for (i = 0; i < p->n_tables; i++)
- tdp->table_data[i].a = p->table[i].a;
-
- tdp->n_tables = p->n_tables;
-
- tdp->msgq_req = p->msgq_req;
- tdp->msgq_rsp = p->msgq_rsp;
- tdp->timer_period = (rte_get_tsc_hz() * p->timer_period_ms) / 1000;
- tdp->time_next = rte_get_tsc_cycles() + tdp->timer_period;
-
- td->n_pipelines++;
-
- /* Pipeline */
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_ENABLE;
- req->pipeline_enable.p = p->p;
- for (i = 0; i < p->n_tables; i++)
- req->pipeline_enable.table[i].a =
- p->table[i].a;
- req->pipeline_enable.msgq_req = p->msgq_req;
- req->pipeline_enable.msgq_rsp = p->msgq_rsp;
- req->pipeline_enable.timer_period_ms = p->timer_period_ms;
- req->pipeline_enable.n_tables = p->n_tables;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
-}
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL))
- return -1;
-
- t = &thread[thread_id];
- if (t->enabled == 0)
- return -1;
-
- if (p->enabled == 0)
- return 0;
-
- if (p->thread_id != thread_id)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- uint32_t i;
-
- for (i = 0; i < td->n_pipelines; i++) {
- struct pipeline_data *tdp = &td->pipeline_data[i];
-
- if (tdp->p != p->p)
- continue;
-
- /* Data plane thread */
- if (i < td->n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- td->p[td->n_pipelines - 1];
- struct pipeline_data *tdp_last =
- &td->pipeline_data[td->n_pipelines - 1];
-
- td->p[i] = pipeline_last;
- memcpy(tdp, tdp_last, sizeof(*tdp));
- }
-
- td->n_pipelines--;
-
- /* Pipeline */
- p->enabled = 0;
-
- break;
- }
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_DISABLE;
- req->pipeline_disable.p = p->p;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->enabled = 0;
-
- return 0;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct thread_msg_req *
-thread_msg_recv(struct rte_ring *msgq_req)
-{
- struct thread_msg_req *req = NULL;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-thread_msg_send(struct rte_ring *msgq_rsp,
- struct thread_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_enable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- struct pipeline_data *p = &t->pipeline_data[t->n_pipelines];
- uint32_t i;
-
- /* Request */
- if (t->n_pipelines >= THREAD_PIPELINES_MAX) {
- rsp->status = -1;
- return rsp;
- }
-
- t->p[t->n_pipelines] = req->pipeline_enable.p;
-
- p->p = req->pipeline_enable.p;
- for (i = 0; i < req->pipeline_enable.n_tables; i++)
- p->table_data[i].a =
- req->pipeline_enable.table[i].a;
-
- p->n_tables = req->pipeline_enable.n_tables;
-
- p->msgq_req = req->pipeline_enable.msgq_req;
- p->msgq_rsp = req->pipeline_enable.msgq_rsp;
- p->timer_period =
- (rte_get_tsc_hz() * req->pipeline_enable.timer_period_ms) / 1000;
- p->time_next = rte_get_tsc_cycles() + p->timer_period;
-
- t->n_pipelines++;
-
- /* Response */
- rsp->status = 0;
- return rsp;
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_disable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- uint32_t n_pipelines = t->n_pipelines;
- struct rte_pipeline *pipeline = req->pipeline_disable.p;
- uint32_t i;
-
- /* find pipeline */
- for (i = 0; i < n_pipelines; i++) {
- struct pipeline_data *p = &t->pipeline_data[i];
-
- if (p->p != pipeline)
- continue;
-
- if (i < n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- t->p[n_pipelines - 1];
- struct pipeline_data *p_last =
- &t->pipeline_data[n_pipelines - 1];
-
- t->p[i] = pipeline_last;
- memcpy(p, p_last, sizeof(*p));
- }
-
- t->n_pipelines--;
-
- rsp->status = 0;
- return rsp;
- }
-
- /* should not get here */
- rsp->status = 0;
- return rsp;
-}
-
-static void
-thread_msg_handle(struct thread_data *t)
-{
- for ( ; ; ) {
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
-
- req = thread_msg_recv(t->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case THREAD_REQ_PIPELINE_ENABLE:
- rsp = thread_msg_handle_pipeline_enable(t, req);
- break;
-
- case THREAD_REQ_PIPELINE_DISABLE:
- rsp = thread_msg_handle_pipeline_disable(t, req);
- break;
-
- default:
- rsp = (struct thread_msg_rsp *) req;
- rsp->status = -1;
- }
-
- thread_msg_send(t->msgq_rsp, rsp);
- }
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum pipeline_req_type {
- /* Port IN */
- PIPELINE_REQ_PORT_IN_STATS_READ,
- PIPELINE_REQ_PORT_IN_ENABLE,
- PIPELINE_REQ_PORT_IN_DISABLE,
-
- /* Port OUT */
- PIPELINE_REQ_PORT_OUT_STATS_READ,
-
- /* Table */
- PIPELINE_REQ_TABLE_STATS_READ,
- PIPELINE_REQ_TABLE_RULE_ADD,
- PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_ADD_BULK,
- PIPELINE_REQ_TABLE_RULE_DELETE,
- PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_STATS_READ,
- PIPELINE_REQ_TABLE_MTR_PROFILE_ADD,
- PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE,
- PIPELINE_REQ_TABLE_RULE_MTR_READ,
- PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,
- PIPELINE_REQ_TABLE_RULE_TTL_READ,
- PIPELINE_REQ_TABLE_RULE_TIME_READ,
- PIPELINE_REQ_MAX
-};
-
-struct pipeline_msg_req_port_in_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_port_out_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_add {
- struct table_rule_match match;
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_default {
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_bulk {
- struct table_rule_list *list;
- int bulk;
-};
-
-struct pipeline_msg_req_table_rule_delete {
- struct table_rule_match match;
-};
-
-struct pipeline_msg_req_table_rule_stats_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_mtr_profile_add {
- uint32_t meter_profile_id;
- struct rte_table_action_meter_profile profile;
-};
-
-struct pipeline_msg_req_table_mtr_profile_delete {
- uint32_t meter_profile_id;
-};
-
-struct pipeline_msg_req_table_rule_mtr_read {
- void *data;
- uint32_t tc_mask;
- int clear;
-};
-
-struct pipeline_msg_req_table_dscp_table_update {
- uint64_t dscp_mask;
- struct rte_table_action_dscp_table dscp_table;
-};
-
-struct pipeline_msg_req_table_rule_ttl_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_time_read {
- void *data;
-};
-
-struct pipeline_msg_req {
- enum pipeline_req_type type;
- uint32_t id; /* Port IN, port OUT or table ID */
-
- union {
- struct pipeline_msg_req_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_req_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_req_table_stats_read table_stats_read;
- struct pipeline_msg_req_table_rule_add table_rule_add;
- struct pipeline_msg_req_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_req_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_req_table_rule_delete table_rule_delete;
- struct pipeline_msg_req_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_req_table_mtr_profile_add table_mtr_profile_add;
- struct pipeline_msg_req_table_mtr_profile_delete table_mtr_profile_delete;
- struct pipeline_msg_req_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_req_table_dscp_table_update table_dscp_table_update;
- struct pipeline_msg_req_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_req_table_rule_time_read table_rule_time_read;
- };
-};
-
-struct pipeline_msg_rsp_port_in_stats_read {
- struct rte_pipeline_port_in_stats stats;
-};
-
-struct pipeline_msg_rsp_port_out_stats_read {
- struct rte_pipeline_port_out_stats stats;
-};
-
-struct pipeline_msg_rsp_table_stats_read {
- struct rte_pipeline_table_stats stats;
-};
-
-struct pipeline_msg_rsp_table_rule_add {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_default {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_bulk {
- uint32_t n_rules;
-};
-
-struct pipeline_msg_rsp_table_rule_stats_read {
- struct rte_table_action_stats_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_mtr_read {
- struct rte_table_action_mtr_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_ttl_read {
- struct rte_table_action_ttl_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_time_read {
- uint64_t timestamp;
-};
-
-struct pipeline_msg_rsp {
- int status;
-
- union {
- struct pipeline_msg_rsp_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_rsp_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_rsp_table_stats_read table_stats_read;
- struct pipeline_msg_rsp_table_rule_add table_rule_add;
- struct pipeline_msg_rsp_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_rsp_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_rsp_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_rsp_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_rsp_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_rsp_table_rule_time_read table_rule_time_read;
- };
-};
-
-/**
- * Main thread
- */
-static struct pipeline_msg_req *
-pipeline_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct pipeline_msg_req),
- sizeof(struct pipeline_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-pipeline_msg_free(struct pipeline_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_send_recv(struct pipeline *p,
- struct pipeline_msg_req *req)
-{
- struct rte_ring *msgq_req = p->msgq_req;
- struct rte_ring *msgq_rsp = p->msgq_rsp;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_STATS_READ;
- req->id = port_id;
- req->port_in_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_enable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_ENABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_disable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_DISABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_out))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_OUT_STATS_READ;
- req->id = port_id;
- req->port_out_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_stats_read(p->p,
- table_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_STATS_READ;
- req->id = table_id;
- req->table_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static int
-match_check(struct table_rule_match *match,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table *table;
-
- if ((match == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
- if (match->match_type != table->params.match_type)
- return -1;
-
- switch (match->match_type) {
- case TABLE_ACL:
- {
- struct table_acl_params *t = &table->params.match.acl;
- struct table_rule_match_acl *r = &match->match.acl;
-
- if ((r->ip_version && (t->ip_version == 0)) ||
- ((r->ip_version == 0) && t->ip_version))
- return -1;
-
- if (r->ip_version) {
- if ((r->sa_depth > 32) ||
- (r->da_depth > 32))
- return -1;
- } else {
- if ((r->sa_depth > 128) ||
- (r->da_depth > 128))
- return -1;
- }
- return 0;
- }
-
- case TABLE_ARRAY:
- return 0;
-
- case TABLE_HASH:
- return 0;
-
- case TABLE_LPM:
- {
- struct table_lpm_params *t = &table->params.match.lpm;
- struct table_rule_match_lpm *r = &match->match.lpm;
-
- if ((r->ip_version && (t->key_size != 4)) ||
- ((r->ip_version == 0) && (t->key_size != 16)))
- return -1;
-
- if (r->ip_version) {
- if (r->depth > 32)
- return -1;
- } else {
- if (r->depth > 128)
- return -1;
- }
- return 0;
- }
-
- case TABLE_STUB:
- return -1;
-
- default:
- return -1;
- }
-}
-
-static int
-action_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table_action_profile *ap;
-
- if ((action == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- ap = p->table[table_id].ap;
- if (action->action_mask != ap->params.action_mask)
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- uint32_t tc_mask0 = (1 << ap->params.mtr.n_tc) - 1;
- uint32_t tc_mask1 = action->mtr.tc_mask;
-
- if (tc_mask1 != tc_mask0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- uint32_t n_subports_per_port =
- ap->params.tm.n_subports_per_port;
- uint32_t n_pipes_per_subport =
- ap->params.tm.n_pipes_per_subport;
- uint32_t subport_id = action->tm.subport_id;
- uint32_t pipe_id = action->tm.pipe_id;
-
- if ((subport_id >= n_subports_per_port) ||
- (pipe_id >= n_pipes_per_subport))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- uint64_t encap_mask = ap->params.encap.encap_mask;
- enum rte_table_action_encap_type type = action->encap.type;
-
- if ((encap_mask & (1LLU << type)) == 0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- int ip_version0 = ap->params.common.ip_version;
- int ip_version1 = action->nat.ip_version;
-
- if ((ip_version1 && (ip_version0 == 0)) ||
- ((ip_version1 == 0) && ip_version0))
- return -1;
- }
-
- return 0;
-}
-
-static int
-action_default_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- if ((action == NULL) ||
- (action->action_mask != (1LLU << RTE_TABLE_ACTION_FWD)) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- return 0;
-}
-
-union table_rule_match_low_level {
- struct rte_table_acl_rule_add_params acl_add;
- struct rte_table_acl_rule_delete_params acl_delete;
- struct rte_table_array_key array;
- uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
- struct rte_table_lpm_key lpm_ipv4;
- struct rte_table_lpm_ipv6_key lpm_ipv6;
-};
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add);
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data);
-
-struct table_ll {
- struct rte_pipeline *p;
- int table_id;
- struct rte_table_action *a;
- int bulk_supported;
-};
-
-static int
-table_rule_add_bulk_ll(struct table_ll *table,
- struct table_rule_list *list,
- uint32_t *n_rules)
-{
- union table_rule_match_low_level *match_ll = NULL;
- uint8_t *action_ll = NULL;
- void **match_ll_ptr = NULL;
- struct rte_pipeline_table_entry **action_ll_ptr = NULL;
- struct rte_pipeline_table_entry **entries_ptr = NULL;
- int *found = NULL;
- struct table_rule *rule;
- uint32_t n, i;
- int status = 0;
-
- n = 0;
- TAILQ_FOREACH(rule, list, node)
- n++;
-
- /* Memory allocation */
- match_ll = calloc(n, sizeof(union table_rule_match_low_level));
- action_ll = calloc(n, TABLE_RULE_ACTION_SIZE_MAX);
-
- match_ll_ptr = calloc(n, sizeof(void *));
- action_ll_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
-
- entries_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
- found = calloc(n, sizeof(int));
-
- if (match_ll == NULL ||
- action_ll == NULL ||
- match_ll_ptr == NULL ||
- action_ll_ptr == NULL ||
- entries_ptr == NULL ||
- found == NULL) {
- status = -ENOMEM;
- goto table_rule_add_bulk_ll_free;
- }
-
- /* Init */
- for (i = 0; i < n; i++) {
- match_ll_ptr[i] = (void *)&match_ll[i];
- action_ll_ptr[i] = (struct rte_pipeline_table_entry *)
- &action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
- }
-
- /* Rule (match, action) conversion */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- status = match_convert(&rule->match, match_ll_ptr[i], 1);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- status = action_convert(table->a, &rule->action, action_ll_ptr[i]);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- i++;
- }
-
- /* Add rule (match, action) to table */
- if (table->bulk_supported) {
- status = rte_pipeline_table_entry_add_bulk(table->p,
- table->table_id,
- match_ll_ptr,
- action_ll_ptr,
- n,
- found,
- entries_ptr);
- if (status)
- goto table_rule_add_bulk_ll_free;
- } else
- for (i = 0; i < n; i++) {
- status = rte_pipeline_table_entry_add(table->p,
- table->table_id,
- match_ll_ptr[i],
- action_ll_ptr[i],
- &found[i],
- &entries_ptr[i]);
- if (status) {
- if (i == 0)
- goto table_rule_add_bulk_ll_free;
-
- /* No roll-back. */
- status = 0;
- n = i;
- break;
- }
- }
-
- /* Write back to the rule list. */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- if (i >= n)
- break;
-
- rule->data = entries_ptr[i];
-
- i++;
- }
-
- *n_rules = n;
-
- /* Free */
-table_rule_add_bulk_ll_free:
- free(found);
- free(entries_ptr);
- free(action_ll_ptr);
- free(match_ll_ptr);
- free(action_ll);
- free(match_ll);
-
- return status;
-}
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id) ||
- action_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->match, match, sizeof(*match));
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- struct rte_pipeline_table_entry *data_in, *data_out;
- int key_found;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Table match-action rule conversion */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- status = action_convert(table->a, action, data_in);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Add rule (match, action) to table */
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD;
- req->id = table_id;
- memcpy(&req->table_rule_add.match, match, sizeof(*match));
- memcpy(&req->table_rule_add.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add.data;
- table_rule_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- action_default_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Apply actions */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_default_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT;
- req->id = table_id;
- memcpy(&req->table_rule_add_default.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add_default.data;
- table_rule_default_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static uint32_t
-table_rule_list_free(struct table_rule_list *list)
-{
- uint32_t n = 0;
-
- if (!list)
- return 0;
-
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- n++;
- }
-
- free(list);
- return n;
-}
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status = 0;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (list == NULL) ||
- TAILQ_EMPTY(list) ||
- (n_rules_added == NULL) ||
- (n_rules_not_added == NULL)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- table = &p->table[table_id];
-
- TAILQ_FOREACH(rule, list, node)
- if (match_check(&rule->match, p, table_id) ||
- action_check(&rule->action, p, table_id)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- if (!pipeline_is_running(p)) {
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = table->a,
- .bulk_supported = table->params.match_type == TABLE_ACL,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, n_rules_added);
- if (status) {
- table_rule_list_free(list);
- return status;
- }
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- table_rule_list_free(list);
- return -ENOMEM;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;
- req->id = table_id;
- req->table_rule_add_bulk.list = list;
- req->table_rule_add_bulk.bulk = table->params.match_type == TABLE_ACL;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- *n_rules_added = rsp->table_rule_add_bulk.n_rules;
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- } else
- table_rule_list_free(list);
-
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- int key_found;
-
- status = match_convert(match, &match_ll, 0);
- if (status)
- return -1;
-
- status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- if (status == 0)
- table_rule_delete(table, match);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE;
- req->id = table_id;
- memcpy(&req->table_rule_delete.match, match, sizeof(*match));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_delete(table, match);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- if (status == 0)
- table_rule_default_delete(table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT;
- req->id = table_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_default_delete(table);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_stats_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_STATS_READ;
- req->id = table_id;
- req->table_rule_stats_read.data = rule->data;
- req->table_rule_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (profile == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
- req->id = table_id;
- req->table_mtr_profile_add.meter_profile_id = meter_profile_id;
- memcpy(&req->table_mtr_profile_add.profile, profile, sizeof(*profile));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE;
- req->id = table_id;
- req->table_mtr_profile_delete.meter_profile_id = meter_profile_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- uint32_t tc_mask;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- tc_mask = (1 << table->ap->params.mtr.n_tc) - 1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_meter_read(table->a,
- rule->data,
- tc_mask,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_MTR_READ;
- req->id = table_id;
- req->table_rule_mtr_read.data = rule->data;
- req->table_rule_mtr_read.tc_mask = tc_mask;
- req->table_rule_mtr_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_mtr_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (dscp_table == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE;
- req->id = table_id;
- req->table_dscp_table_update.dscp_mask = dscp_mask;
- memcpy(&req->table_dscp_table_update.dscp_table,
- dscp_table, sizeof(*dscp_table));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- if (!table->ap->params.ttl.n_packets_enabled)
- return -1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_ttl_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TTL_READ;
- req->id = table_id;
- req->table_rule_ttl_read.data = rule->data;
- req->table_rule_ttl_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (timestamp == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_time_read(table->a,
- rule->data,
- timestamp);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TIME_READ;
- req->id = table_id;
- req->table_rule_time_read.data = rule->data;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- *timestamp = rsp->table_rule_time_read.timestamp;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct pipeline_msg_req *
-pipeline_msg_recv(struct rte_ring *msgq_req)
-{
- struct pipeline_msg_req *req;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-pipeline_msg_send(struct rte_ring *msgq_rsp,
- struct pipeline_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_in_stats_read.clear;
-
- rsp->status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- &rsp->port_in_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_enable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_enable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_disable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_disable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_out_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_out_stats_read.clear;
-
- rsp->status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- &rsp->port_out_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->table_stats_read.clear;
-
- rsp->status = rte_pipeline_table_stats_read(p->p,
- port_id,
- &rsp->table_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static int
-match_convert_ipv6_depth(uint32_t depth, uint32_t *depth32)
-{
- if (depth > 128)
- return -1;
-
- switch (depth / 32) {
- case 0:
- depth32[0] = depth;
- depth32[1] = 0;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 1:
- depth32[0] = 32;
- depth32[1] = depth - 32;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 2:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = depth - 64;
- depth32[3] = 0;
- return 0;
-
- case 3:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = depth - 96;
- return 0;
-
- case 4:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = 32;
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add)
-{
- memset(ml, 0, sizeof(*ml));
-
- switch (mh->match_type) {
- case TABLE_ACL:
- if (mh->match.acl.ip_version)
- if (add) {
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_add.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_add.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_add.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_add.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_delete.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_delete.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_delete.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_delete.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
- }
- else
- if (add) {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_add.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_add.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_add.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_add.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_add.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_add.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_add.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_add.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_add.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_add.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_add.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_add.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_add.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_add.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_add.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_add.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_delete.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_delete.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_delete.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_delete.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_delete.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_delete.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_delete.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_delete.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_delete.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_delete.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_delete.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_delete.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_delete.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_delete.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_delete.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_delete.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
- }
- return 0;
-
- case TABLE_ARRAY:
- ml->array.pos = mh->match.array.pos;
- return 0;
-
- case TABLE_HASH:
- memcpy(ml->hash, mh->match.hash.key, sizeof(ml->hash));
- return 0;
-
- case TABLE_LPM:
- if (mh->match.lpm.ip_version) {
- ml->lpm_ipv4.ip = mh->match.lpm.ipv4;
- ml->lpm_ipv4.depth = mh->match.lpm.depth;
- } else {
- ml->lpm_ipv6.ip = mh->match.lpm.ipv6;
- ml->lpm_ipv6.depth = mh->match.lpm.depth;
- }
-
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data)
-{
- int status;
-
- /* Apply actions */
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_FWD,
- &action->fwd);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_LB,
- &action->lb);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_MTR,
- &action->mtr);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TM,
- &action->tm);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_ENCAP,
- &action->encap);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_NAT,
- &action->nat);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TTL,
- &action->ttl);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_STATS,
- &action->stats);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TIME,
- &action->time);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- &action->sym_crypto);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TAG,
- &action->tag);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_DECAP,
- &action->decap);
-
- if (status)
- return status;
- }
-
- return 0;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_add.match;
- struct table_rule_action *action = &req->table_rule_add.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int key_found, status;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = action_convert(a, action, data_in);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_action *action = &req->table_rule_add_default.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int status;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_default.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
-
- uint32_t table_id = req->id;
- struct table_rule_list *list = req->table_rule_add_bulk.list;
- uint32_t bulk = req->table_rule_add_bulk.bulk;
-
- uint32_t n_rules_added;
- int status;
-
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = p->table_data[table_id].a,
- .bulk_supported = bulk,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, &n_rules_added);
- if (status) {
- rsp->status = -1;
- rsp->table_rule_add_bulk.n_rules = 0;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_bulk.n_rules = n_rules_added;
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_delete.match;
- uint32_t table_id = req->id;
- int key_found, status;
-
- status = match_convert(match, &match_ll, 0);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_stats_read.data;
- int clear = req->table_rule_stats_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_stats_read(a,
- data,
- &rsp->table_rule_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id = req->table_mtr_profile_add.meter_profile_id;
- struct rte_table_action_meter_profile *profile =
- &req->table_mtr_profile_add.profile;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id =
- req->table_mtr_profile_delete.meter_profile_id;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_mtr_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_mtr_read.data;
- uint32_t tc_mask = req->table_rule_mtr_read.tc_mask;
- int clear = req->table_rule_mtr_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_read(a,
- data,
- tc_mask,
- &rsp->table_rule_mtr_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_dscp_table_update(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint64_t dscp_mask = req->table_dscp_table_update.dscp_mask;
- struct rte_table_action_dscp_table *dscp_table =
- &req->table_dscp_table_update.dscp_table;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_ttl_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_ttl_read.data;
- int clear = req->table_rule_ttl_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_ttl_read(a,
- data,
- &rsp->table_rule_ttl_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_time_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_time_read.data;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_time_read(a,
- data,
- &rsp->table_rule_time_read.timestamp);
-
- return rsp;
-}
-
-static void
-pipeline_msg_handle(struct pipeline_data *p)
-{
- for ( ; ; ) {
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
-
- req = pipeline_msg_recv(p->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case PIPELINE_REQ_PORT_IN_STATS_READ:
- rsp = pipeline_msg_handle_port_in_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_ENABLE:
- rsp = pipeline_msg_handle_port_in_enable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_DISABLE:
- rsp = pipeline_msg_handle_port_in_disable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_OUT_STATS_READ:
- rsp = pipeline_msg_handle_port_out_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_STATS_READ:
- rsp = pipeline_msg_handle_table_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD:
- rsp = pipeline_msg_handle_table_rule_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_add_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_BULK:
- rsp = pipeline_msg_handle_table_rule_add_bulk(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE:
- rsp = pipeline_msg_handle_table_rule_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_delete_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_STATS_READ:
- rsp = pipeline_msg_handle_table_rule_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_ADD:
- rsp = pipeline_msg_handle_table_mtr_profile_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE:
- rsp = pipeline_msg_handle_table_mtr_profile_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_MTR_READ:
- rsp = pipeline_msg_handle_table_rule_mtr_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE:
- rsp = pipeline_msg_handle_table_dscp_table_update(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TTL_READ:
- rsp = pipeline_msg_handle_table_rule_ttl_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TIME_READ:
- rsp = pipeline_msg_handle_table_rule_time_read(p, req);
- break;
-
- default:
- rsp = (struct pipeline_msg_rsp *) req;
- rsp->status = -1;
- }
-
- pipeline_msg_send(p->msgq_rsp, rsp);
- }
-}
-
-/**
- * Data plane threads: main
- */
-int
-thread_main(void *arg __rte_unused)
-{
- struct thread_data *t;
- uint32_t thread_id, i;
-
- thread_id = rte_lcore_id();
- t = &thread_data[thread_id];
-
- /* Dispatch loop */
- for (i = 0; ; i++) {
- uint32_t j;
-
- /* Data Plane */
- for (j = 0; j < t->n_pipelines; j++)
- rte_pipeline_run(t->p[j]);
-
- /* Control Plane */
- if ((i & 0xF) == 0) {
- uint64_t time = rte_get_tsc_cycles();
- uint64_t time_next_min = UINT64_MAX;
-
- if (time < t->time_next_min)
- continue;
-
- /* Pipeline message queues */
- for (j = 0; j < t->n_pipelines; j++) {
- struct pipeline_data *p =
- &t->pipeline_data[j];
- uint64_t time_next = p->time_next;
-
- if (time_next <= time) {
- pipeline_msg_handle(p);
- rte_pipeline_flush(p->p);
- time_next = time + p->timer_period;
- p->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- /* Thread message queues */
- {
- uint64_t time_next = t->time_next;
-
- if (time_next <= time) {
- thread_msg_handle(t);
- time_next = time + t->timer_period;
- t->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- t->time_next_min = time_next_min;
- }
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h
deleted file mode 100644
index facdf004eb..0000000000
--- a/examples/ip_pipeline/thread.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_THREAD_H_
-#define _INCLUDE_THREAD_H_
-
-#include <stdint.h>
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_init(void);
-
-int
-thread_main(void *arg);
-
-#endif /* _INCLUDE_THREAD_H_ */
diff --git a/examples/ip_pipeline/tmgr.c b/examples/ip_pipeline/tmgr.c
deleted file mode 100644
index 2432b56aee..0000000000
--- a/examples/ip_pipeline/tmgr.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_string_fns.h>
-
-#include "tmgr.h"
-
-static struct rte_sched_subport_profile_params
- subport_profile[TMGR_SUBPORT_PROFILE_MAX];
-
-static uint32_t n_subport_profiles;
-
-static struct rte_sched_pipe_params
- pipe_profile[TMGR_PIPE_PROFILE_MAX];
-
-static uint32_t n_pipe_profiles;
-
-static const struct rte_sched_subport_params subport_params_default = {
- .n_pipes_per_subport_enabled = 0, /* filled at runtime */
- .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
- .pipe_profiles = pipe_profile,
- .n_pipe_profiles = 0, /* filled at run time */
- .n_max_pipe_profiles = RTE_DIM(pipe_profile),
- .cman_params = NULL,
-};
-
-static struct tmgr_port_list tmgr_port_list;
-
-int
-tmgr_init(void)
-{
- TAILQ_INIT(&tmgr_port_list);
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_find(const char *name)
-{
- struct tmgr_port *tmgr_port;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tmgr_port, &tmgr_port_list, node)
- if (strcmp(tmgr_port->name, name) == 0)
- return tmgr_port;
-
- return NULL;
-}
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *params)
-{
- /* Check input params */
- if (params == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&subport_profile[n_subport_profiles],
- params,
- sizeof(*params));
-
- n_subport_profiles++;
-
- return 0;
-}
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p)
-{
- /* Check input params */
- if (p == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&pipe_profile[n_pipe_profiles],
- p,
- sizeof(*p));
-
- n_pipe_profiles++;
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params)
-{
- struct rte_sched_subport_params subport_params;
- struct rte_sched_port_params p;
- struct tmgr_port *tmgr_port;
- struct rte_sched_port *s;
- uint32_t i, j;
-
- /* Check input params */
- if ((name == NULL) ||
- tmgr_port_find(name) ||
- (params == NULL) ||
- (params->n_subports_per_port == 0) ||
- (params->n_pipes_per_subport == 0) ||
- (params->cpu_id >= RTE_MAX_NUMA_NODES) ||
- (n_subport_profiles == 0) ||
- (n_pipe_profiles == 0))
- return NULL;
-
- /* Resource create */
- p.name = name;
- p.socket = (int) params->cpu_id;
- p.rate = params->rate;
- p.mtu = params->mtu;
- p.frame_overhead = params->frame_overhead;
- p.n_subports_per_port = params->n_subports_per_port;
- p.n_subport_profiles = n_subport_profiles;
- p.subport_profiles = subport_profile;
- p.n_max_subport_profiles = TMGR_SUBPORT_PROFILE_MAX;
- p.n_pipes_per_subport = params->n_pipes_per_subport;
-
-
- s = rte_sched_port_config(&p);
- if (s == NULL)
- return NULL;
-
- memcpy(&subport_params, &subport_params_default,
- sizeof(subport_params_default));
-
- subport_params.n_pipe_profiles = n_pipe_profiles;
- subport_params.n_pipes_per_subport_enabled =
- params->n_pipes_per_subport;
-
- for (i = 0; i < params->n_subports_per_port; i++) {
- int status;
-
- status = rte_sched_subport_config(
- s,
- i,
- &subport_params,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- for (j = 0; j < params->n_pipes_per_subport; j++) {
-
- status = rte_sched_pipe_config(
- s,
- i,
- j,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
- }
- }
-
- /* Node allocation */
- tmgr_port = calloc(1, sizeof(struct tmgr_port));
- if (tmgr_port == NULL) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(tmgr_port->name, name, sizeof(tmgr_port->name));
- tmgr_port->s = s;
- tmgr_port->n_subports_per_port = params->n_subports_per_port;
- tmgr_port->n_pipes_per_subport = params->n_pipes_per_subport;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tmgr_port_list, tmgr_port, node);
-
- return tmgr_port;
-}
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id)
-{
- struct tmgr_port *port;
- int status;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (subport_profile_id >= n_subport_profiles))
- return -1;
-
- /* Resource config */
- status = rte_sched_subport_config(
- port->s,
- subport_id,
- NULL,
- subport_profile_id);
-
- return status;
-}
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id)
-{
- struct tmgr_port *port;
- uint32_t i;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (pipe_id_first >= port->n_pipes_per_subport) ||
- (pipe_id_last >= port->n_pipes_per_subport) ||
- (pipe_id_first > pipe_id_last) ||
- (pipe_profile_id >= n_pipe_profiles))
- return -1;
-
- /* Resource config */
- for (i = pipe_id_first; i <= pipe_id_last; i++) {
- int status;
-
- status = rte_sched_pipe_config(
- port->s,
- subport_id,
- i,
- (int) pipe_profile_id);
-
- if (status)
- return status;
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/tmgr.h b/examples/ip_pipeline/tmgr.h
deleted file mode 100644
index 1994c55bcc..0000000000
--- a/examples/ip_pipeline/tmgr.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TMGR_H_
-#define _INCLUDE_TMGR_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_sched.h>
-#include <rte_red.h>
-
-#include "common.h"
-
-#ifndef TMGR_PIPE_SUBPORT_MAX
-#define TMGR_PIPE_SUBPORT_MAX 4096
-#endif
-
-#ifndef TMGR_SUBPORT_PROFILE_MAX
-#define TMGR_SUBPORT_PROFILE_MAX 256
-#endif
-
-#ifndef TMGR_PIPE_PROFILE_MAX
-#define TMGR_PIPE_PROFILE_MAX 256
-#endif
-
-struct tmgr_port {
- TAILQ_ENTRY(tmgr_port) node;
- char name[NAME_SIZE];
- struct rte_sched_port *s;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
-};
-
-TAILQ_HEAD(tmgr_port_list, tmgr_port);
-
-int
-tmgr_init(void);
-
-struct tmgr_port *
-tmgr_port_find(const char *name);
-
-struct tmgr_port_params {
- uint64_t rate;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
- uint32_t frame_overhead;
- uint32_t mtu;
- uint32_t cpu_id;
-};
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *sp);
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p);
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params);
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id);
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id);
-
-#endif /* _INCLUDE_TMGR_H_ */
diff --git a/examples/meson.build b/examples/meson.build
index 25d9c88457..544ec5eadd 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -19,7 +19,6 @@ all_examples = [
'flow_filtering',
'helloworld',
'ip_fragmentation',
- 'ip_pipeline',
'ip_reassembly',
'ipsec-secgw',
'ipv4_multicast',
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC 4/6] pipeline: remove legacy API
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (2 preceding siblings ...)
2026-07-24 16:43 ` [RFC 3/6] examples/ip_pipeline: remove example Stephen Hemminger
@ 2026-07-24 16:44 ` Stephen Hemminger
2026-07-24 16:44 ` [RFC 6/6] port: " Stephen Hemminger
` (11 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-24 16:44 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy pipeline API (rte_pipeline_*) together with the
port and table action APIs built on top of it, as announced for
removal in the 24.11 release. The SWX pipeline API remains.
The sched dependency was only used by the table action API,
so drop it.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 3 -
doc/guides/prog_guide/packet_framework.rst | 203 --
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 4 +
lib/pipeline/meson.build | 8 +-
lib/pipeline/rte_pipeline.c | 1640 ---------
lib/pipeline/rte_pipeline.h | 840 -----
lib/pipeline/rte_port_in_action.c | 539 ---
lib/pipeline/rte_port_in_action.h | 311 --
lib/pipeline/rte_table_action.c | 3483 --------------------
lib/pipeline/rte_table_action.h | 1137 -------
11 files changed, 5 insertions(+), 8168 deletions(-)
delete mode 100644 lib/pipeline/rte_pipeline.c
delete mode 100644 lib/pipeline/rte_pipeline.h
delete mode 100644 lib/pipeline/rte_port_in_action.c
delete mode 100644 lib/pipeline/rte_port_in_action.h
delete mode 100644 lib/pipeline/rte_table_action.c
delete mode 100644 lib/pipeline/rte_table_action.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 9296042119..17c15027b8 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -196,9 +196,6 @@ The public API headers are grouped by topics:
[hash](@ref rte_table_hash.h),
[array](@ref rte_table_array.h),
[stub](@ref rte_table_stub.h)
- * [pipeline](@ref rte_pipeline.h)
- [port_in_action](@ref rte_port_in_action.h)
- [table_action](@ref rte_table_action.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index ac302938dc..9eb2c5d3de 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -942,209 +942,6 @@ Additional notes:
This does not impact the performance of the key lookup operation,
as the probability of having the bucket in extended state is relatively small.
-Pipeline Library Design
------------------------
-
-A pipeline is defined by:
-
-#. The set of input ports;
-
-#. The set of output ports;
-
-#. The set of tables;
-
-#. The set of actions.
-
-The input ports are connected with the output ports through tree-like topologies of interconnected tables.
-The table entries contain the actions defining the operations to be executed on the input packets and the packet flow within the pipeline.
-
-Connectivity of Ports and Tables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To avoid any dependencies on the order in which pipeline elements are created,
-the connectivity of pipeline elements is defined after all the pipeline input ports,
-output ports and tables have been created.
-
-General connectivity rules:
-
-#. Each input port is connected to a single table. No input port should be left unconnected;
-
-#. The table connectivity to other tables or to output ports is regulated by the next hop actions of each table entry and the default table entry.
- The table connectivity is fluid, as the table entries and the default table entry can be updated during run-time.
-
- * A table can have multiple entries (including the default entry) connected to the same output port.
- A table can have different entries connected to different output ports.
- Different tables can have entries (including default table entry) connected to the same output port.
-
- * A table can have multiple entries (including the default entry) connected to another table,
- in which case all these entries have to point to the same table.
- This constraint is enforced by the API and prevents tree-like topologies from being created (allowing table chaining only),
- with the purpose of simplifying the implementation of the pipeline run-time execution engine.
-
-Port Actions
-~~~~~~~~~~~~
-
-Port Action Handler
-^^^^^^^^^^^^^^^^^^^
-
-An action handler can be assigned to each input/output port to define actions to be executed on each input packet that is received by the port.
-Defining the action handler for a specific input/output port is optional (i.e. the action handler can be disabled).
-
-For input ports, the action handler is executed after RX function. For output ports, the action handler is executed before the TX function.
-
-The action handler can decide to drop packets.
-
-Table Actions
-~~~~~~~~~~~~~
-
-Table Action Handler
-^^^^^^^^^^^^^^^^^^^^
-
-An action handler to be executed on each input packet can be assigned to each table.
-Defining the action handler for a specific table is optional (i.e. the action handler can be disabled).
-
-The action handler is executed after the table lookup operation is performed and the table entry associated with each input packet is identified.
-The action handler can only handle the user-defined actions, while the reserved actions (e.g. the next hop actions) are handled by the Packet Framework.
-The action handler can decide to drop the input packet.
-
-Reserved Actions
-^^^^^^^^^^^^^^^^
-
-The reserved actions are handled directly by the Packet Framework without the user being able to change their meaning
-through the table action handler configuration.
-A special category of the reserved actions is represented by the next hop actions, which regulate the packet flow between input ports,
-tables and output ports through the pipeline.
-:numref:`packet_framework_table_qos_33` lists the next hop actions.
-
-.. _packet_framework_table_qos_33:
-
-.. table:: Next Hop Actions (Reserved)
-
- +---+---------------------+-----------------------------------------------------------------------------------+
- | # | Next hop action | Description |
- | | | |
- +===+=====================+===================================================================================+
- | 1 | Drop | Drop the current packet. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 2 | Send to output port | Send the current packet to specified output port. The output port ID is metadata |
- | | | stored in the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 3 | Send to table | Send the current packet to specified table. The table ID is metadata stored in |
- | | | the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
-
-User Actions
-^^^^^^^^^^^^
-
-For each table, the meaning of user actions is defined through the configuration of the table action handler.
-Different tables can be configured with different action handlers, therefore the meaning of the user actions
-and their associated meta-data is private to each table.
-Within the same table, all the table entries (including the table default entry) share the same definition
-for the user actions and their associated meta-data,
-with each table entry having its own set of enabled user actions and its own copy of the action meta-data.
-:numref:`packet_framework_table_qos_34` contains a non-exhaustive list of user action examples.
-
-.. _packet_framework_table_qos_34:
-
-.. table:: User Action Examples
-
- +---+-----------------------------------+---------------------------------------------------------------------+
- | # | User action | Description |
- | | | |
- +===+===================================+=====================================================================+
- | 1 | Metering | Per flow traffic metering using the srTCM and trTCM algorithms. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 2 | Statistics | Update the statistics counters maintained per flow. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 3 | App ID | Per flow state machine fed by variable length sequence of packets |
- | | | at the flow initialization with the purpose of identifying the |
- | | | traffic type and application. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 4 | Push/pop labels | Push/pop VLAN/MPLS labels to/from the current packet. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 5 | Network Address Translation (NAT) | Translate between the internal (LAN) and external (WAN) IP |
- | | | destination/source address and/or L4 protocol destination/source |
- | | | port. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 6 | TTL update | Decrement IP TTL and, in case of IPv4 packets, update the IP |
- | | | checksum. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 7 | Sym Crypto | Generate Cryptodev session based on the user-specified algorithm |
- | | | and key(s), and assemble the cryptodev operation based on the |
- | | | predefined offsets. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
-
-Multicore Scaling
------------------
-
-A complex application is typically split across multiple cores, with cores communicating through SW queues.
-There is usually a performance limit on the number of table lookups
-and actions that can be fitted on the same CPU core due to HW constraints like:
-available CPU cycles, cache memory size, cache transfer BW, memory transfer BW, etc.
-
-As the application is split across multiple CPU cores, the Packet Framework facilitates the creation of several pipelines,
-the assignment of each such pipeline to a different CPU core
-and the interconnection of all CPU core-level pipelines into a single application-level complex pipeline.
-For example, if CPU core A is assigned to run pipeline P1 and CPU core B pipeline P2,
-then the interconnection of P1 with P2 could be achieved by having the same set of SW queues act like output ports
-for P1 and input ports for P2.
-
-This approach enables the application development using the pipeline, run-to-completion (clustered) or hybrid (mixed) models.
-
-It is allowed for the same core to run several pipelines, but it is not allowed for several cores to run the same pipeline.
-
-Shared Data Structures
-~~~~~~~~~~~~~~~~~~~~~~
-
-The threads performing table lookup are actually table writers rather than just readers.
-Even if the specific table lookup algorithm is thread-safe for multiple readers
-(e. g. read-only access of the search algorithm data structures is enough to conduct the lookup operation),
-once the table entry for the current packet is identified, the thread is typically expected to update the action meta-data stored in the table entry
-(e.g. increment the counter tracking the number of packets that hit this table entry), and thus modify the table entry.
-During the time this thread is accessing this table entry (either writing or reading; duration is application specific),
-for data consistency reasons, no other threads (threads performing table lookup or entry add/delete operations) are allowed to modify this table entry.
-
-Mechanisms to share the same table between multiple threads:
-
-#. **Multiple writer threads.**
- Threads need to use synchronization primitives like semaphores (distinct semaphore per table entry) or atomic instructions.
- The cost of semaphores is usually high, even when the semaphore is free.
- The cost of atomic instructions is normally higher than the cost of regular instructions.
-
-#. **Multiple writer threads, with single thread performing table lookup operations and multiple threads performing table entry add/delete operations.**
- The threads performing table entry add/delete operations send table update requests to the reader (typically through message passing queues),
- which does the actual table updates and then sends the response back to the request initiator.
-
-#. **Single writer thread performing table entry add/delete operations and multiple reader threads that perform table lookup operations with read-only access to the table entries.**
- The reader threads use the main table copy while the writer is updating the mirror copy.
- Once the writer update is done, the writer can signal to the readers and busy wait until all readers swap between the main copy (which now becomes the mirror copy) and
- the mirror copy (which now becomes the main copy).
-
-Interfacing with Accelerators
------------------------------
-
-The presence of accelerators is usually detected during the initialization phase by inspecting the HW devices that are part of the system (e.g. by PCI bus enumeration).
-Typical devices with acceleration capabilities are:
-
-* Inline accelerators: NICs, switches, FPGAs, etc;
-
-* Look-aside accelerators: chipsets, FPGAs, Intel QuickAssist, etc.
-
-Usually, to support a specific functional block, specific implementation of Packet Framework tables and/or ports and/or actions has to be provided for each accelerator,
-with all the implementations sharing the same API: pure SW implementation (no acceleration), implementation using accelerator A, implementation using accelerator B, etc.
-The selection between these implementations could be done at build time or at run-time (recommended), based on which accelerators are present in the system,
-with no application changes required.
-
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 6ad7698c6b..758652a492 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* 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_*)
- will gradually transition from experimental to stable status.
-
* table: The table library legacy API (functions rte_table_*)
will be deprecated and subsequently removed in DPDK 24.11 release.
Before this, the new table library API (functions rte_swx_table_*)
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 4cc1cec108..a1056ae5d2 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -75,6 +75,10 @@ Removed Items
the legacy pipeline library API.
The ``pipeline`` example application covers the SWX pipeline API.
+* Removed the legacy pipeline library API: ``rte_pipeline_*``,
+ ``rte_port_in_action_*`` and ``rte_table_action_*`` functions.
+ The SWX pipeline API (``rte_swx_pipeline_*``) remains.
+
API Changes
-----------
diff --git a/lib/pipeline/meson.build b/lib/pipeline/meson.build
index 823c7929a7..997ded6792 100644
--- a/lib/pipeline/meson.build
+++ b/lib/pipeline/meson.build
@@ -10,21 +10,15 @@ endif
cflags += no_wvla_cflag
sources = files(
- 'rte_pipeline.c',
- 'rte_port_in_action.c',
- 'rte_table_action.c',
'rte_swx_ipsec.c',
'rte_swx_pipeline.c',
'rte_swx_pipeline_spec.c',
'rte_swx_ctl.c',
)
headers = files(
- 'rte_pipeline.h',
- 'rte_port_in_action.h',
- 'rte_table_action.h',
'rte_swx_ipsec.h',
'rte_swx_pipeline.h',
'rte_swx_extern.h',
'rte_swx_ctl.h',
)
-deps += ['port', 'table', 'meter', 'sched', 'cryptodev', 'ipsec']
+deps += ['port', 'table', 'meter', 'cryptodev', 'ipsec']
diff --git a/lib/pipeline/rte_pipeline.c b/lib/pipeline/rte_pipeline.c
deleted file mode 100644
index fa3c8b77ee..0000000000
--- a/lib/pipeline/rte_pipeline.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-
-#include "rte_pipeline.h"
-
-RTE_LOG_REGISTER_DEFAULT(pipeline_logtype, INFO);
-#define RTE_LOGTYPE_PIPELINE pipeline_logtype
-
-#define PIPELINE_LOG(level, ...) \
- RTE_LOG_LINE(level, PIPELINE, "" __VA_ARGS__)
-
-#define RTE_TABLE_INVALID UINT32_MAX
-
-#ifdef RTE_PIPELINE_STATS_COLLECT
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask) \
- __extension__ ({ (p)->n_pkts_ah_drop = rte_popcount64(mask); })
-
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter) \
- __extension__ ({ (counter) += (p)->n_pkts_ah_drop; (p)->n_pkts_ah_drop = 0; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p) \
- __extension__ ({ (p)->pkts_drop_mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter) \
-__extension__ ({ \
- uint64_t mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; \
- mask ^= (p)->pkts_drop_mask; \
- (counter) += rte_popcount64(mask); \
-})
-
-#else
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask)
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter)
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p)
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter)
-
-#endif
-
-struct rte_port_in {
- /* Input parameters */
- struct rte_port_in_ops ops;
- rte_pipeline_port_in_action_handler f_action;
- void *arg_ah;
- uint32_t burst_size;
-
- /* The table to which this port is connected */
- uint32_t table_id;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* List of enabled ports */
- struct rte_port_in *next;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_port_out {
- /* Input parameters */
- struct rte_port_out_ops ops;
- rte_pipeline_port_out_action_handler f_action;
- void *arg_ah;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_table {
- /* Input parameters */
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action_hit;
- rte_pipeline_table_action_handler_miss f_action_miss;
- void *arg_ah;
- struct rte_pipeline_table_entry *default_entry;
- uint32_t entry_size;
-
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
-
- /* Handle to the low-level table object */
- void *h_table;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
- uint64_t n_pkts_dropped_lkp_hit;
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct __rte_cache_aligned rte_pipeline {
- /* Input parameters */
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- int socket_id;
- uint32_t offset_port_id;
-
- /* Internal tables */
- struct rte_port_in ports_in[RTE_PIPELINE_PORT_IN_MAX];
- struct rte_port_out ports_out[RTE_PIPELINE_PORT_OUT_MAX];
- struct rte_table tables[RTE_PIPELINE_TABLE_MAX];
-
- /* Occupancy of internal tables */
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
-
- /* List of enabled ports */
- uint64_t enabled_port_in_mask;
- struct rte_port_in *port_in_next;
-
- /* Pipeline run structures */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_pipeline_table_entry *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t action_mask0[RTE_PIPELINE_ACTIONS];
- uint64_t action_mask1[RTE_PIPELINE_ACTIONS];
- uint64_t pkts_mask;
- uint64_t n_pkts_ah_drop;
- uint64_t pkts_drop_mask;
-};
-
-static inline uint32_t
-rte_mask_get_next(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask << ((63 - pos) & 0x3F)) |
- (mask >> ((pos + 1) & 0x3F));
- return (rte_ctz64(mask_rot) - (63 - pos)) & 0x3F;
-}
-
-static inline uint32_t
-rte_mask_get_prev(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask >> (pos & 0x3F)) |
- (mask << ((64 - pos) & 0x3F));
- return ((63 - rte_clz64(mask_rot)) + pos) & 0x3F;
-}
-
-static void
-rte_pipeline_table_free(struct rte_table *table);
-
-static void
-rte_pipeline_port_in_free(struct rte_port_in *port);
-
-static void
-rte_pipeline_port_out_free(struct rte_port_out *port);
-
-/*
- * Pipeline
- */
-static int
-rte_pipeline_check_params(struct rte_pipeline_params *params)
-{
- if (params == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter params", __func__);
- return -EINVAL;
- }
-
- /* name */
- if (params->name == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter name", __func__);
- return -EINVAL;
- }
-
- /* socket */
- if (params->socket_id < 0) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter socket_id",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_create)
-struct rte_pipeline *
-rte_pipeline_create(struct rte_pipeline_params *params)
-{
- struct rte_pipeline *p;
- int status;
-
- /* Check input parameters */
- status = rte_pipeline_check_params(params);
- if (status != 0) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline params check failed (%d)",
- __func__, status);
- return NULL;
- }
-
- /* Allocate memory for the pipeline on requested socket */
- p = rte_zmalloc_socket("PIPELINE", sizeof(struct rte_pipeline),
- RTE_CACHE_LINE_SIZE, params->socket_id);
-
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline memory allocation failed", __func__);
- return NULL;
- }
-
- /* Save input parameters */
- strlcpy(p->name, params->name, RTE_PIPELINE_MAX_NAME_SZ);
- p->socket_id = params->socket_id;
- p->offset_port_id = params->offset_port_id;
-
- /* Initialize pipeline internal data structure */
- p->num_ports_in = 0;
- p->num_ports_out = 0;
- p->num_tables = 0;
- p->enabled_port_in_mask = 0;
- p->port_in_next = NULL;
- p->pkts_mask = 0;
- p->n_pkts_ah_drop = 0;
-
- return p;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_free)
-int
-rte_pipeline_free(struct rte_pipeline *p)
-{
- uint32_t i;
-
- /* Check input parameters */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: rte_pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free input ports */
- for (i = 0; i < p->num_ports_in; i++) {
- struct rte_port_in *port = &p->ports_in[i];
-
- rte_pipeline_port_in_free(port);
- }
-
- /* Free tables */
- for (i = 0; i < p->num_tables; i++) {
- struct rte_table *table = &p->tables[i];
-
- rte_pipeline_table_free(table);
- }
-
- /* Free output ports */
- for (i = 0; i < p->num_ports_out; i++) {
- struct rte_port_out *port = &p->ports_out[i];
-
- rte_pipeline_port_out_free(port);
- }
-
- /* Free pipeline memory */
- rte_free(p);
-
- return 0;
-}
-
-/*
- * Table
- */
-static int
-rte_table_check_params(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (table_id == NULL) {
- PIPELINE_LOG(ERR, "%s: table_id parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_lookup == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_lookup function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- /* De we have room for one more table? */
- if (p->num_tables == RTE_PIPELINE_TABLE_MAX) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for num_tables parameter",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_create)
-int
-rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- struct rte_table *table;
- struct rte_pipeline_table_entry *default_entry;
- void *h_table;
- uint32_t entry_size, id;
- int status;
-
- /* Check input arguments */
- status = rte_table_check_params(p, params, table_id);
- if (status != 0)
- return status;
-
- id = p->num_tables;
- table = &p->tables[id];
-
- /* Allocate space for the default table entry */
- entry_size = sizeof(struct rte_pipeline_table_entry) +
- params->action_data_size;
- default_entry = rte_zmalloc_socket(
- "PIPELINE", entry_size, RTE_CACHE_LINE_SIZE, p->socket_id);
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Failed to allocate default entry", __func__);
- return -EINVAL;
- }
-
- /* Create the table */
- h_table = params->ops->f_create(params->arg_create, p->socket_id,
- entry_size);
- if (h_table == NULL) {
- rte_free(default_entry);
- PIPELINE_LOG(ERR, "%s: Table creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_tables++;
- *table_id = id;
-
- /* Save input parameters */
- table->ops = *params->ops;
- table->f_action_hit = params->f_action_hit;
- table->f_action_miss = params->f_action_miss;
- table->arg_ah = params->arg_ah;
- table->entry_size = entry_size;
-
- /* Clear the lookup miss actions (to be set later through API) */
- table->default_entry = default_entry;
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- /* Initialize table internal data structure */
- table->h_table = h_table;
- table->table_next_id = 0;
- table->table_next_id_valid = 0;
-
- return 0;
-}
-
-void
-rte_pipeline_table_free(struct rte_table *table)
-{
- if (table->ops.f_free != NULL)
- table->ops.f_free(table->h_table);
-
- rte_free(table->default_entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_add)
-int
-rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: default_entry parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (default_entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Set the lookup miss actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = default_entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- memcpy(table->default_entry, default_entry, table->entry_size);
-
- *default_entry_ptr = table->default_entry;
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_delete)
-int
-rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- /* Save the current contents of the default entry */
- if (entry)
- memcpy(entry, table->default_entry, table->entry_size);
-
- /* Clear the lookup miss actions */
- memset(table->default_entry, 0, table->entry_size);
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add)
-int
-rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entry == NULL) {
- PIPELINE_LOG(ERR, "%s: entry parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Add entry */
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- return (table->ops.f_add)(table->h_table, key, (void *) entry,
- key_found, (void **) entry_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete)
-int
-rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete)(table->h_table, key, key_found, entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add_bulk)
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr)
-{
- struct rte_table *table;
- uint32_t i;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: keys parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entries == NULL) {
- PIPELINE_LOG(ERR, "%s: entries parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add_bulk == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add_bulk function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entries[i]->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
- }
-
- /* Add entry */
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entries[i]->table_id;
- table->table_next_id_valid = 1;
- }
- }
-
- return (table->ops.f_add_bulk)(table->h_table, keys, (void **) entries,
- n_keys, key_found, (void **) entries_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete_bulk)
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete_bulk)(table->h_table, keys, n_keys, key_found,
- (void **) entries);
-}
-
-/*
- * Port
- */
-static int
-rte_pipeline_port_in_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_rx == NULL) {
- PIPELINE_LOG(ERR, "%s: f_rx function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- /* burst_size */
- if ((params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PIPELINE_LOG(ERR, "%s: invalid value for burst_size",
- __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_in == RTE_PIPELINE_PORT_IN_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_in", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-rte_pipeline_port_out_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx_bulk function pointer NULL", __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_out == RTE_PIPELINE_PORT_OUT_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_out", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_create)
-int
-rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- struct rte_port_in *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_in_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_in;
- port = &p->ports_in[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_in++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
- port->burst_size = params->burst_size;
-
- /* Initialize port internal data structure */
- port->table_id = RTE_TABLE_INVALID;
- port->h_port = h_port;
- port->next = NULL;
-
- return 0;
-}
-
-void
-rte_pipeline_port_in_free(struct rte_port_in *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_create)
-int
-rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- struct rte_port_out *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_out_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_out;
- port = &p->ports_out[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_out++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
-
- /* Initialize port internal data structure */
- port->h_port = h_port;
-
- return 0;
-}
-
-void
-rte_pipeline_port_out_free(struct rte_port_out *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_connect_to_table)
-int
-rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct rte_port_in *port;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: Table ID %u is out of range",
- __func__, table_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
- port->table_id = table_id;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_enable)
-int
-rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already enabled */
- port_mask = 1LLU << port_id;
- if (p->enabled_port_in_mask & port_mask)
- return 0;
-
- p->enabled_port_in_mask |= port_mask;
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port;
- port->next = port_next;
-
- /* Check if list of enabled ports was previously empty */
- if (p->enabled_port_in_mask == port_mask)
- p->port_in_next = port;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_disable)
-int
-rte_pipeline_port_in_disable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR, "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already disabled */
- port_mask = 1LLU << port_id;
- if ((p->enabled_port_in_mask & port_mask) == 0)
- return 0;
-
- p->enabled_port_in_mask &= ~port_mask;
-
- /* Return if no other enabled ports */
- if (p->enabled_port_in_mask == 0) {
- p->port_in_next = NULL;
-
- return 0;
- }
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port_next;
-
- /* Check if the port which has just been disabled is next to serve */
- if (port == p->port_in_next)
- p->port_in_next = port_next;
-
- return 0;
-}
-
-/*
- * Pipeline run-time
- */
-RTE_EXPORT_SYMBOL(rte_pipeline_check)
-int
-rte_pipeline_check(struct rte_pipeline *p)
-{
- uint32_t port_in_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* Check that pipeline has at least one input port, one table and one
- output port */
- if (p->num_ports_in == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 input port",
- __func__);
- return -EINVAL;
- }
- if (p->num_tables == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 table",
- __func__);
- return -EINVAL;
- }
- if (p->num_ports_out == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 output port",
- __func__);
- return -EINVAL;
- }
-
- /* Check that all input ports are connected */
- for (port_in_id = 0; port_in_id < p->num_ports_in; port_in_id++) {
- struct rte_port_in *port_in = &p->ports_in[port_in_id];
-
- if (port_in->table_id == RTE_TABLE_INVALID) {
- PIPELINE_LOG(ERR,
- "%s: Port IN ID %u is not connected",
- __func__, port_in_id);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static inline void
-rte_pipeline_compute_masks(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->action_mask1[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos = p->entries[i]->action;
-
- p->action_mask1[pos] |= pkt_mask;
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pos = p->entries[i]->action;
- p->action_mask1[pos] |= pkt_mask;
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_bulk(struct rte_pipeline *p,
- uint64_t pkts_mask, uint32_t port_id)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- p->pkts_mask = pkts_mask;
-
- /* Output port user actions */
- if (port_out->f_action != NULL) {
- port_out->f_action(p, p->pkts, pkts_mask, port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
- }
-
- /* Output port TX */
- if (p->pkts_mask != 0)
- port_out->ops.f_tx_bulk(port_out->h_port,
- p->pkts,
- p->pkts_mask);
-}
-
-static inline void
-rte_pipeline_action_handler_port(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id = p->entries[i]->port_id;
- struct rte_port_out *port_out =
- &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = p->entries[i]->port_id;
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_meta(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id =
- RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- struct rte_port_out *port_out = &p->ports_out[
- port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_drop(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- rte_pktmbuf_free(p->pkts[i]);
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- rte_pktmbuf_free(p->pkts[i]);
- }
- }
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_run)
-int
-rte_pipeline_run(struct rte_pipeline *p)
-{
- struct rte_port_in *port_in = p->port_in_next;
- uint32_t n_pkts, table_id;
-
- if (port_in == NULL)
- return 0;
-
- /* Input port RX */
- n_pkts = port_in->ops.f_rx(port_in->h_port, p->pkts,
- port_in->burst_size);
- if (n_pkts == 0) {
- p->port_in_next = port_in->next;
- return 0;
- }
-
- p->pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- /* Input port user actions */
- if (port_in->f_action != NULL) {
- port_in->f_action(p, p->pkts, n_pkts, port_in->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_in->n_pkts_dropped_by_ah);
- }
-
- /* Table */
- for (table_id = port_in->table_id; p->pkts_mask != 0; ) {
- struct rte_table *table;
- uint64_t lookup_hit_mask, lookup_miss_mask;
-
- /* Lookup */
- table = &p->tables[table_id];
- table->ops.f_lookup(table->h_table, p->pkts, p->pkts_mask,
- &lookup_hit_mask, (void **) p->entries);
- lookup_miss_mask = p->pkts_mask & (~lookup_hit_mask);
-
- /* Lookup miss */
- if (lookup_miss_mask != 0) {
- struct rte_pipeline_table_entry *default_entry =
- table->default_entry;
-
- p->pkts_mask = lookup_miss_mask;
-
- /* Table user actions */
- if (table->f_action_miss != NULL) {
- table->f_action_miss(p,
- p->pkts,
- lookup_miss_mask,
- default_entry,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_miss_ah);
- }
-
- /* Table reserved actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_PORT) &&
- (p->pkts_mask != 0))
- rte_pipeline_action_handler_port_bulk(p,
- p->pkts_mask,
- default_entry->port_id);
- else {
- uint32_t pos = default_entry->action;
-
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
-
- p->action_mask0[pos] |= p->pkts_mask;
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_miss);
- }
- }
-
- /* Lookup hit */
- if (lookup_hit_mask != 0) {
- p->pkts_mask = lookup_hit_mask;
-
- /* Table user actions */
- if (table->f_action_hit != NULL) {
- table->f_action_hit(p,
- p->pkts,
- lookup_hit_mask,
- p->entries,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_hit_ah);
- }
-
- /* Table reserved actions */
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
- rte_pipeline_compute_masks(p, p->pkts_mask);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_DROP];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT_META];
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_TABLE];
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_hit);
- }
-
- /* Prepare for next iteration */
- p->pkts_mask = p->action_mask0[RTE_PIPELINE_ACTION_TABLE];
- table_id = table->table_next_id;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
- }
-
- /* Table reserved action PORT */
- rte_pipeline_action_handler_port(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT]);
-
- /* Table reserved action PORT META */
- rte_pipeline_action_handler_port_meta(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
-
- /* Table reserved action DROP */
- rte_pipeline_action_handler_drop(p,
- p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
-
- /* Pick candidate for next port IN to serve */
- p->port_in_next = port_in->next;
-
- return (int) n_pkts;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_flush)
-int
-rte_pipeline_flush(struct rte_pipeline *p)
-{
- uint32_t port_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- for (port_id = 0; port_id < p->num_ports_out; port_id++) {
- struct rte_port_out *port = &p->ports_out[port_id];
-
- if (port->ops.f_flush != NULL)
- port->ops.f_flush(port->h_port);
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_packet_insert)
-int
-rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id, struct rte_mbuf *pkt)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- port_out->ops.f_tx(port_out->h_port, pkt); /* Output port TX */
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_hijack)
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_drop)
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
-
- RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_stats_read)
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear)
-{
- struct rte_port_in *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_stats_read)
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear)
-{
- struct rte_port_out *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_out) {
- PIPELINE_LOG(ERR,
- "%s: port OUT ID %u is out of range", __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_out[port_id];
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_stats_read)
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear)
-{
- struct rte_table *table;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table %u is out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
- if (table->ops.f_stats != NULL) {
- retval = table->ops.f_stats(table->h_table, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL) {
- stats->n_pkts_dropped_by_lkp_hit_ah =
- table->n_pkts_dropped_by_lkp_hit_ah;
- stats->n_pkts_dropped_by_lkp_miss_ah =
- table->n_pkts_dropped_by_lkp_miss_ah;
- stats->n_pkts_dropped_lkp_hit = table->n_pkts_dropped_lkp_hit;
- stats->n_pkts_dropped_lkp_miss = table->n_pkts_dropped_lkp_miss;
- }
-
- if (clear != 0) {
- table->n_pkts_dropped_by_lkp_hit_ah = 0;
- table->n_pkts_dropped_by_lkp_miss_ah = 0;
- table->n_pkts_dropped_lkp_hit = 0;
- table->n_pkts_dropped_lkp_miss = 0;
- }
-
- return 0;
-}
diff --git a/lib/pipeline/rte_pipeline.h b/lib/pipeline/rte_pipeline.h
deleted file mode 100644
index c9e7172453..0000000000
--- a/lib/pipeline/rte_pipeline.h
+++ /dev/null
@@ -1,840 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PIPELINE_H__
-#define __INCLUDE_RTE_PIPELINE_H__
-
-/**
- * @file
- * RTE Pipeline
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard methodology (logically similar to OpenFlow) for rapid development
- * of complex packet processing pipelines out of ports, tables and actions.
- *
- * <B>Basic operation.</B> A pipeline is constructed by connecting its input
- * ports to its output ports through a chain of lookup tables. As result of
- * lookup operation into the current table, one of the table entries (or the
- * default table entry, in case of lookup miss) is identified to provide the
- * actions to be executed on the current packet and the associated action
- * meta-data. The behavior of user actions is defined through the configurable
- * table action handler, while the reserved actions define the next hop for the
- * current packet (either another table, an output port or packet drop) and are
- * handled transparently by the framework.
- *
- * <B>Initialization and run-time flows.</B> Once all the pipeline elements
- * (input ports, tables, output ports) have been created, input ports connected
- * to tables, table action handlers configured, tables populated with the
- * initial set of entries (actions and action meta-data) and input ports
- * enabled, the pipeline runs automatically, pushing packets from input ports
- * to tables and output ports. At each table, the identified user actions are
- * being executed, resulting in action meta-data (stored in the table entry)
- * and packet meta-data (stored with the packet descriptor) being updated. The
- * pipeline tables can have further updates and input ports can be disabled or
- * enabled later on as required.
- *
- * <B>Multi-core scaling.</B> Typically, each CPU core will run its own
- * pipeline instance. Complex application-level pipelines can be implemented by
- * interconnecting multiple CPU core-level pipelines in tree-like topologies,
- * as the same port devices (e.g. SW rings) can serve as output ports for the
- * pipeline running on CPU core A, as well as input ports for the pipeline
- * running on CPU core B. This approach enables the application development
- * using the pipeline (CPU cores connected serially), cluster/run-to-completion
- * (CPU cores connected in parallel) or mixed (pipeline of CPU core clusters)
- * programming models.
- *
- * <B>Thread safety.</B> It is possible to have multiple pipelines running on
- * the same CPU core, but it is not allowed (for thread safety reasons) to have
- * multiple CPU cores running the same pipeline instance.
- */
-
-#include <stdint.h>
-
-#include <rte_port.h>
-#include <rte_table.h>
-#include <rte_common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_mbuf;
-
-/*
- * Pipeline
- */
-/** Opaque data type for pipeline */
-struct rte_pipeline;
-
-/** Parameters for pipeline creation */
-struct rte_pipeline_params {
- /** Pipeline name */
- const char *name;
-
- /** CPU socket ID where memory for the pipeline and its elements (ports
- and tables) should be allocated */
- int socket_id;
-
- /** Offset within packet meta-data to port_id to be used by action
- "Send packet to output port read from packet meta-data". Has to be
- 4-byte aligned. */
- uint32_t offset_port_id;
-};
-
-/** Pipeline port in stats. */
-struct rte_pipeline_port_in_stats {
- /** Port in stats. */
- struct rte_port_in_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-
-};
-
-/** Pipeline port out stats. */
-struct rte_pipeline_port_out_stats {
- /** Port out stats. */
- struct rte_port_out_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-/** Pipeline table stats. */
-struct rte_pipeline_table_stats {
- /** Table stats. */
- struct rte_table_stats stats;
-
- /** Number of packets dropped by lookup hit action handler. */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
-
- /** Number of packets dropped by lookup miss action handler. */
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_hit;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-/**
- * Pipeline create
- *
- * @param params
- * Parameters for pipeline creation
- * @return
- * Handle to pipeline instance on success or NULL otherwise
- */
-struct rte_pipeline *rte_pipeline_create(struct rte_pipeline_params *params);
-
-/**
- * Pipeline free
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_free(struct rte_pipeline *p);
-
-/**
- * Pipeline consistency check
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_check(struct rte_pipeline *p);
-
-/**
- * Pipeline run
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * Number of packets read and processed
- */
-int rte_pipeline_run(struct rte_pipeline *p);
-
-/**
- * Pipeline flush
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_flush(struct rte_pipeline *p);
-
-/*
- * Actions
- */
-/** Reserved actions */
-enum rte_pipeline_action {
- /** Drop the packet */
- RTE_PIPELINE_ACTION_DROP = 0,
-
- /** Send packet to output port */
- RTE_PIPELINE_ACTION_PORT,
-
- /** Send packet to output port read from packet meta-data */
- RTE_PIPELINE_ACTION_PORT_META,
-
- /** Send packet to table */
- RTE_PIPELINE_ACTION_TABLE,
-
- /** Number of reserved actions */
- RTE_PIPELINE_ACTIONS
-};
-
-/*
- * Table
- */
-/** Maximum number of tables allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_TABLE_MAX 64
-
-/**
- * Head format for the table entry of any pipeline table. For any given
- * pipeline table, all table entries should have the same size and format. For
- * any given pipeline table, the table entry has to start with a head of this
- * structure, which contains the reserved actions and their associated
- * meta-data, and then optionally continues with user actions and their
- * associated meta-data. As all the currently defined reserved actions are
- * mutually exclusive, only one reserved action can be set per table entry.
- */
-struct rte_pipeline_table_entry {
- /** Reserved action */
- enum rte_pipeline_action action;
-
- union {
- /** Output port ID (meta-data for "Send packet to output port"
- action) */
- uint32_t port_id;
- /** Table ID (meta-data for "Send packet to table" action) */
- uint32_t table_id;
- };
- /** Start of table entry area for user defined actions and meta-data */
- uint8_t action_data[];
-};
-
-/**
- * Pipeline table action handler on lookup hit
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet and element n of entries array is pointing to a valid table
- * entry associated with the packet, with the association typically done by
- * the table lookup operation. Otherwise, element n of pkts array and element
- * n of entries array will not be accessed.
- * @param entries
- * Set of table entries specified as array of up to 64 pointers to struct
- * rte_pipeline_table_entry
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_hit)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg);
-
-/**
- * Pipeline table action handler on lookup miss
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param entry
- * Single table entry associated with all the valid packets from the input
- * burst, specified as pointer to struct rte_pipeline_table_entry.
- * This entry is the pipeline table default entry that is associated by the
- * table lookup operation with the input packets that have resulted in lookup
- * miss.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_miss)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry *entry,
- void *arg);
-
-/** Parameters for pipeline table creation. Action handlers have to be either
- both enabled or both disabled (they can be disabled by setting them to
- NULL). */
-struct rte_pipeline_table_params {
- /** Table operations (specific to each table type) */
- struct rte_table_ops *ops;
- /** Opaque param to be passed to the table create operation when
- invoked */
- void *arg_create;
- /** Callback function to execute the user actions on input packets in
- case of lookup hit */
- rte_pipeline_table_action_handler_hit f_action_hit;
- /** Callback function to execute the user actions on input packets in
- case of lookup miss */
- rte_pipeline_table_action_handler_miss f_action_miss;
-
- /** Opaque parameter to be passed to lookup hit and/or lookup miss
- action handlers when invoked */
- void *arg_ah;
- /** Memory size to be reserved per table entry for storing the user
- actions and their meta-data */
- uint32_t action_data_size;
-};
-
-/**
- * Pipeline table create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline table creation
- * @param table_id
- * Table ID. Valid only within the scope of table IDs of the current
- * pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id);
-
-/**
- * Pipeline table default entry add
- *
- * The contents of the table default entry is updated with the provided actions
- * and meta-data. When the default entry is not configured (by using this
- * function), the built-in default entry has the action "Drop" and meta-data
- * set to all-zeros.
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param default_entry
- * New contents for the table default entry
- * @param default_entry_ptr
- * On successful invocation, pointer to the default table entry which can be
- * used for further read-write accesses to this table entry. This pointer
- * is valid until the default entry is deleted or re-added.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr);
-
-/**
- * Pipeline table default entry delete
- *
- * The new contents of the table default entry is set to reserved action "Drop
- * the packet" with meta-data cleared (i.e. set to all-zeros).
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param entry
- * On successful invocation, when entry points to a valid buffer, the
- * previous contents of the table default entry (as it was just before the
- * delete operation) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param entry
- * New contents for the table entry identified by key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * already present in the table before the add operation and to FALSE (value
- * 0) if not
- * @param entry_ptr
- * On successful invocation, pointer to the table entry associated with key.
- * This can be used for further read-write accesses to this table entry and
- * is valid until the key is deleted from the table or re-added (usually for
- * associating different actions and/or action meta-data to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr);
-
-/**
- * Pipeline table entry delete
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * found in the table before the delete operation and to FALSE (value 0) if
- * not
- * @param entry
- * On successful invocation, when key is found in the table and entry points
- * to a valid buffer, the table entry contents (as it was before the delete
- * was performed) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param entries
- * Array containing new contents for every table entry identified by key
- * @param n_keys
- * Number of keys to add
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was already present in the table
- * before the add operation and to FALSE (value 0) if not
- * @param entries_ptr
- * On successful invocation, array *entries_ptr stores pointer to every table
- * entry associated with key. This can be used for further read-write accesses
- * to this table entry and is valid until the key is deleted from the table or
- * re-added (usually for associating different actions and/or action meta-data
- * to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr);
-
-/**
- * Pipeline table entry delete bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param n_keys
- * Number of keys to delete
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was found in the table before the
- * delete operation and to FALSE (value 0) if not
- * @param entries
- * If entries pointer is NULL, this pointer is ignored for every entry found.
- * Else, after successful invocation, if specific key is found in the table
- * and entry points to a valid buffer, the table entry contents (as it was
- * before the delete was performed) is copied to this buffer.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries);
-
-/**
- * Read pipeline table stats.
- *
- * This function reads table statistics identified by *table_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param table_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear);
-
-/*
- * Port IN
- */
-/** Maximum number of input ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_IN_MAX 64
-
-/**
- * Pipeline input port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param n
- * Number of packets in the input burst. This parameter specifies that
- * elements 0 to (n-1) of pkts array are valid.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_in_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n,
- void *arg);
-
-/** Parameters for pipeline input port creation */
-struct rte_pipeline_port_in_params {
- /** Input port operations (specific to each table type) */
- struct rte_port_in_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function to execute the user actions on input packets.
- Disabled if set to NULL. */
- rte_pipeline_port_in_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-
- /** Recommended burst size for the RX operation(in number of pkts) */
- uint32_t burst_size;
-};
-
-/**
- * Pipeline input port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline input port creation
- * @param port_id
- * Input port ID. Valid only within the scope of input port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id);
-
-/**
- * Pipeline input port connect to table
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id);
-
-/**
- * Pipeline input port enable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_enable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Pipeline input port disable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_disable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Read pipeline port in stats.
- *
- * This function reads port in statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear);
-
-/*
- * Port OUT
- */
-/** Maximum number of output ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_OUT_MAX 64
-
-/**
- * Pipeline output port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_out_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- void *arg);
-
-/** Parameters for pipeline output port creation. The action handlers have to
-be either both enabled or both disabled (by setting them to NULL). When
-enabled, the pipeline selects between them at different moments, based on the
-number of packets that have to be sent to the same output port. */
-struct rte_pipeline_port_out_params {
- /** Output port operations (specific to each table type) */
- struct rte_port_out_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function executing the user actions on bust of input
- packets */
- rte_pipeline_port_out_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-};
-
-/**
- * Pipeline output port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline output port creation
- * @param port_id
- * Output port ID. Valid only within the scope of output port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id);
-
-/**
- * Read pipeline port out stats.
- *
- * This function reads port out statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear);
-
-/*
- * Functions to be called as part of the port IN/OUT or table action handlers
- */
-/**
- * Action handler packet insert to output port
- *
- * This function can be called by any input/output port or table action handler
- * to send a packet out through one of the pipeline output ports. This packet is
- * generated by the action handler, i.e. this packet is not part of the burst of
- * packets read from one of the pipeline input ports and currently processed by
- * the pipeline (this packet is not an element of the pkts array input parameter
- * of the action handler).
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Output port ID (returned by previous invocation of pipeline output port
- * create) to send the packet specified by pkt
- * @param pkt
- * New packet generated by the action handler
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id,
- struct rte_mbuf *pkt);
-
-#define rte_pipeline_ah_port_out_packet_insert \
- rte_pipeline_port_out_packet_insert
-
-/**
- * Action handler packet hijack
- *
- * This function can be called by any input/output port or table action handler
- * to hijack selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The hijacked
- * packets are removed from any further pipeline processing, with the action
- * handler now having the full ownership for these packets.
- *
- * The action handler can further send the hijacked packets out through any
- * pipeline output port by calling the rte_pipeline_ah_port_out_packet_insert()
- * function. The action handler can also drop these packets by calling the
- * rte_pktmbuf_free() function, although a better alternative is provided by
- * the action handler using the rte_pipeline_ah_packet_drop() function.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be hijacked by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is hijacked.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-/**
- * Action handler packet drop
- *
- * This function is called by the pipeline action handlers (port in/out, table)
- * to drop the packets selected using packet mask.
- *
- * This function can be called by any input/output port or table action handler
- * to drop selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The dropped
- * packets are removed from any further pipeline processing and the packet
- * buffers are eventually freed to their buffer pool.
- *
- * This function updates the drop statistics counters correctly, therefore the
- * recommended approach for dropping packets by the action handlers is to call
- * this function as opposed to the action handler hijacking the packets first
- * and then dropping them invisibly to the pipeline (by using the
- * rte_pktmbuf_free() function).
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be dropped by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is dropped.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/pipeline/rte_port_in_action.c b/lib/pipeline/rte_port_in_action.c
deleted file mode 100644
index 2378e64de9..0000000000
--- a/lib/pipeline/rte_port_in_action.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_in_action.h"
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-static int
-fltr_cfg_check(struct rte_port_in_action_fltr_config *cfg)
-{
- if (cfg == NULL)
- return -1;
-
- return 0;
-}
-
-struct fltr_data {
- uint32_t port_id;
-};
-
-static void
-fltr_init(struct fltr_data *data,
- struct rte_port_in_action_fltr_config *cfg)
-{
- data->port_id = cfg->port_id;
-}
-
-static int
-fltr_apply(struct fltr_data *data,
- struct rte_port_in_action_fltr_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- data->port_id = p->port_id;
-
- return 0;
-}
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_port_in_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct lb_data {
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-static void
-lb_init(struct lb_data *data,
- struct rte_port_in_action_lb_config *cfg)
-{
- memcpy(data->port_id, cfg->port_id, sizeof(cfg->port_id));
-}
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_port_in_action_lb_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- memcpy(data->port_id, p->port_id, sizeof(p->port_id));
-
- return 0;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- case RTE_PORT_IN_ACTION_LB:
- return 1;
- default:
- return 0;
- }
-}
-
-#define RTE_PORT_IN_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-static size_t
-action_cfg_size(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct rte_port_in_action_fltr_config);
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct rte_port_in_action_lb_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_port_in_action_type type)
-{
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return &ap_config->fltr;
-
- case RTE_PORT_IN_ACTION_LB:
- return &ap_config->lb;
-
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_port_in_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_PORT_IN_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_port_in_action_type action,
- struct ap_config *ap_config __rte_unused)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct fltr_data);
-
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct lb_data);
-
- default:
- return 0;
- }
-}
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_PORT_IN_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_port_in_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_port_in_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_create, 18.05)
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id)
-{
- struct rte_port_in_action_profile *ap;
-
- /* Memory allocation */
- ap = rte_zmalloc_socket(NULL,
- sizeof(struct rte_port_in_action_profile),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (ap == NULL)
- return NULL;
-
- return ap;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_action_register, 18.05)
-int
-rte_port_in_action_profile_action_register(struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- status = fltr_cfg_check(action_config);
- break;
-
- case RTE_PORT_IN_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_freeze, 18.05)
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_free, 18.05)
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-struct rte_port_in_action {
- struct ap_config cfg;
- struct ap_data data;
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static __rte_always_inline void *
-action_data_get(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- size_t offset = action->data.offset[type];
-
- return &action->memory[offset];
-}
-
-static void
-action_data_init(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- void *data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- fltr_init(data, &action->cfg.fltr);
- return;
-
- case RTE_PORT_IN_ACTION_LB:
- lb_init(data, &action->cfg.lb);
- return;
-
- default:
- return;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_create, 18.05)
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_port_in_action *action;
- size_t size;
- uint32_t i;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- size = sizeof(struct rte_port_in_action) + profile->data.total_size;
- size = RTE_CACHE_LINE_ROUNDUP(size);
-
- action = rte_zmalloc_socket(NULL,
- size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- for (i = 0; i < RTE_PORT_IN_ACTION_MAX; i++)
- if (action->cfg.action_mask & (1LLU << i))
- action_data_init(action,
- (enum rte_port_in_action_type)i);
-
- return action;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_apply, 18.05)
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return fltr_apply(action_data,
- action_params);
-
- case RTE_PORT_IN_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-ah_filter_on_match(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or == 0) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_filter_on_mismatch(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_lb(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_lb_config *cfg = &action->cfg.lb;
- struct lb_data *data = action_data_get(action, RTE_PORT_IN_ACTION_LB);
- uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- uint32_t i;
-
- rte_pipeline_ah_packet_hijack(p, pkt_mask);
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(pkt,
- cfg->key_offset);
-
- uint64_t digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- uint64_t pos = digest & (RTE_PORT_IN_ACTION_LB_TABLE_SIZE - 1);
- uint32_t port_id = data->port_id[pos];
-
- rte_pipeline_port_out_packet_insert(p, port_id, pkt);
- }
-
- return 0;
-}
-
-static rte_pipeline_port_in_action_handler
-ah_selector(struct rte_port_in_action *action)
-{
- if (action->cfg.action_mask == 0)
- return NULL;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_FLTR)
- return (action->cfg.fltr.filter_on_match) ?
- ah_filter_on_match : ah_filter_on_mismatch;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_LB)
- return ah_lb;
-
- return NULL;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_params_get, 18.05)
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params)
-{
- rte_pipeline_port_in_action_handler f_action;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action = ah_selector(action);
-
- /* Fill in params */
- params->f_action = f_action;
- params->arg_ah = (f_action) ? action : NULL;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_free, 18.05)
-int
-rte_port_in_action_free(struct rte_port_in_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_port_in_action.h b/lib/pipeline/rte_port_in_action.h
deleted file mode 100644
index 9d17bae988..0000000000
--- a/lib/pipeline/rte_port_in_action.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IN_ACTION_H__
-#define __INCLUDE_RTE_PORT_IN_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Input Port Actions
- *
- * This API provides a common set of actions for pipeline input ports to speed
- * up application development.
- *
- * Each pipeline input port can be assigned an action handler to be executed
- * on every input packet during the pipeline execution. The pipeline library
- * allows the user to define his own input port actions by providing customized
- * input port action handler. While the user can still follow this process, this
- * API is intended to provide a quicker development alternative for a set of
- * predefined actions.
- *
- * The typical steps to use this API are:
- * - Define an input port action profile. This is a configuration template that
- * can potentially be shared by multiple input ports from the same or
- * different pipelines, with different input ports from the same pipeline
- * able to use different action profiles. For every input port using a given
- * action profile, the profile defines the set of actions and the action
- * configuration to be executed by the input port. API functions:
- * rte_port_in_action_profile_create(),
- * rte_port_in_action_profile_action_register(),
- * rte_port_in_action_profile_freeze().
- *
- * - Instantiate the input port action profile to create input port action
- * objects. Each pipeline input port has its own action object.
- * API functions: rte_port_in_action_create().
- *
- * - Use the input port action object to generate the input port action handler
- * invoked by the pipeline. API functions:
- * rte_port_in_action_params_get().
- *
- * - Use the input port action object to generate the internal data structures
- * used by the input port action handler based on given action parameters.
- * API functions: rte_port_in_action_apply().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Input port actions. */
-enum rte_port_in_action_type {
- /** Filter selected input packets. */
- RTE_PORT_IN_ACTION_FLTR = 0,
-
- /** Load balance. */
- RTE_PORT_IN_ACTION_LB,
-};
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-/** Filter key size (number of bytes) */
-#define RTE_PORT_IN_ACTION_FLTR_KEY_SIZE 16
-
-/** Filter action configuration (per action profile). */
-struct rte_port_in_action_fltr_config {
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask. */
- uint8_t key_mask[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** Key value. */
- uint8_t key[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** When non-zero, all the input packets that match the *key* (with the
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- * When zero, all the input packets that do NOT match the *key* (with
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- */
- int filter_on_match;
-
- /** Pipeline output port ID to send the filtered input packets to.
- * Can be updated later.
- *
- * @see struct rte_port_in_action_fltr_params
- */
- uint32_t port_id;
-};
-
-/** Filter action parameters (per action). */
-struct rte_port_in_action_fltr_params {
- /** Pipeline output port ID to send the filtered input packets to. */
- uint32_t port_id;
-};
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_PORT_IN_ACTION_LB_TABLE_SIZE 16
-
-/** Load balance action configuration (per action profile). */
-struct rte_port_in_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask(*key_size* bytes are valid). */
- uint8_t key_mask[RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table. Can be updated later.
- *
- * @see struct rte_port_in_action_lb_params
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/** Load balance action parameters (per action). */
-struct rte_port_in_action_lb_params {
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table.
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * Input port action profile.
- */
-struct rte_port_in_action_profile;
-
-/**
- * Input port action profile create.
- *
- * @param[in] socket_id
- * CPU socket ID for the internal data structures memory allocation.
- * @return
- * Input port action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id);
-
-/**
- * Input port action profile free.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid).
- * If profile is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action profile action register.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid and not in frozen
- * state).
- * @param[in] type
- * Specific input port action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_port_in_action_*type*_config is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_action_register(
- struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config);
-
-/**
- * Input port action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * input port action objects.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and not in frozen
- * state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_port_in_action_create()
- */
-__rte_experimental
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action.
- */
-struct rte_port_in_action;
-
-/**
- * Input port action create.
- *
- * Instantiates the given input port action profile to create an input port
- * action object.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new input
- * port action object should be allocated.
- * @return
- * Handle to input port action object on success, NULL on error.
- */
-__rte_experimental
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Input port action free.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * If action is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_free(struct rte_port_in_action *action);
-
-/**
- * Input port params get.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[inout] params
- * Pipeline input port parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params);
-
-/**
- * Input port action apply.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[in] type
- * Specific input port action previously registered for the input port action
- * profile of the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_port_in_action_*type*_params is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_PORT_IN_ACTION_H__ */
diff --git a/lib/pipeline/rte_table_action.c b/lib/pipeline/rte_table_action.c
deleted file mode 100644
index c990d7eb56..0000000000
--- a/lib/pipeline/rte_table_action.c
+++ /dev/null
@@ -1,3483 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_cycles.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_udp.h>
-#include <rte_vxlan.h>
-#include <rte_cryptodev.h>
-
-#include "rte_table_action.h"
-
-#define rte_htons rte_cpu_to_be_16
-#define rte_htonl rte_cpu_to_be_32
-
-#define rte_ntohs rte_be_to_cpu_16
-#define rte_ntohl rte_be_to_cpu_32
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-#define fwd_data rte_pipeline_table_entry
-
-static int
-fwd_apply(struct fwd_data *data,
- struct rte_table_action_fwd_params *p)
-{
- data->action = p->action;
-
- if (p->action == RTE_PIPELINE_ACTION_PORT)
- data->port_id = p->id;
-
- if (p->action == RTE_PIPELINE_ACTION_TABLE)
- data->table_id = p->id;
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_table_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_TABLE_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_TABLE_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct __rte_packed_begin lb_data {
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-} __rte_packed_end;
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_table_action_lb_params *p)
-{
- memcpy(data->out, p->out, sizeof(data->out));
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_lb(struct rte_mbuf *mbuf,
- struct lb_data *data,
- struct rte_table_action_lb_config *cfg)
-{
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->key_offset);
- uint32_t *out = RTE_MBUF_METADATA_UINT32_PTR(mbuf, cfg->out_offset);
- uint64_t digest, pos;
- uint32_t out_val;
-
- digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- pos = digest & (RTE_TABLE_ACTION_LB_TABLE_SIZE - 1);
- out_val = data->out[pos];
-
- *out = out_val;
-}
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-static int
-mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
-{
- if ((mtr->alg == RTE_TABLE_ACTION_METER_SRTCM) ||
- ((mtr->n_tc != 1) && (mtr->n_tc != 4)) ||
- (mtr->n_bytes_enabled != 0))
- return -ENOTSUP;
- return 0;
-}
-
-struct mtr_trtcm_data {
- struct rte_meter_trtcm trtcm;
- uint64_t stats[RTE_COLORS];
-};
-
-#define MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data) \
- (((data)->stats[RTE_COLOR_GREEN] & 0xF8LLU) >> 3)
-
-static void
-mtr_trtcm_data_meter_profile_id_set(struct mtr_trtcm_data *data,
- uint32_t profile_id)
-{
- data->stats[RTE_COLOR_GREEN] &= ~0xF8LLU;
- data->stats[RTE_COLOR_GREEN] |= (profile_id % 32) << 3;
-}
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color)\
- (((data)->stats[(color)] & 4LLU) >> 2)
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color)\
- ((enum rte_color)((data)->stats[(color)] & 3LLU))
-
-static void
-mtr_trtcm_data_policer_action_set(struct mtr_trtcm_data *data,
- enum rte_color color,
- enum rte_table_action_policer action)
-{
- if (action == RTE_TABLE_ACTION_POLICER_DROP) {
- data->stats[color] |= 4LLU;
- } else {
- data->stats[color] &= ~7LLU;
- data->stats[color] |= color & 3LLU;
- }
-}
-
-static uint64_t
-mtr_trtcm_data_stats_get(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- return data->stats[color] >> 8;
-}
-
-static void
-mtr_trtcm_data_stats_reset(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- data->stats[color] &= 0xFFLU;
-}
-
-#define MTR_TRTCM_DATA_STATS_INC(data, color) \
- ((data)->stats[(color)] += (1LLU << 8))
-
-static size_t
-mtr_data_size(struct rte_table_action_mtr_config *mtr)
-{
- return mtr->n_tc * sizeof(struct mtr_trtcm_data);
-}
-
-struct dscp_table_entry_data {
- enum rte_color color;
- uint16_t tc;
- uint16_t tc_queue;
-};
-
-struct dscp_table_data {
- struct dscp_table_entry_data entry[64];
-};
-
-struct meter_profile_data {
- struct rte_meter_trtcm_profile profile;
- uint32_t profile_id;
- int valid;
-};
-
-static struct meter_profile_data *
-meter_profile_data_find(struct meter_profile_data *mp,
- uint32_t mp_size,
- uint32_t profile_id)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (mp_data->valid && (mp_data->profile_id == profile_id))
- return mp_data;
- }
-
- return NULL;
-}
-
-static struct meter_profile_data *
-meter_profile_data_find_unused(struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (!mp_data->valid)
- return mp_data;
- }
-
- return NULL;
-}
-
-static int
-mtr_apply_check(struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- if (p->tc_mask > RTE_LEN2MASK(cfg->n_tc, uint32_t))
- return -EINVAL;
-
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-mtr_apply(struct mtr_trtcm_data *data,
- struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
- int status;
-
- /* Check input arguments */
- status = mtr_apply_check(p, cfg, mp, mp_size);
- if (status)
- return status;
-
- /* Apply */
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct mtr_trtcm_data *data_tc = &data[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- /* Find profile */
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
-
- memset(data_tc, 0, sizeof(*data_tc));
-
- /* Meter object */
- status = rte_meter_trtcm_config(&data_tc->trtcm,
- &mp_data->profile);
- if (status)
- return status;
-
- /* Meter profile */
- mtr_trtcm_data_meter_profile_id_set(data_tc,
- mp_data - mp);
-
- /* Policer actions */
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_GREEN,
- p_tc->policer[RTE_COLOR_GREEN]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_YELLOW,
- p_tc->policer[RTE_COLOR_YELLOW]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_RED,
- p_tc->policer[RTE_COLOR_RED]);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_mtr(struct rte_mbuf *mbuf,
- struct mtr_trtcm_data *data,
- struct dscp_table_data *dscp_table,
- struct meter_profile_data *mp,
- uint64_t time,
- uint32_t dscp,
- uint16_t total_length)
-{
- uint64_t drop_mask;
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- enum rte_color color_in, color_meter, color_policer;
- uint32_t tc, mp_id;
-
- tc = dscp_entry->tc;
- color_in = dscp_entry->color;
- data += tc;
- mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
-
- /* Meter */
- color_meter = rte_meter_trtcm_color_aware_check(
- &data->trtcm,
- &mp[mp_id].profile,
- time,
- total_length,
- color_in);
-
- /* Stats */
- MTR_TRTCM_DATA_STATS_INC(data, color_meter);
-
- /* Police */
- drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
- color_policer =
- MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- rte_mbuf_sched_color_set(mbuf, (uint8_t)color_policer);
-
- return drop_mask;
-}
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-static int
-tm_cfg_check(struct rte_table_action_tm_config *tm)
-{
- if ((tm->n_subports_per_port == 0) ||
- (rte_is_power_of_2(tm->n_subports_per_port) == 0) ||
- (tm->n_subports_per_port > UINT16_MAX) ||
- (tm->n_pipes_per_subport == 0) ||
- (rte_is_power_of_2(tm->n_pipes_per_subport) == 0))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin tm_data {
- uint32_t queue_id;
- uint32_t reserved;
-} __rte_packed_end;
-
-static int
-tm_apply_check(struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- if ((p->subport_id >= cfg->n_subports_per_port) ||
- (p->pipe_id >= cfg->n_pipes_per_subport))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-tm_apply(struct tm_data *data,
- struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = tm_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- data->queue_id = p->subport_id <<
- (rte_ctz32(cfg->n_pipes_per_subport) + 4) |
- p->pipe_id << 4;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tm(struct rte_mbuf *mbuf,
- struct tm_data *data,
- struct dscp_table_data *dscp_table,
- uint32_t dscp)
-{
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- uint32_t queue_id = data->queue_id |
- dscp_entry->tc_queue;
- rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc,
- (uint8_t)dscp_entry->color);
-}
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-static int
-encap_valid(enum rte_table_action_encap_type encap)
-{
- switch (encap) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 1;
- default:
- return 0;
- }
-}
-
-static int
-encap_cfg_check(struct rte_table_action_encap_config *encap)
-{
- if ((encap->encap_mask == 0) ||
- (rte_popcount64(encap->encap_mask) != 1))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct encap_ether_data {
- struct rte_ether_hdr ether;
-};
-
-#define VLAN(pcp, dei, vid) \
- ((uint16_t)((((uint64_t)(pcp)) & 0x7LLU) << 13) | \
- ((((uint64_t)(dei)) & 0x1LLU) << 12) | \
- (((uint64_t)(vid)) & 0xFFFLLU)) \
-
-struct encap_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
-};
-
-struct encap_qinq_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
-};
-
-#define ETHER_TYPE_MPLS_UNICAST 0x8847
-
-#define ETHER_TYPE_MPLS_MULTICAST 0x8848
-
-#define MPLS(label, tc, s, ttl) \
- ((uint32_t)(((((uint64_t)(label)) & 0xFFFFFLLU) << 12) |\
- ((((uint64_t)(tc)) & 0x7LLU) << 9) | \
- ((((uint64_t)(s)) & 0x1LLU) << 8) | \
- (((uint64_t)(ttl)) & 0xFFLLU)))
-
-struct __rte_aligned(2) __rte_packed_begin encap_mpls_data {
- struct rte_ether_hdr ether;
- uint32_t mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
- uint32_t mpls_count;
-} __rte_packed_end;
-
-#define PPP_PROTOCOL_IP 0x0021
-
-struct pppoe_ppp_hdr {
- uint16_t ver_type_code;
- uint16_t session_id;
- uint16_t length;
- uint16_t protocol;
-};
-
-struct encap_pppoe_data {
- struct rte_ether_hdr ether;
- struct pppoe_ppp_hdr pppoe_ppp;
-};
-
-#define IP_PROTO_UDP 17
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_data {
- struct rte_ether_hdr ether;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_data {
- struct rte_ether_hdr ether;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_qinq_pppoe_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
- struct pppoe_ppp_hdr pppoe_ppp;
-} __rte_packed_end;
-
-static size_t
-encap_data_size(struct rte_table_action_encap_config *encap)
-{
- switch (encap->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- return sizeof(struct encap_ether_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- return sizeof(struct encap_vlan_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- return sizeof(struct encap_qinq_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- return sizeof(struct encap_mpls_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- return sizeof(struct encap_pppoe_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- if (encap->vxlan.ip_version)
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv4_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv4_data);
- else
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv6_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv6_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return sizeof(struct encap_qinq_pppoe_data);
-
- default:
- return 0;
- }
-}
-
-static int
-encap_apply_check(struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((encap_valid(p->type) == 0) ||
- ((cfg->encap_mask & (1LLU << p->type)) == 0))
- return -EINVAL;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- if ((p->mpls.mpls_count == 0) ||
- (p->mpls.mpls_count > RTE_TABLE_ACTION_MPLS_LABELS_MAX))
- return -EINVAL;
-
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-encap_ether_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_ether_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->ether.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->ether.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_vlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_vlan_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vlan.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vlan.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vlan.vlan.pcp,
- p->vlan.vlan.dei,
- p->vlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_qinq_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_QINQ);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_qinq_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->qinq_pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_mpls_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_mpls_data *d = data;
- uint16_t ethertype = (p->mpls.unicast) ?
- ETHER_TYPE_MPLS_UNICAST :
- ETHER_TYPE_MPLS_MULTICAST;
- uint32_t i;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->mpls.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->mpls.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- /* MPLS */
- for (i = 0; i < p->mpls.mpls_count - 1; i++)
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 0,
- p->mpls.mpls[i].ttl));
-
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 1,
- p->mpls.mpls[i].ttl));
-
- d->mpls_count = p->mpls.mpls_count;
- return 0;
-}
-
-static int
-encap_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->pppoe.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->pppoe.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_vxlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((p->vxlan.vxlan.vni > 0xFFFFFF) ||
- (cfg->vxlan.ip_version && (p->vxlan.ipv4.dscp > 0x3F)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.flow_label > 0xFFFFF)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.dscp > 0x3F)) ||
- (cfg->vxlan.vlan && (p->vxlan.vlan.vid > 0xFFF)))
- return -1;
-
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv4_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv4_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
- else
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv6_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv6_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
-}
-
-static int
-encap_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg,
- struct rte_table_action_common_config *common_cfg)
-{
- int status;
-
- /* Check input arguments */
- status = encap_apply_check(p, cfg);
- if (status)
- return status;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return encap_ether_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return encap_vlan_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return encap_qinq_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- return encap_mpls_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return encap_pppoe_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return encap_vxlan_apply(data, p, cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return encap_qinq_pppoe_apply(data, p);
-
- default:
- return -EINVAL;
- }
-}
-
-static __rte_always_inline uint16_t
-encap_vxlan_ipv4_checksum_update(uint16_t cksum0,
- uint16_t total_length)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Add total length (one's complement logic) */
- cksum1 += total_length;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void *
-encap(void *dst, const void *src, size_t n)
-{
- dst = ((uint8_t *) dst) - n;
- return rte_memcpy(dst, src, n);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap(struct rte_mbuf *mbuf,
- void *data,
- struct rte_table_action_encap_config *cfg,
- void *ip,
- uint16_t total_length,
- uint32_t ip_offset)
-{
- switch (cfg->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- encap(ip, data, sizeof(struct encap_ether_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_ether_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_ether_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- encap(ip, data, sizeof(struct encap_vlan_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_vlan_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_vlan_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- encap(ip, data, sizeof(struct encap_qinq_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- {
- struct encap_mpls_data *mpls = data;
- size_t size = sizeof(struct rte_ether_hdr) +
- mpls->mpls_count * 4;
-
- encap(ip, data, size);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) + size);
- mbuf->pkt_len = mbuf->data_len = total_length + size;
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- {
- struct encap_pppoe_data *pppoe =
- encap(ip, data, sizeof(struct encap_pppoe_data));
- pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- {
- struct encap_qinq_pppoe_data *qinq_pppoe =
- encap(ip, data, sizeof(struct encap_qinq_pppoe_data));
- qinq_pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- {
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv4_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv4(mbuf, data, cfg);
- else
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv6_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv6(mbuf, data, cfg);
- }
-
- default:
- break;
- }
-}
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-static int
-nat_cfg_check(struct rte_table_action_nat_config *nat)
-{
- if ((nat->proto != 0x06) &&
- (nat->proto != 0x11))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin nat_ipv4_data {
- uint32_t addr;
- uint16_t port;
-} __rte_packed_end;
-
-struct __rte_packed_begin nat_ipv6_data {
- struct rte_ipv6_addr addr;
- uint16_t port;
-} __rte_packed_end;
-
-static size_t
-nat_data_size(struct rte_table_action_nat_config *nat __rte_unused,
- struct rte_table_action_common_config *common)
-{
- int ip_version = common->ip_version;
-
- return (ip_version) ?
- sizeof(struct nat_ipv4_data) :
- sizeof(struct nat_ipv6_data);
-}
-
-static int
-nat_apply_check(struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- if ((p->ip_version && (cfg->ip_version == 0)) ||
- ((p->ip_version == 0) && cfg->ip_version))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-nat_apply(void *data,
- struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = nat_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- if (p->ip_version) {
- struct nat_ipv4_data *d = data;
-
- d->addr = rte_htonl(p->addr.ipv4);
- d->port = rte_htons(p->port);
- } else {
- struct nat_ipv6_data *d = data;
-
- d->addr = p->addr.ipv6;
- d->port = rte_htons(p->port);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_tcp_udp_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF) + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF) + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv6_tcp_udp_checksum_update(uint16_t cksum0,
- uint16_t *ip0,
- uint16_t *ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= ip0[0] + ip0[1] + ip0[2] + ip0[3] +
- ip0[4] + ip0[5] + ip0[6] + ip0[7] + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += ip1[0] + ip1[1] + ip1[2] + ip1[3] +
- ip1[4] + ip1[5] + ip1[6] + ip1[7] + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void
-pkt_ipv4_work_nat(struct rte_ipv4_hdr *ip,
- struct nat_ipv4_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->src_addr,
- data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->src_addr,
- data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->src_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->dst_addr,
- data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->dst_addr,
- data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->dst_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-static __rte_always_inline void
-pkt_ipv6_work_nat(struct rte_ipv6_hdr *ip,
- struct nat_ipv6_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- udp->src_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- udp->dst_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-static int
-ttl_cfg_check(struct rte_table_action_ttl_config *ttl)
-{
- if (ttl->drop == 0)
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin ttl_data {
- uint32_t n_packets;
-} __rte_packed_end;
-
-#define TTL_INIT(data, decrement) \
- ((data)->n_packets = (decrement) ? 1 : 0)
-
-#define TTL_DEC_GET(data) \
- ((uint8_t)((data)->n_packets & 1))
-
-#define TTL_STATS_RESET(data) \
- ((data)->n_packets = ((data)->n_packets & 1))
-
-#define TTL_STATS_READ(data) \
- ((data)->n_packets >> 1)
-
-#define TTL_STATS_ADD(data, value) \
- ((data)->n_packets = \
- (((((data)->n_packets >> 1) + (value)) << 1) | \
- ((data)->n_packets & 1)))
-
-static int
-ttl_apply(void *data,
- struct rte_table_action_ttl_params *p)
-{
- struct ttl_data *d = data;
-
- TTL_INIT(d, p->decrement);
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv4_work_ttl(struct rte_ipv4_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint16_t cksum = ip->hdr_checksum;
- uint8_t ttl = ip->time_to_live;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- cksum += ttl_diff;
- ttl -= ttl_diff;
-
- ip->hdr_checksum = cksum;
- ip->time_to_live = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv6_work_ttl(struct rte_ipv6_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint8_t ttl = ip->hop_limits;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- ttl -= ttl_diff;
-
- ip->hop_limits = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-static int
-stats_cfg_check(struct rte_table_action_stats_config *stats)
-{
- if ((stats->n_packets_enabled == 0) && (stats->n_bytes_enabled == 0))
- return -EINVAL;
-
- return 0;
-}
-
-struct __rte_packed_begin stats_data {
- uint64_t n_packets;
- uint64_t n_bytes;
-} __rte_packed_end;
-
-static int
-stats_apply(struct stats_data *data,
- struct rte_table_action_stats_params *p)
-{
- data->n_packets = p->n_packets;
- data->n_bytes = p->n_bytes;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_stats(struct stats_data *data,
- uint16_t total_length)
-{
- data->n_packets++;
- data->n_bytes += total_length;
-}
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-struct __rte_packed_begin time_data {
- uint64_t time;
-} __rte_packed_end;
-
-static int
-time_apply(struct time_data *data,
- struct rte_table_action_time_params *p)
-{
- data->time = p->time;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_time(struct time_data *data,
- uint64_t time)
-{
- data->time = time;
-}
-
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-
-#define CRYPTO_OP_MASK_CIPHER 0x1
-#define CRYPTO_OP_MASK_AUTH 0x2
-#define CRYPTO_OP_MASK_AEAD 0x4
-
-struct crypto_op_sym_iv_aad {
- struct rte_crypto_op op;
- struct rte_crypto_sym_op sym_op;
- union {
- struct {
- uint8_t cipher_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t auth_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- } cipher_auth;
-
- struct {
- uint8_t iv[RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t aad[RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX];
- } aead_iv_aad;
-
- } iv_aad;
-};
-
-struct __rte_packed_begin sym_crypto_data {
-
- union {
- struct {
-
- /** Length of cipher iv. */
- uint16_t cipher_iv_len;
-
- /** Offset from start of IP header to the cipher iv. */
- uint16_t cipher_iv_data_offset;
-
- /** Length of cipher iv to be updated in the mbuf. */
- uint16_t cipher_iv_update_len;
-
- /** Offset from start of IP header to the auth iv. */
- uint16_t auth_iv_data_offset;
-
- /** Length of auth iv in the mbuf. */
- uint16_t auth_iv_len;
-
- /** Length of auth iv to be updated in the mbuf. */
- uint16_t auth_iv_update_len;
-
- } cipher_auth;
- struct {
-
- /** Length of iv. */
- uint16_t iv_len;
-
- /** Offset from start of IP header to the aead iv. */
- uint16_t iv_data_offset;
-
- /** Length of iv to be updated in the mbuf. */
- uint16_t iv_update_len;
-
- /** Length of aad */
- uint16_t aad_len;
-
- /** Offset from start of IP header to the aad. */
- uint16_t aad_data_offset;
-
- /** Length of aad to updated in the mbuf. */
- uint16_t aad_update_len;
-
- } aead;
- };
-
- /** Offset from start of IP header to the data. */
- uint16_t data_offset;
-
- /** Digest length. */
- uint16_t digest_len;
-
- /** block size */
- uint16_t block_size;
-
- /** Mask of crypto operation */
- uint16_t op_mask;
-
- /** Session pointer. */
- struct rte_cryptodev_sym_session *session;
-
- /** Direction of crypto, encrypt or decrypt */
- uint16_t direction;
-
- /** Private data size to store cipher iv / aad. */
- uint8_t iv_aad_data[32];
-
-} __rte_packed_end;
-
-static int
-sym_crypto_cfg_check(struct rte_table_action_sym_crypto_config *cfg)
-{
- if (!rte_cryptodev_is_valid_dev(cfg->cryptodev_id))
- return -EINVAL;
- if (cfg->mp_create == NULL || cfg->mp_init == NULL)
- return -EINVAL;
-
- return 0;
-}
-
-static int
-get_block_size(const struct rte_crypto_sym_xform *xform, uint8_t cdev_id)
-{
- struct rte_cryptodev_info dev_info;
- const struct rte_cryptodev_capabilities *cap;
- uint32_t i;
-
- rte_cryptodev_info_get(cdev_id, &dev_info);
-
- for (i = 0; dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
- i++) {
- cap = &dev_info.capabilities[i];
-
- if (cap->sym.xform_type != xform->type)
- continue;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
- (cap->sym.cipher.algo == xform->cipher.algo))
- return cap->sym.cipher.block_size;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
- (cap->sym.aead.algo == xform->aead.algo))
- return cap->sym.aead.block_size;
-
- if (xform->type == RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED)
- break;
- }
-
- return -1;
-}
-
-static int
-sym_crypto_apply(struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- struct rte_table_action_sym_crypto_params *p)
-{
- const struct rte_crypto_cipher_xform *cipher_xform = NULL;
- const struct rte_crypto_auth_xform *auth_xform = NULL;
- const struct rte_crypto_aead_xform *aead_xform = NULL;
- struct rte_crypto_sym_xform *xform = p->xform;
- struct rte_cryptodev_sym_session *session;
- int ret;
-
- memset(data, 0, sizeof(*data));
-
- while (xform) {
- if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
- cipher_xform = &xform->cipher;
-
- if (cipher_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- if (cipher_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_CIPHER;
-
- data->cipher_auth.cipher_iv_len =
- cipher_xform->iv.length;
- data->cipher_auth.cipher_iv_data_offset = (uint16_t)
- p->cipher_auth.cipher_iv_update.offset;
- data->cipher_auth.cipher_iv_update_len = (uint16_t)
- p->cipher_auth.cipher_iv_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.cipher_iv.val,
- p->cipher_auth.cipher_iv.length);
-
- data->direction = cipher_xform->op;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
- auth_xform = &xform->auth;
- if (auth_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- data->op_mask |= CRYPTO_OP_MASK_AUTH;
-
- data->cipher_auth.auth_iv_len = auth_xform->iv.length;
- data->cipher_auth.auth_iv_data_offset = (uint16_t)
- p->cipher_auth.auth_iv_update.offset;
- data->cipher_auth.auth_iv_update_len = (uint16_t)
- p->cipher_auth.auth_iv_update.length;
- data->digest_len = auth_xform->digest_length;
-
- data->direction = (auth_xform->op ==
- RTE_CRYPTO_AUTH_OP_GENERATE) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
- aead_xform = &xform->aead;
-
- if ((aead_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX) || (
- aead_xform->aad_length >
- RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX))
- return -EINVAL;
- if (aead_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_AEAD;
-
- data->digest_len = aead_xform->digest_length;
- data->aead.iv_len = aead_xform->iv.length;
- data->aead.aad_len = aead_xform->aad_length;
-
- data->aead.iv_data_offset = (uint16_t)
- p->aead.iv_update.offset;
- data->aead.iv_update_len = (uint16_t)
- p->aead.iv_update.length;
- data->aead.aad_data_offset = (uint16_t)
- p->aead.aad_update.offset;
- data->aead.aad_update_len = (uint16_t)
- p->aead.aad_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->aead.iv.val,
- p->aead.iv.length);
-
- rte_memcpy(data->iv_aad_data + p->aead.iv.length,
- p->aead.aad.val,
- p->aead.aad.length);
-
- data->direction = (aead_xform->op ==
- RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
- } else
- return -EINVAL;
-
- xform = xform->next;
- }
-
- if (auth_xform && auth_xform->iv.length) {
- if (cipher_xform) {
- if (auth_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET +
- cipher_xform->iv.length)
- return -EINVAL;
-
- rte_memcpy(data->iv_aad_data + cipher_xform->iv.length,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- } else {
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- }
- }
-
- session = rte_cryptodev_sym_session_create(cfg->cryptodev_id,
- p->xform, cfg->mp_create);
- if (!session)
- return -ENOMEM;
-
- data->data_offset = (uint16_t)p->data_offset;
- data->session = session;
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_sym_crypto(struct rte_mbuf *mbuf, struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- uint16_t ip_offset)
-{
- struct crypto_op_sym_iv_aad *crypto_op = (struct crypto_op_sym_iv_aad *)
- RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->op_offset);
- struct rte_crypto_op *op = &crypto_op->op;
- struct rte_crypto_sym_op *sym = op->sym;
- uint32_t pkt_offset = sizeof(*mbuf) + mbuf->data_off;
- uint32_t payload_len = pkt_offset + mbuf->data_len - data->data_offset;
-
- op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
- op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
- op->phys_addr = rte_mbuf_iova_get(mbuf) + cfg->op_offset - sizeof(*mbuf);
- op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
- sym->m_src = mbuf;
- sym->m_dst = NULL;
- sym->session = data->session;
-
- /** pad the packet */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
- uint32_t append_len = RTE_ALIGN_CEIL(payload_len,
- data->block_size) - payload_len;
-
- if (unlikely(rte_pktmbuf_append(mbuf, append_len +
- data->digest_len) == NULL))
- return 1;
-
- payload_len += append_len;
- } else
- payload_len -= data->digest_len;
-
- if (data->op_mask & CRYPTO_OP_MASK_CIPHER) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.cipher_iv;
-
- sym->cipher.data.length = payload_len;
- sym->cipher.data.offset = data->data_offset - pkt_offset;
-
- if (data->cipher_auth.cipher_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.cipher_iv_data_offset
- + ip_offset);
-
- /** For encryption, update the pkt iv field, otherwise
- * update the iv_aad_field
- */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_update_len);
- else
- rte_memcpy(data->iv_aad_data, pkt_iv,
- data->cipher_auth.cipher_iv_update_len);
- }
-
- /** write iv */
- rte_memcpy(iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_len);
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AUTH) {
- /** authentication always start from IP header. */
- sym->auth.data.offset = ip_offset - pkt_offset;
- sym->auth.data.length = mbuf->data_len - sym->auth.data.offset -
- data->digest_len;
- sym->auth.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->auth.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
-
- if (data->cipher_auth.auth_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.auth_iv_data_offset
- + ip_offset);
- uint8_t *data_iv = data->iv_aad_data +
- data->cipher_auth.cipher_iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->cipher_auth.auth_iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->cipher_auth.auth_iv_update_len);
- }
-
- if (data->cipher_auth.auth_iv_len) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.auth_iv;
-
- rte_memcpy(iv, data->iv_aad_data +
- data->cipher_auth.cipher_iv_len,
- data->cipher_auth.auth_iv_len);
- }
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AEAD) {
- uint8_t *iv = crypto_op->iv_aad.aead_iv_aad.iv;
- uint8_t *aad = crypto_op->iv_aad.aead_iv_aad.aad;
-
- sym->aead.aad.data = aad;
- sym->aead.aad.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- aad - rte_pktmbuf_mtod(mbuf, uint8_t *));
- sym->aead.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->aead.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
- sym->aead.data.offset = data->data_offset - pkt_offset;
- sym->aead.data.length = payload_len;
-
- if (data->aead.iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.iv_data_offset + ip_offset);
- uint8_t *data_iv = data->iv_aad_data;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(iv, data->iv_aad_data, data->aead.iv_len);
-
- if (data->aead.aad_update_len) {
- uint8_t *pkt_aad = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.aad_data_offset + ip_offset);
- uint8_t *data_aad = data->iv_aad_data +
- data->aead.iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_aad, data_aad,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_aad, pkt_aad,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(aad, data->iv_aad_data + data->aead.iv_len,
- data->aead.aad_len);
- }
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-struct __rte_packed_begin tag_data {
- uint32_t tag;
-} __rte_packed_end;
-
-static int
-tag_apply(struct tag_data *data,
- struct rte_table_action_tag_params *p)
-{
- data->tag = p->tag;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tag(struct rte_mbuf *mbuf,
- struct tag_data *data)
-{
- mbuf->hash.fdir.hi = data->tag;
- mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-static __rte_always_inline void
-pkt4_work_tag(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct tag_data *data0,
- struct tag_data *data1,
- struct tag_data *data2,
- struct tag_data *data3)
-{
- mbuf0->hash.fdir.hi = data0->tag;
- mbuf1->hash.fdir.hi = data1->tag;
- mbuf2->hash.fdir.hi = data2->tag;
- mbuf3->hash.fdir.hi = data3->tag;
-
- mbuf0->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf1->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf2->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf3->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-struct __rte_packed_begin decap_data {
- uint16_t n;
-} __rte_packed_end;
-
-static int
-decap_apply(struct decap_data *data,
- struct rte_table_action_decap_params *p)
-{
- data->n = p->n;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_decap(struct rte_mbuf *mbuf,
- struct decap_data *data)
-{
- uint16_t data_off = mbuf->data_off;
- uint16_t data_len = mbuf->data_len;
- uint32_t pkt_len = mbuf->pkt_len;
- uint16_t n = data->n;
-
- mbuf->data_off = data_off + n;
- mbuf->data_len = data_len - n;
- mbuf->pkt_len = pkt_len - n;
-}
-
-static __rte_always_inline void
-pkt4_work_decap(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct decap_data *data0,
- struct decap_data *data1,
- struct decap_data *data2,
- struct decap_data *data3)
-{
- uint16_t data_off0 = mbuf0->data_off;
- uint16_t data_len0 = mbuf0->data_len;
- uint32_t pkt_len0 = mbuf0->pkt_len;
-
- uint16_t data_off1 = mbuf1->data_off;
- uint16_t data_len1 = mbuf1->data_len;
- uint32_t pkt_len1 = mbuf1->pkt_len;
-
- uint16_t data_off2 = mbuf2->data_off;
- uint16_t data_len2 = mbuf2->data_len;
- uint32_t pkt_len2 = mbuf2->pkt_len;
-
- uint16_t data_off3 = mbuf3->data_off;
- uint16_t data_len3 = mbuf3->data_len;
- uint32_t pkt_len3 = mbuf3->pkt_len;
-
- uint16_t n0 = data0->n;
- uint16_t n1 = data1->n;
- uint16_t n2 = data2->n;
- uint16_t n3 = data3->n;
-
- mbuf0->data_off = data_off0 + n0;
- mbuf0->data_len = data_len0 - n0;
- mbuf0->pkt_len = pkt_len0 - n0;
-
- mbuf1->data_off = data_off1 + n1;
- mbuf1->data_len = data_len1 - n1;
- mbuf1->pkt_len = pkt_len1 - n1;
-
- mbuf2->data_off = data_off2 + n2;
- mbuf2->data_len = data_len2 - n2;
- mbuf2->pkt_len = pkt_len2 - n2;
-
- mbuf3->data_off = data_off3 + n3;
- mbuf3->data_len = data_len3 - n3;
- mbuf3->pkt_len = pkt_len3 - n3;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- case RTE_TABLE_ACTION_LB:
- case RTE_TABLE_ACTION_MTR:
- case RTE_TABLE_ACTION_TM:
- case RTE_TABLE_ACTION_ENCAP:
- case RTE_TABLE_ACTION_NAT:
- case RTE_TABLE_ACTION_TTL:
- case RTE_TABLE_ACTION_STATS:
- case RTE_TABLE_ACTION_TIME:
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- case RTE_TABLE_ACTION_TAG:
- case RTE_TABLE_ACTION_DECAP:
- return 1;
- default:
- return 0;
- }
-}
-
-
-#define RTE_TABLE_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-static size_t
-action_cfg_size(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct rte_table_action_lb_config);
- case RTE_TABLE_ACTION_MTR:
- return sizeof(struct rte_table_action_mtr_config);
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct rte_table_action_tm_config);
- case RTE_TABLE_ACTION_ENCAP:
- return sizeof(struct rte_table_action_encap_config);
- case RTE_TABLE_ACTION_NAT:
- return sizeof(struct rte_table_action_nat_config);
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct rte_table_action_ttl_config);
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct rte_table_action_stats_config);
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sizeof(struct rte_table_action_sym_crypto_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_table_action_type type)
-{
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- return &ap_config->lb;
-
- case RTE_TABLE_ACTION_MTR:
- return &ap_config->mtr;
-
- case RTE_TABLE_ACTION_TM:
- return &ap_config->tm;
-
- case RTE_TABLE_ACTION_ENCAP:
- return &ap_config->encap;
-
- case RTE_TABLE_ACTION_NAT:
- return &ap_config->nat;
-
- case RTE_TABLE_ACTION_TTL:
- return &ap_config->ttl;
-
- case RTE_TABLE_ACTION_STATS:
- return &ap_config->stats;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return &ap_config->sym_crypto;
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_table_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_TABLE_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_table_action_type action,
- struct ap_config *ap_config)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- return sizeof(struct fwd_data);
-
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct lb_data);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_data_size(&ap_config->mtr);
-
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct tm_data);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_data_size(&ap_config->encap);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_data_size(&ap_config->nat,
- &ap_config->common);
-
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct ttl_data);
-
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct stats_data);
-
- case RTE_TABLE_ACTION_TIME:
- return sizeof(struct time_data);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return (sizeof(struct sym_crypto_data));
-
- case RTE_TABLE_ACTION_TAG:
- return sizeof(struct tag_data);
-
- case RTE_TABLE_ACTION_DECAP:
- return sizeof(struct decap_data);
-
- default:
- return 0;
- }
-}
-
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_TABLE_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_table_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_table_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_create, 18.05)
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common)
-{
- struct rte_table_action_profile *ap;
-
- /* Check input arguments */
- if (common == NULL)
- return NULL;
-
- /* Memory allocation */
- ap = calloc(1, sizeof(struct rte_table_action_profile));
- if (ap == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&ap->cfg.common, common, sizeof(*common));
-
- return ap;
-}
-
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_action_register, 18.05)
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_MTR:
- status = mtr_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TM:
- status = tm_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_ENCAP:
- status = encap_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_NAT:
- status = nat_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TTL:
- status = ttl_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_STATS:
- status = stats_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- status = sym_crypto_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_freeze, 18.05)
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- profile->cfg.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_free, 18.05)
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-#define METER_PROFILES_MAX 32
-
-struct rte_table_action {
- struct ap_config cfg;
- struct ap_data data;
- struct dscp_table_data dscp_table;
- struct meter_profile_data mp[METER_PROFILES_MAX];
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_create, 18.05)
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_table_action *action;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- action = rte_zmalloc_socket(NULL,
- sizeof(struct rte_table_action),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- return action;
-}
-
-static __rte_always_inline void *
-action_data_get(void *data,
- struct rte_table_action *action,
- enum rte_table_action_type type)
-{
- size_t offset = action->data.offset[type];
- uint8_t *data_bytes = data;
-
- return &data_bytes[offset];
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_apply, 18.05)
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (data == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(data, action, type);
-
- switch (type) {
- case RTE_TABLE_ACTION_FWD:
- return fwd_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_apply(action_data,
- action_params,
- &action->cfg.mtr,
- action->mp,
- RTE_DIM(action->mp));
-
- case RTE_TABLE_ACTION_TM:
- return tm_apply(action_data,
- action_params,
- &action->cfg.tm);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_apply(action_data,
- action_params,
- &action->cfg.encap,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_apply(action_data,
- action_params,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_TTL:
- return ttl_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_STATS:
- return stats_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_TIME:
- return time_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sym_crypto_apply(action_data,
- &action->cfg.sym_crypto,
- action_params);
-
- case RTE_TABLE_ACTION_TAG:
- return tag_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_DECAP:
- return decap_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_dscp_table_update, 18.05)
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table)
-{
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TM))) == 0) ||
- (dscp_mask == 0) ||
- (table == NULL))
- return -EINVAL;
-
- for (i = 0; i < RTE_DIM(table->entry); i++) {
- struct dscp_table_entry_data *data =
- &action->dscp_table.entry[i];
- struct rte_table_action_dscp_table_entry *entry =
- &table->entry[i];
-
- if ((dscp_mask & (1LLU << i)) == 0)
- continue;
-
- data->color = entry->color;
- data->tc = entry->tc_id;
- data->tc_queue = entry->tc_queue_id;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_add, 18.05)
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct meter_profile_data *mp_data;
- uint32_t status;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (profile == NULL))
- return -EINVAL;
-
- if (profile->alg != RTE_TABLE_ACTION_METER_TRTCM)
- return -ENOTSUP;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (mp_data)
- return -EEXIST;
-
- mp_data = meter_profile_data_find_unused(action->mp,
- RTE_DIM(action->mp));
- if (!mp_data)
- return -ENOSPC;
-
- /* Install new profile */
- status = rte_meter_trtcm_profile_config(&mp_data->profile,
- &profile->trtcm);
- if (status)
- return status;
-
- mp_data->profile_id = meter_profile_id;
- mp_data->valid = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_delete, 18.05)
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id)
-{
- struct meter_profile_data *mp_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0))
- return -EINVAL;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (!mp_data)
- return 0;
-
- /* Uninstall profile */
- mp_data->valid = 0;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_read, 18.05)
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct mtr_trtcm_data *mtr_data;
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (data == NULL) ||
- (tc_mask > RTE_LEN2MASK(action->cfg.mtr.n_tc, uint32_t)))
- return -EINVAL;
-
- mtr_data = action_data_get(data, action, RTE_TABLE_ACTION_MTR);
-
- /* Read */
- if (stats) {
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_counters_tc *dst =
- &stats->stats[i];
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- dst->n_packets[RTE_COLOR_GREEN] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_GREEN);
-
- dst->n_packets[RTE_COLOR_YELLOW] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_YELLOW);
-
- dst->n_packets[RTE_COLOR_RED] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_RED);
-
- dst->n_packets_valid = 1;
- dst->n_bytes_valid = 0;
- }
-
- stats->tc_mask = tc_mask;
- }
-
- /* Clear */
- if (clear)
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_GREEN);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_YELLOW);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_RED);
- }
-
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_ttl_read, 18.05)
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct ttl_data *ttl_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TTL)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- ttl_data = action_data_get(data, action, RTE_TABLE_ACTION_TTL);
-
- /* Read */
- if (stats)
- stats->n_packets = TTL_STATS_READ(ttl_data);
-
- /* Clear */
- if (clear)
- TTL_STATS_RESET(ttl_data);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_stats_read, 18.05)
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct stats_data *stats_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_STATS)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- stats_data = action_data_get(data, action,
- RTE_TABLE_ACTION_STATS);
-
- /* Read */
- if (stats) {
- stats->n_packets = stats_data->n_packets;
- stats->n_bytes = stats_data->n_bytes;
- stats->n_packets_valid = 1;
- stats->n_bytes_valid = 1;
- }
-
- /* Clear */
- if (clear) {
- stats_data->n_packets = 0;
- stats_data->n_bytes = 0;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_time_read, 18.05)
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp)
-{
- struct time_data *time_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TIME)) == 0) ||
- (data == NULL) ||
- (timestamp == NULL))
- return -EINVAL;
-
- time_data = action_data_get(data, action, RTE_TABLE_ACTION_TIME);
-
- /* Read */
- *timestamp = time_data->time;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_crypto_sym_session_get, 18.11)
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data)
-{
- struct sym_crypto_data *sym_crypto_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) == 0) ||
- (data == NULL))
- return NULL;
-
- sym_crypto_data = action_data_get(data, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- return sym_crypto_data->session;
-}
-
-static __rte_always_inline uint64_t
-pkt_work(struct rte_mbuf *mbuf,
- struct rte_pipeline_table_entry *table_entry,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask = 0;
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ip_offset);
-
- uint32_t dscp;
- uint16_t total_length;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr = ip;
-
- dscp = hdr->type_of_service >> 2;
- total_length = rte_ntohs(hdr->total_length);
- } else {
- struct rte_ipv6_hdr *hdr = ip;
-
- dscp = (rte_ntohl(hdr->vtc_flow) & 0x0F600000) >> 18;
- total_length = rte_ntohs(hdr->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf,
- data,
- &cfg->lb);
- }
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask |= pkt_work_mtr(mbuf,
- data,
- &action->dscp_table,
- action->mp,
- time,
- dscp,
- total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf,
- data,
- &action->dscp_table,
- dscp);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt_work_decap(mbuf, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf,
- data,
- &cfg->encap,
- ip,
- total_length,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version)
- pkt_ipv4_work_nat(ip, data, &cfg->nat);
- else
- pkt_ipv6_work_nat(ip, data, &cfg->nat);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version)
- drop_mask |= pkt_ipv4_work_ttl(ip, data);
- else
- drop_mask |= pkt_ipv6_work_ttl(ip, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data, total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data = action_data_get(table_entry, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask |= pkt_work_sym_crypto(mbuf, data, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt_work_tag(mbuf, data);
- }
-
- return drop_mask;
-}
-
-static __rte_always_inline uint64_t
-pkt4_work(struct rte_mbuf **mbufs,
- struct rte_pipeline_table_entry **table_entries,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask0 = 0;
- uint64_t drop_mask1 = 0;
- uint64_t drop_mask2 = 0;
- uint64_t drop_mask3 = 0;
-
- struct rte_mbuf *mbuf0 = mbufs[0];
- struct rte_mbuf *mbuf1 = mbufs[1];
- struct rte_mbuf *mbuf2 = mbufs[2];
- struct rte_mbuf *mbuf3 = mbufs[3];
-
- struct rte_pipeline_table_entry *table_entry0 = table_entries[0];
- struct rte_pipeline_table_entry *table_entry1 = table_entries[1];
- struct rte_pipeline_table_entry *table_entry2 = table_entries[2];
- struct rte_pipeline_table_entry *table_entry3 = table_entries[3];
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip0 = RTE_MBUF_METADATA_UINT32_PTR(mbuf0, ip_offset);
- void *ip1 = RTE_MBUF_METADATA_UINT32_PTR(mbuf1, ip_offset);
- void *ip2 = RTE_MBUF_METADATA_UINT32_PTR(mbuf2, ip_offset);
- void *ip3 = RTE_MBUF_METADATA_UINT32_PTR(mbuf3, ip_offset);
-
- uint32_t dscp0, dscp1, dscp2, dscp3;
- uint16_t total_length0, total_length1, total_length2, total_length3;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr0 = ip0;
- struct rte_ipv4_hdr *hdr1 = ip1;
- struct rte_ipv4_hdr *hdr2 = ip2;
- struct rte_ipv4_hdr *hdr3 = ip3;
-
- dscp0 = hdr0->type_of_service >> 2;
- dscp1 = hdr1->type_of_service >> 2;
- dscp2 = hdr2->type_of_service >> 2;
- dscp3 = hdr3->type_of_service >> 2;
-
- total_length0 = rte_ntohs(hdr0->total_length);
- total_length1 = rte_ntohs(hdr1->total_length);
- total_length2 = rte_ntohs(hdr2->total_length);
- total_length3 = rte_ntohs(hdr3->total_length);
- } else {
- struct rte_ipv6_hdr *hdr0 = ip0;
- struct rte_ipv6_hdr *hdr1 = ip1;
- struct rte_ipv6_hdr *hdr2 = ip2;
- struct rte_ipv6_hdr *hdr3 = ip3;
-
- dscp0 = (rte_ntohl(hdr0->vtc_flow) & 0x0F600000) >> 18;
- dscp1 = (rte_ntohl(hdr1->vtc_flow) & 0x0F600000) >> 18;
- dscp2 = (rte_ntohl(hdr2->vtc_flow) & 0x0F600000) >> 18;
- dscp3 = (rte_ntohl(hdr3->vtc_flow) & 0x0F600000) >> 18;
-
- total_length0 = rte_ntohs(hdr0->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length1 = rte_ntohs(hdr1->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length2 = rte_ntohs(hdr2->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length3 = rte_ntohs(hdr3->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_LB);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_LB);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_LB);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf0,
- data0,
- &cfg->lb);
-
- pkt_work_lb(mbuf1,
- data1,
- &cfg->lb);
-
- pkt_work_lb(mbuf2,
- data2,
- &cfg->lb);
-
- pkt_work_lb(mbuf3,
- data3,
- &cfg->lb);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_MTR);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_MTR);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_MTR);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask0 |= pkt_work_mtr(mbuf0,
- data0,
- &action->dscp_table,
- action->mp,
- time,
- dscp0,
- total_length0);
-
- drop_mask1 |= pkt_work_mtr(mbuf1,
- data1,
- &action->dscp_table,
- action->mp,
- time,
- dscp1,
- total_length1);
-
- drop_mask2 |= pkt_work_mtr(mbuf2,
- data2,
- &action->dscp_table,
- action->mp,
- time,
- dscp2,
- total_length2);
-
- drop_mask3 |= pkt_work_mtr(mbuf3,
- data3,
- &action->dscp_table,
- action->mp,
- time,
- dscp3,
- total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TM);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TM);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TM);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf0,
- data0,
- &action->dscp_table,
- dscp0);
-
- pkt_work_tm(mbuf1,
- data1,
- &action->dscp_table,
- dscp1);
-
- pkt_work_tm(mbuf2,
- data2,
- &action->dscp_table,
- dscp2);
-
- pkt_work_tm(mbuf3,
- data3,
- &action->dscp_table,
- dscp3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt4_work_decap(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_ENCAP);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_ENCAP);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_ENCAP);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf0,
- data0,
- &cfg->encap,
- ip0,
- total_length0,
- ip_offset);
-
- pkt_work_encap(mbuf1,
- data1,
- &cfg->encap,
- ip1,
- total_length1,
- ip_offset);
-
- pkt_work_encap(mbuf2,
- data2,
- &cfg->encap,
- ip2,
- total_length2,
- ip_offset);
-
- pkt_work_encap(mbuf3,
- data3,
- &cfg->encap,
- ip3,
- total_length3,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_NAT);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_NAT);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_NAT);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version) {
- pkt_ipv4_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv4_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv4_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv4_work_nat(ip3, data3, &cfg->nat);
- } else {
- pkt_ipv6_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv6_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv6_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv6_work_nat(ip3, data3, &cfg->nat);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TTL);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TTL);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TTL);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version) {
- drop_mask0 |= pkt_ipv4_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv4_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv4_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv4_work_ttl(ip3, data3);
- } else {
- drop_mask0 |= pkt_ipv6_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv6_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv6_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv6_work_ttl(ip3, data3);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_STATS);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_STATS);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_STATS);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data0, total_length0);
- pkt_work_stats(data1, total_length1);
- pkt_work_stats(data2, total_length2);
- pkt_work_stats(data3, total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TIME);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TIME);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TIME);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data0, time);
- pkt_work_time(data1, time);
- pkt_work_time(data2, time);
- pkt_work_time(data3, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data0 = action_data_get(table_entry0, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data1 = action_data_get(table_entry1, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data2 = action_data_get(table_entry2, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data3 = action_data_get(table_entry3, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask0 |= pkt_work_sym_crypto(mbuf0, data0, &cfg->sym_crypto,
- ip_offset);
- drop_mask1 |= pkt_work_sym_crypto(mbuf1, data1, &cfg->sym_crypto,
- ip_offset);
- drop_mask2 |= pkt_work_sym_crypto(mbuf2, data2, &cfg->sym_crypto,
- ip_offset);
- drop_mask3 |= pkt_work_sym_crypto(mbuf3, data3, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt4_work_tag(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- return drop_mask0 |
- (drop_mask1 << 1) |
- (drop_mask2 << 2) |
- (drop_mask3 << 3);
-}
-
-static __rte_always_inline int
-ah(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t pkts_drop_mask = 0;
- uint64_t time = 0;
-
- if (cfg->action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TIME)))
- time = rte_rdtsc();
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {
- uint64_t drop_mask;
-
- drop_mask = pkt4_work(&pkts[i],
- &entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
-
- for ( ; i < n_pkts; i++) {
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[i],
- entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
- } else
- for ( ; pkts_mask; ) {
- uint32_t pos = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pos;
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[pos],
- entries[pos],
- time,
- action,
- cfg);
-
- pkts_mask &= ~pkt_mask;
- pkts_drop_mask |= drop_mask << pos;
- }
-
- rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
-
- return 0;
-}
-
-static int
-ah_default(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg)
-{
- struct rte_table_action *action = arg;
-
- return ah(p,
- pkts,
- pkts_mask,
- entries,
- action,
- &action->cfg);
-}
-
-static rte_pipeline_table_action_handler_hit
-ah_selector(struct rte_table_action *action)
-{
- if (action->cfg.action_mask == (1LLU << RTE_TABLE_ACTION_FWD))
- return NULL;
-
- return ah_default;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_table_params_get, 18.05)
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params)
-{
- rte_pipeline_table_action_handler_hit f_action_hit;
- uint32_t total_size;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action_hit = ah_selector(action);
- total_size = rte_align32pow2(action->data.total_size);
-
- /* Fill in params */
- params->f_action_hit = f_action_hit;
- params->f_action_miss = NULL;
- params->arg_ah = (f_action_hit) ? action : NULL;
- params->action_data_size = total_size -
- sizeof(struct rte_pipeline_table_entry);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_free, 18.05)
-int
-rte_table_action_free(struct rte_table_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_table_action.h b/lib/pipeline/rte_table_action.h
deleted file mode 100644
index 47a7bdfc01..0000000000
--- a/lib/pipeline/rte_table_action.h
+++ /dev/null
@@ -1,1137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_ACTION_H__
-#define __INCLUDE_RTE_TABLE_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Table Actions
- *
- * This API provides a common set of actions for pipeline tables to speed up
- * application development.
- *
- * Each match-action rule added to a pipeline table has associated data that
- * stores the action context. This data is input to the table action handler
- * called for every input packet that hits the rule as part of the table lookup
- * during the pipeline execution. The pipeline library allows the user to define
- * his own table actions by providing customized table action handlers (table
- * lookup) and complete freedom of setting the rules and their data (table rule
- * add/delete). While the user can still follow this process, this API is
- * intended to provide a quicker development alternative for a set of predefined
- * actions.
- *
- * The typical steps to use this API are:
- * - Define a table action profile. This is a configuration template that can
- * potentially be shared by multiple tables from the same or different
- * pipelines, with different tables from the same pipeline likely to use
- * different action profiles. For every table using a given action profile,
- * the profile defines the set of actions and the action configuration to be
- * implemented for all the table rules. API functions:
- * rte_table_action_profile_create(),
- * rte_table_action_profile_action_register(),
- * rte_table_action_profile_freeze().
- *
- * - Instantiate the table action profile to create table action objects. Each
- * pipeline table has its own table action object. API functions:
- * rte_table_action_create().
- *
- * - Use the table action object to generate the pipeline table action handlers
- * (invoked by the pipeline table lookup operation). API functions:
- * rte_table_action_table_params_get().
- *
- * - Use the table action object to generate the rule data (for the pipeline
- * table rule add operation) based on given action parameters. API functions:
- * rte_table_action_apply().
- *
- * - Use the table action object to read action data (e.g. stats counters) for
- * any given rule. API functions: rte_table_action_XYZ_read().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_ether.h>
-#include <rte_ip6.h>
-#include <rte_meter.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Table actions. */
-enum rte_table_action_type {
- /** Forward to next pipeline table, output port or drop. */
- RTE_TABLE_ACTION_FWD = 0,
-
- /** Load balance. */
- RTE_TABLE_ACTION_LB,
-
- /** Traffic Metering and Policing. */
- RTE_TABLE_ACTION_MTR,
-
- /** Traffic Management. */
- RTE_TABLE_ACTION_TM,
-
- /** Packet encapsulations. */
- RTE_TABLE_ACTION_ENCAP,
-
- /** Network Address Translation (NAT). */
- RTE_TABLE_ACTION_NAT,
-
- /** Time to Live (TTL) update. */
- RTE_TABLE_ACTION_TTL,
-
- /** Statistics. */
- RTE_TABLE_ACTION_STATS,
-
- /** Timestamp. */
- RTE_TABLE_ACTION_TIME,
-
- /** Crypto. */
- RTE_TABLE_ACTION_SYM_CRYPTO,
-
- /** Tag. */
- RTE_TABLE_ACTION_TAG,
-
- /** Packet decapsulations. */
- RTE_TABLE_ACTION_DECAP,
-};
-
-/** Common action configuration (per table action profile). */
-struct rte_table_action_common_config {
- /** Input packet Internet Protocol (IP) version. Non-zero for IPv4, zero
- * for IPv6.
- */
- int ip_version;
-
- /** IP header offset within the input packet buffer. Offset 0 points to
- * the first byte of the MBUF structure.
- */
- uint32_t ip_offset;
-};
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-/** Forward action parameters (per table rule). */
-struct rte_table_action_fwd_params {
- /** Forward action. */
- enum rte_pipeline_action action;
-
- /** Pipeline table ID or output port ID. */
- uint32_t id;
-};
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_TABLE_ACTION_LB_TABLE_SIZE 8
-
-/** Load balance action configuration (per table action profile). */
-struct rte_table_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask (*key_size* bytes are valid). */
- uint8_t key_mask[RTE_TABLE_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Output value offset within the input packet buffer. Offset 0 points
- * to the first byte of the MBUF structure.
- */
- uint32_t out_offset;
-};
-
-/** Load balance action parameters (per table rule). */
-struct rte_table_action_lb_params {
- /** Table defining the output values and their weights. The weights are
- * set in 1/RTE_TABLE_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_TABLE_ACTION_LB_TABLE_SIZE to a given output value
- * (0 <= N <= RTE_TABLE_ACTION_LB_TABLE_SIZE), the same output value
- * needs to show up exactly N times in this table.
- */
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-/** Max number of traffic classes (TCs). */
-#define RTE_TABLE_ACTION_TC_MAX 16
-
-/** Max number of queues per traffic class. */
-#define RTE_TABLE_ACTION_TC_QUEUE_MAX 16
-
-/** Differentiated Services Code Point (DSCP) translation table entry. */
-struct rte_table_action_dscp_table_entry {
- /** Traffic class. Used by the meter or the traffic management actions.
- * Has to be strictly smaller than *RTE_TABLE_ACTION_TC_MAX*. Traffic
- * class 0 is the highest priority.
- */
- uint32_t tc_id;
-
- /** Traffic class queue. Used by the traffic management action. Has to
- * be strictly smaller than *RTE_TABLE_ACTION_TC_QUEUE_MAX*.
- */
- uint32_t tc_queue_id;
-
- /** Packet color. Used by the meter action as the packet input color
- * for the color aware mode of the traffic metering algorithm.
- */
- enum rte_color color;
-};
-
-/** DSCP translation table. */
-struct rte_table_action_dscp_table {
- /** Array of DSCP table entries */
- struct rte_table_action_dscp_table_entry entry[64];
-};
-
-/** Supported traffic metering algorithms. */
-enum rte_table_action_meter_algorithm {
- /** Single Rate Three Color Marker (srTCM) - IETF RFC 2697. */
- RTE_TABLE_ACTION_METER_SRTCM,
-
- /** Two Rate Three Color Marker (trTCM) - IETF RFC 2698. */
- RTE_TABLE_ACTION_METER_TRTCM,
-};
-
-/** Traffic metering profile (configuration template). */
-struct rte_table_action_meter_profile {
- /** Traffic metering algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- union {
- /** Only valid when *alg* is set to srTCM - IETF RFC 2697. */
- struct rte_meter_srtcm_params srtcm;
-
- /** Only valid when *alg* is set to trTCM - IETF RFC 2698. */
- struct rte_meter_trtcm_params trtcm;
- };
-};
-
-/** Policer actions. */
-enum rte_table_action_policer {
- /** Recolor the packet as green. */
- RTE_TABLE_ACTION_POLICER_COLOR_GREEN = 0,
-
- /** Recolor the packet as yellow. */
- RTE_TABLE_ACTION_POLICER_COLOR_YELLOW,
-
- /** Recolor the packet as red. */
- RTE_TABLE_ACTION_POLICER_COLOR_RED,
-
- /** Drop the packet. */
- RTE_TABLE_ACTION_POLICER_DROP,
-
- /** Number of policer actions. */
- RTE_TABLE_ACTION_POLICER_MAX
-};
-
-/** Meter action configuration per traffic class. */
-struct rte_table_action_mtr_tc_params {
- /** Meter profile ID. */
- uint32_t meter_profile_id;
-
- /** Policer actions. */
- enum rte_table_action_policer policer[RTE_COLORS];
-};
-
-/** Meter action statistics counters per traffic class. */
-struct rte_table_action_mtr_counters_tc {
- /** Number of packets per color at the output of the traffic metering
- * and before the policer actions are executed. Only valid when
- * *n_packets_valid* is non-zero.
- */
- uint64_t n_packets[RTE_COLORS];
-
- /** Number of packet bytes per color at the output of the traffic
- * metering and before the policer actions are executed. Only valid when
- * *n_bytes_valid* is non-zero.
- */
- uint64_t n_bytes[RTE_COLORS];
-
- /** When non-zero, the *n_packets* field is valid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid. */
- int n_bytes_valid;
-};
-
-/** Meter action configuration (per table action profile). */
-struct rte_table_action_mtr_config {
- /** Meter algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- /** Number of traffic classes. Each traffic class has its own traffic
- * meter and policer instances. Needs to be equal to either 1 or to
- * *RTE_TABLE_ACTION_TC_MAX*.
- */
- uint32_t n_tc;
-
- /** When non-zero, the *n_packets* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_bytes_enabled;
-};
-
-/** Meter action parameters (per table rule). */
-struct rte_table_action_mtr_params {
- /** Traffic meter and policer parameters for each of the *tc_mask*
- * traffic classes.
- */
- struct rte_table_action_mtr_tc_params mtr[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/** Meter action statistics counters (per table rule). */
-struct rte_table_action_mtr_counters {
- /** Stats counters for each of the *tc_mask* traffic classes. */
- struct rte_table_action_mtr_counters_tc stats[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-/** Traffic management action configuration (per table action profile). */
-struct rte_table_action_tm_config {
- /** Number of subports per port. */
- uint32_t n_subports_per_port;
-
- /** Number of pipes per subport. */
- uint32_t n_pipes_per_subport;
-};
-
-/** Traffic management action parameters (per table rule). */
-struct rte_table_action_tm_params {
- /** Subport ID. */
- uint32_t subport_id;
-
- /** Pipe ID. */
- uint32_t pipe_id;
-};
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-/** Supported packet encapsulation types. */
-enum rte_table_action_encap_type {
- /** IP -> { Ether | IP } */
- RTE_TABLE_ACTION_ENCAP_ETHER = 0,
-
- /** IP -> { Ether | VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_VLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ,
-
- /** IP -> { Ether | MPLS | IP } */
- RTE_TABLE_ACTION_ENCAP_MPLS,
-
- /** IP -> { Ether | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_PPPOE,
-
- /** Ether -> { Ether | IP | UDP | VXLAN | Ether }
- * Ether -> { Ether | VLAN | IP | UDP | VXLAN | Ether }
- */
- RTE_TABLE_ACTION_ENCAP_VXLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE,
-};
-
-/** Pre-computed Ethernet header fields for encapsulation action. */
-struct rte_table_action_ether_hdr {
- struct rte_ether_addr da; /**< Destination address. */
- struct rte_ether_addr sa; /**< Source address. */
-};
-
-/** Pre-computed VLAN header fields for encapsulation action. */
-struct rte_table_action_vlan_hdr {
- uint8_t pcp; /**< Priority Code Point (PCP). */
- uint8_t dei; /**< Drop Eligibility Indicator (DEI). */
- uint16_t vid; /**< VLAN Identifier (VID). */
-};
-
-/** Pre-computed MPLS header fields for encapsulation action. */
-struct rte_table_action_mpls_hdr {
- uint32_t label; /**< Label. */
- uint8_t tc; /**< Traffic Class (TC). */
- uint8_t ttl; /**< Time to Live (TTL). */
-};
-
-/** Pre-computed PPPoE header fields for encapsulation action. */
-struct rte_table_action_pppoe_hdr {
- uint16_t session_id; /**< Session ID. */
-};
-
-/** Pre-computed IPv4 header fields for encapsulation action. */
-struct rte_table_action_ipv4_header {
- uint32_t sa; /**< Source address. */
- uint32_t da; /**< Destination address. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t ttl; /**< Time To Live (TTL). */
-};
-
-/** Pre-computed IPv6 header fields for encapsulation action. */
-struct rte_table_action_ipv6_header {
- struct rte_ipv6_addr sa; /**< Source address. */
- struct rte_ipv6_addr da; /**< Destination address. */
- uint32_t flow_label; /**< Flow label. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t hop_limit; /**< Hop Limit (HL). */
-};
-
-/** Pre-computed UDP header fields for encapsulation action. */
-struct rte_table_action_udp_header {
- uint16_t sp; /**< Source port. */
- uint16_t dp; /**< Destination port. */
-};
-
-/** Pre-computed VXLAN header fields for encapsulation action. */
-struct rte_table_action_vxlan_hdr {
- uint32_t vni; /**< VXLAN Network Identifier (VNI). */
-};
-
-/** Ether encap parameters. */
-struct rte_table_action_encap_ether_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
-};
-
-/** VLAN encap parameters. */
-struct rte_table_action_encap_vlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-};
-
-/** QinQ encap parameters. */
-struct rte_table_action_encap_qinq_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
-};
-
-/** Max number of MPLS labels per output packet for MPLS encapsulation. */
-#ifndef RTE_TABLE_ACTION_MPLS_LABELS_MAX
-#define RTE_TABLE_ACTION_MPLS_LABELS_MAX 4
-#endif
-
-/** MPLS encap parameters. */
-struct rte_table_action_encap_mpls_params {
- /** Ethernet header. */
- struct rte_table_action_ether_hdr ether;
-
- /** MPLS header. */
- struct rte_table_action_mpls_hdr mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
-
- /** Number of MPLS labels in MPLS header. */
- uint32_t mpls_count;
-
- /** Non-zero for MPLS unicast, zero for MPLS multicast. */
- int unicast;
-};
-
-/** PPPoE encap parameters. */
-struct rte_table_action_encap_pppoe_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** VXLAN encap parameters. */
-struct rte_table_action_encap_vxlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-
- union {
- struct rte_table_action_ipv4_header ipv4; /**< IPv4 header. */
- struct rte_table_action_ipv6_header ipv6; /**< IPv6 header. */
- };
-
- struct rte_table_action_udp_header udp; /**< UDP header. */
- struct rte_table_action_vxlan_hdr vxlan; /**< VXLAN header. */
-};
-
-/** Encap action configuration (per table action profile). */
-struct rte_table_action_encap_config {
- /** Bit mask defining the set of packet encapsulations enabled for the
- * current table action profile. If bit (1 << N) is set in *encap_mask*,
- * then packet encapsulation N is enabled, otherwise it is disabled.
- *
- * @see enum rte_table_action_encap_type
- */
- uint64_t encap_mask;
-
- /** Encapsulation type specific configuration. */
- union {
- struct {
- /** Input packet to be encapsulated: offset within the
- * input packet buffer to the start of the Ethernet
- * frame to be encapsulated. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- /** Encapsulation header: non-zero when encapsulation
- * header includes a VLAN tag, zero otherwise.
- */
- int vlan;
-
- /** Encapsulation header: IP version of the IP header
- * within the encapsulation header. Non-zero for IPv4,
- * zero for IPv6.
- */
- int ip_version;
- } vxlan; /**< VXLAN specific configuration. */
- };
-};
-
-/** QinQ_PPPoE encap parameters. */
-struct rte_table_encap_ether_qinq_pppoe {
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_ether_hdr ether;
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** Encap action parameters (per table rule). */
-struct rte_table_action_encap_params {
- /** Encapsulation type. */
- enum rte_table_action_encap_type type;
-
- union {
- /** Only valid when *type* is set to Ether. */
- struct rte_table_action_encap_ether_params ether;
-
- /** Only valid when *type* is set to VLAN. */
- struct rte_table_action_encap_vlan_params vlan;
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_encap_qinq_params qinq;
-
- /** Only valid when *type* is set to MPLS. */
- struct rte_table_action_encap_mpls_params mpls;
-
- /** Only valid when *type* is set to PPPoE. */
- struct rte_table_action_encap_pppoe_params pppoe;
-
- /** Only valid when *type* is set to VXLAN. */
- struct rte_table_action_encap_vxlan_params vxlan;
-
- /** Only valid when *type* is set to QinQ_PPPoE. */
- struct rte_table_encap_ether_qinq_pppoe qinq_pppoe;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-/** NAT action configuration (per table action profile). */
-struct rte_table_action_nat_config {
- /** When non-zero, the IP source address and L4 protocol source port are
- * translated. When zero, the IP destination address and L4 protocol
- * destination port are translated.
- */
- int source_nat;
-
- /** Layer 4 protocol, for example TCP (0x06) or UDP (0x11). The checksum
- * field is computed differently and placed at different header offset
- * by each layer 4 protocol.
- */
- uint8_t proto;
-};
-
-/** NAT action parameters (per table rule). */
-struct rte_table_action_nat_params {
- /** IP version for *addr*: non-zero for IPv4, zero for IPv6. */
- int ip_version;
-
- /** IP address. */
- union {
- /** IPv4 address; only valid when *ip_version* is non-zero. */
- uint32_t ipv4;
-
- /** IPv6 address; only valid when *ip_version* is set to 0. */
- struct rte_ipv6_addr ipv6;
- } addr;
-
- /** Port. */
- uint16_t port;
-};
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-/** TTL action configuration (per table action profile). */
-struct rte_table_action_ttl_config {
- /** When non-zero, the input packets whose updated IPv4 Time to Live
- * (TTL) field or IPv6 Hop Limit (HL) field is zero are dropped.
- * When zero, the input packets whose updated IPv4 TTL field or IPv6 HL
- * field is zero are forwarded as usual (typically for debugging
- * purpose).
- */
- int drop;
-
- /** When non-zero, the *n_packets* stats counter for TTL action is
- * enabled, otherwise disabled.
- *
- * @see struct rte_table_action_ttl_counters
- */
- int n_packets_enabled;
-};
-
-/** TTL action parameters (per table rule). */
-struct rte_table_action_ttl_params {
- /** When non-zero, decrement the IPv4 TTL field and update the checksum
- * field, or decrement the IPv6 HL field. When zero, the IPv4 TTL field
- * or the IPv6 HL field is not changed.
- */
- int decrement;
-};
-
-/** TTL action statistics packets (per table rule). */
-struct rte_table_action_ttl_counters {
- /** Number of IPv4 packets whose updated TTL field is zero or IPv6
- * packets whose updated HL field is zero.
- */
- uint64_t n_packets;
-};
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-/** Stats action configuration (per table action profile). */
-struct rte_table_action_stats_config {
- /** When non-zero, the *n_packets* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_bytes_enabled;
-};
-
-/** Stats action parameters (per table rule). */
-struct rte_table_action_stats_params {
- /** Initial value for the *n_packets* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_packets;
-
- /** Initial value for the *n_bytes* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_bytes;
-};
-
-/** Stats action counters (per table rule). */
-struct rte_table_action_stats_counters {
- /** Number of packets. Valid only when *n_packets_valid* is non-zero. */
- uint64_t n_packets;
-
- /** Number of bytes. Valid only when *n_bytes_valid* is non-zero. */
- uint64_t n_bytes;
-
- /** When non-zero, the *n_packets* field is valid, otherwise invalid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid, otherwise invalid. */
- int n_bytes_valid;
-};
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-/** Timestamp action parameters (per table rule). */
-struct rte_table_action_time_params {
- /** Initial timestamp value. Typically set to current time. */
- uint64_t time;
-};
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET \
- (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
-#endif
-
-/** Common action structure to store the data's value, length, and offset */
-struct rte_table_action_vlo {
- uint8_t *val;
- uint32_t length;
- uint32_t offset;
-};
-
-/** Symmetric crypto action configuration (per table action profile). */
-struct rte_table_action_sym_crypto_config {
- /** Target Cryptodev ID. */
- uint8_t cryptodev_id;
-
- /**
- * Offset to rte_crypto_op structure within the input packet buffer.
- * Offset 0 points to the first byte of the MBUF structure.
- */
- uint32_t op_offset;
-
- /** The mempool for creating cryptodev sessions. */
- struct rte_mempool *mp_create;
-
- /** The mempool for initializing cryptodev sessions. */
- struct rte_mempool *mp_init;
-};
-
-/** Symmetric Crypto action parameters (per table rule). */
-struct rte_table_action_sym_crypto_params {
-
- /** Xform pointer contains all relevant information */
- struct rte_crypto_sym_xform *xform;
-
- /**
- * Offset within the input packet buffer to the first byte of data
- * to be processed by the crypto unit. Offset 0 points to the first
- * byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- union {
- struct {
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv;
-
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv_update;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv_update;
-
- } cipher_auth;
-
- struct {
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv;
-
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad_update;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv_update;
-
- } aead;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-/** Tag action parameters (per table rule). */
-struct rte_table_action_tag_params {
- /** Tag to be attached to the input packet. */
- uint32_t tag;
-};
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-/** Decap action parameters (per table rule). */
-struct rte_table_action_decap_params {
- /** Number of bytes to be removed from the start of the packet. */
- uint16_t n;
-};
-
-/**
- * Table action profile.
- */
-struct rte_table_action_profile;
-
-/**
- * Table action profile create.
- *
- * @param[in] common
- * Common action configuration.
- * @return
- * Table action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common);
-
-/**
- * Table action profile free.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile);
-
-/**
- * Table action profile action register.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @param[in] type
- * Specific table action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_table_action_*type*_config is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config);
-
-/**
- * Table action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * table action objects.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile);
-
-/**
- * Table action.
- */
-struct rte_table_action;
-
-/**
- * Table action create.
- *
- * Instantiates the given table action profile to create a table action object.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new table
- * action object should be allocated.
- * @return
- * Handle to table action object on success, NULL on error.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Table action free.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_free(struct rte_table_action *action);
-
-/**
- * Table action table params get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[inout] params
- * Pipeline table parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params);
-
-/**
- * Table action apply.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) to apply action *type* on.
- * @param[in] type
- * Specific table action previously registered for the table action profile of
- * the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_table_action_*type*_params is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params);
-
-/**
- * Table action DSCP table update.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] dscp_mask
- * 64-bit mask defining the DSCP table entries to be updated. If bit N is set
- * in this bit mask, then DSCP table entry N is to be updated, otherwise not.
- * @param[in] table
- * DSCP table.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table);
-
-/**
- * Table action meter profile add.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID to be used for the *profile* once it is successfully added
- * to the *action* object (needs to be unused by the set of meter profiles
- * currently registered for the *action* object).
- * @param[in] profile
- * Meter profile to be added.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-/**
- * Table action meter profile delete.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID of the meter profile to be deleted from the *action*
- * object (needs to be valid for the *action* object).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id);
-
-/**
- * Table action meter read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with meter action previously
- * applied on it.
- * @param[in] tc_mask
- * Bit mask defining which traffic classes should have the meter stats
- * counters read from *data* and stored into *stats*. If bit N is set in this
- * bit mask, then traffic class N is part of this operation, otherwise it is
- * not. If bit N is set in this bit mask, then traffic class N must be one of
- * the traffic classes that are enabled for the meter action in the table
- * action profile used by the *action* object.
- * @param[inout] stats
- * When non-NULL, it points to the area where the meter stats counters read
- * from *data* are saved. Only the meter stats counters for the *tc_mask*
- * traffic classes are read and stored to *stats*.
- * @param[in] clear
- * When non-zero, the meter stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-/**
- * Table action TTL read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with TTL action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the TTL stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the TTL stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-/**
- * Table action stats read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with stats action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the stats counters are cleared (i.e. set to zero), otherwise
- * the counters are not modified. When the read operation is enabled (*stats*
- * is non-NULL), the clear operation is performed after the read operation is
- * completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-/**
- * Table action timestamp read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with timestamp action
- * previously applied on it.
- * @param[inout] timestamp
- * Pre-allocated memory where the timestamp read from *data* is saved (has to
- * be non-NULL).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp);
-
-/**
- * Table action cryptodev symmetric session get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with sym crypto action.
- * @return
- * The pointer to the session on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_TABLE_ACTION_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC 6/6] port: remove legacy API
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (3 preceding siblings ...)
2026-07-24 16:44 ` [RFC 4/6] pipeline: remove legacy API Stephen Hemminger
@ 2026-07-24 16:44 ` Stephen Hemminger
2026-07-25 7:54 ` [PATCH 0/6] remove legacy Packet Framework API David Marchand
` (10 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-24 16:44 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy port library API (rte_port_*) as announced for
removal in the 24.11 release. The SWX port API remains.
The sched, ip_frag, cryptodev and eventdev dependencies were only
used by the legacy port types, so drop them. The pcap dependency
is kept for the SWX source/sink port.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 7 -
doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
doc/guides/prog_guide/packet_framework.rst | 132 +---
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 3 +
lib/port/meson.build | 22 +-
lib/port/port_log.c | 7 -
lib/port/port_log.h | 11 -
lib/port/rte_port.h | 223 ------
lib/port/rte_port_ethdev.c | 530 --------------
lib/port/rte_port_ethdev.h | 75 --
lib/port/rte_port_eventdev.c | 590 ---------------
lib/port/rte_port_eventdev.h | 94 ---
lib/port/rte_port_fd.c | 524 --------------
lib/port/rte_port_fd.h | 74 --
lib/port/rte_port_frag.c | 280 --------
lib/port/rte_port_frag.h | 70 --
lib/port/rte_port_ras.c | 336 ---------
lib/port/rte_port_ras.h | 58 --
lib/port/rte_port_ring.c | 796 ---------------------
lib/port/rte_port_ring.h | 91 ---
lib/port/rte_port_sched.c | 298 --------
lib/port/rte_port_sched.h | 52 --
lib/port/rte_port_source_sink.c | 616 ----------------
lib/port/rte_port_source_sink.h | 57 --
lib/port/rte_port_sym_crypto.c | 558 ---------------
lib/port/rte_port_sym_crypto.h | 92 ---
27 files changed, 10 insertions(+), 5591 deletions(-)
delete mode 100644 doc/guides/prog_guide/img/figure32.png
delete mode 100644 lib/port/port_log.c
delete mode 100644 lib/port/port_log.h
delete mode 100644 lib/port/rte_port.h
delete mode 100644 lib/port/rte_port_ethdev.c
delete mode 100644 lib/port/rte_port_ethdev.h
delete mode 100644 lib/port/rte_port_eventdev.c
delete mode 100644 lib/port/rte_port_eventdev.h
delete mode 100644 lib/port/rte_port_fd.c
delete mode 100644 lib/port/rte_port_fd.h
delete mode 100644 lib/port/rte_port_frag.c
delete mode 100644 lib/port/rte_port_frag.h
delete mode 100644 lib/port/rte_port_ras.c
delete mode 100644 lib/port/rte_port_ras.h
delete mode 100644 lib/port/rte_port_ring.c
delete mode 100644 lib/port/rte_port_ring.h
delete mode 100644 lib/port/rte_port_sched.c
delete mode 100644 lib/port/rte_port_sched.h
delete mode 100644 lib/port/rte_port_source_sink.c
delete mode 100644 lib/port/rte_port_source_sink.h
delete mode 100644 lib/port/rte_port_sym_crypto.c
delete mode 100644 lib/port/rte_port_sym_crypto.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 760b770d6f..16827a602b 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -182,13 +182,6 @@ The public API headers are grouped by topics:
[bitmap](@ref rte_bitmap.h)
- **packet framework**:
- * [port](@ref rte_port.h):
- [ethdev](@ref rte_port_ethdev.h),
- [ring](@ref rte_port_ring.h),
- [frag](@ref rte_port_frag.h),
- [reass](@ref rte_port_ras.h),
- [sched](@ref rte_port_sched.h),
- [src/sink](@ref rte_port_source_sink.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/img/figure32.png b/doc/guides/prog_guide/img/figure32.png
deleted file mode 100644
index 5215113fd9d533ff56526e21e1832bc7a6cabd04..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 11603
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
XpF?WbPu~YeLUe8#Xq8>R7xljYKq0l$
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index 98cf3be109..3b5ede7dc2 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -4,132 +4,12 @@
Packet Framework Library
========================
-Design Objectives
------------------
-
-The main design objectives for the DPDK Packet Framework are:
-
-* Provide standard methodology to build complex packet processing pipelines.
- Provide reusable and extensible templates for the commonly used pipeline functional blocks;
-
-* Provide capability to switch between pure software and hardware-accelerated implementations for the same pipeline functional block;
-
-* Provide the best trade-off between flexibility and performance.
- Hardcoded pipelines usually provide the best performance, but are not flexible,
- while developing flexible frameworks is never a problem, but performance is usually low;
-
-* Provide a framework that is logically similar to Open Flow.
-
-Overview
---------
-
-Packet processing applications are frequently structured as pipelines of multiple stages,
-with the logic of each stage glued around a lookup table.
-For each incoming packet, the table defines the set of actions to be applied to the packet,
-as well as the next stage to send the packet to.
-
-The DPDK Packet Framework minimizes the development effort required to build packet processing pipelines
-by defining a standard methodology for pipeline development,
-as well as providing libraries of reusable templates for the commonly used pipeline blocks.
-
-The pipeline is constructed by connecting the set of input ports with the set of output ports
-through the set of tables in a tree-like topology.
-As a result of lookup operation for the current packet in the current table,
-one of the table entries (on lookup hit) or the default table entry (on lookup miss)
-provides the set of actions to be applied on the current packet,
-as well as the next hop for the packet, which can be either another table, an output port or packet drop.
-
-An example of packet processing pipeline is presented in :numref:`packet_framework_figure_32`:
-
-.. _packet_framework_figure_32:
-
-.. figure:: img/figure32.*
-
- Example of Packet Processing Pipeline where Input Ports 0 and 1
- are Connected with Output Ports 0, 1 and 2 through Tables 0 and 1
-
-
-Port Library Design
--------------------
-
-Port Types
-~~~~~~~~~~
-
-:numref:`packet_framework_table_qos_19` is a non-exhaustive list of ports
-that can be implemented with the Packet Framework.
-
-.. _packet_framework_table_qos_19:
-
-.. table:: Port Types
-
- +---+------------------+---------------------------------------------------------------------------------------+
- | # | Port type | Description |
- | | | |
- +===+==================+=======================================================================================+
- | 1 | SW ring | SW circular buffer used for message passing between the application threads. Uses |
- | | | the DPDK rte_ring primitive. Expected to be the most commonly used type of |
- | | | port. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 2 | HW ring | Queue of buffer descriptors used to interact with NIC, switch or accelerator ports. |
- | | | For NIC ports, it uses the DPDK rte_eth_rx_queue or rte_eth_tx_queue |
- | | | primitives. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 3 | IP reassembly | Input packets are either IP fragments or complete IP datagrams. Output packets are |
- | | | complete IP datagrams. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 4 | IP fragmentation | Input packets are jumbo (IP datagrams with length bigger than MTU) or non-jumbo |
- | | | packets. Output packets are non-jumbo packets. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 5 | Traffic manager | Traffic manager attached to a specific NIC output port, performing congestion |
- | | | management and hierarchical scheduling according to pre-defined SLAs. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 6 | Source | Input port used as packet generator. Similar to Linux kernel /dev/zero character |
- | | | device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 7 | Sink | Output port used to drop all input packets. Similar to Linux kernel /dev/null |
- | | | character device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 8 | Sym_crypto | Output port used to extract DPDK Cryptodev operations from a fixed offset of the |
- | | | packet and then enqueue to the Cryptodev PMD. Input port used to dequeue the |
- | | | Cryptodev operations from the Cryptodev PMD and then retrieve the packets from them. |
- +---+------------------+---------------------------------------------------------------------------------------+
-
-Port Interface
-~~~~~~~~~~~~~~
-
-Each port is unidirectional, i.e. either input port or output port.
-Each input/output port is required to implement an abstract interface that
-defines the initialization and run-time operation of the port.
-The port abstract interface is described below.
-
-.. table:: 20 Port Abstract Interface
-
- +---+----------------+-----------------------------------------------------------------------------------------+
- | # | Port Operation | Description |
- | | | |
- +===+================+=========================================================================================+
- | 1 | Create | Create the low-level port object (e.g. queue). Can internally allocate memory. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 2 | Free | Free the resources (e.g. memory) used by the low-level port object. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 3 | RX | Read a burst of input packets. Non-blocking operation. Only defined for input ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 4 | TX | Write a burst of input packets. Non-blocking operation. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 5 | Flush | Flush the output buffer. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
+The Packet Framework is a set of libraries (port, table and pipeline)
+for building flexible packet processing pipelines:
+the pipeline is constructed by connecting a set of input ports
+with a set of output ports through a set of match-action tables.
+The current framework API is the Software Switch (SWX) pipeline
+described below.
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9dcf86098f..75b56b0e10 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* port: The port library legacy API (functions rte_port_*)
- will be deprecated and subsequently removed in DPDK 24.11 release.
- Before this, the new port library API (functions rte_swx_port_*)
- will gradually transition from experimental to stable status.
-
* bus/vmbus: Starting DPDK 25.11, all the vmbus API defined in
``drivers/bus/vmbus/rte_bus_vmbus.h`` will become internal to DPDK.
Those API functions are used internally by DPDK core and netvsc PMD.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 306482c1d9..bc0ac01d5d 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -82,6 +82,9 @@ Removed Items
* Removed the legacy table library API (``rte_table_*`` functions).
The SWX table API (``rte_swx_table_*``) remains.
+* Removed the legacy port library API (``rte_port_*`` functions).
+ The SWX port API (``rte_swx_port_*``) remains.
+
API Changes
-----------
diff --git a/lib/port/meson.build b/lib/port/meson.build
index b597772872..ef88b917a3 100644
--- a/lib/port/meson.build
+++ b/lib/port/meson.build
@@ -8,39 +8,19 @@ if is_windows
endif
sources = files(
- 'port_log.c',
- 'rte_port_ethdev.c',
- 'rte_port_fd.c',
- 'rte_port_frag.c',
- 'rte_port_ras.c',
- 'rte_port_ring.c',
- 'rte_port_sched.c',
- 'rte_port_source_sink.c',
- 'rte_port_sym_crypto.c',
- 'rte_port_eventdev.c',
'rte_swx_port_ethdev.c',
'rte_swx_port_fd.c',
'rte_swx_port_ring.c',
'rte_swx_port_source_sink.c',
)
headers = files(
- 'rte_port_ethdev.h',
- 'rte_port_fd.h',
- 'rte_port_frag.h',
- 'rte_port_ras.h',
- 'rte_port.h',
- 'rte_port_ring.h',
- 'rte_port_sched.h',
- 'rte_port_source_sink.h',
- 'rte_port_sym_crypto.h',
- 'rte_port_eventdev.h',
'rte_swx_port.h',
'rte_swx_port_ethdev.h',
'rte_swx_port_fd.h',
'rte_swx_port_ring.h',
'rte_swx_port_source_sink.h',
)
-deps += ['ethdev', 'sched', 'ip_frag', 'cryptodev', 'eventdev']
+deps += ['ethdev']
if dpdk_conf.has('RTE_HAS_LIBPCAP')
dpdk_conf.set('RTE_PORT_PCAP', 1)
diff --git a/lib/port/port_log.c b/lib/port/port_log.c
deleted file mode 100644
index e7a10d80ef..0000000000
--- a/lib/port/port_log.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2024 Stephen Hemminger <stephen@networkplumber.org>
- */
-
-#include <rte_log.h>
-
-RTE_LOG_REGISTER_DEFAULT(port_logtype, INFO);
diff --git a/lib/port/port_log.h b/lib/port/port_log.h
deleted file mode 100644
index 28d75ee48b..0000000000
--- a/lib/port/port_log.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2023 Red Hat, Inc.
- */
-
-#include <rte_log.h>
-
-extern int port_logtype;
-#define RTE_LOGTYPE_PORT port_logtype
-
-#define PORT_LOG(level, ...) \
- RTE_LOG_LINE(level, PORT, "" __VA_ARGS__)
diff --git a/lib/port/rte_port.h b/lib/port/rte_port.h
deleted file mode 100644
index 81f57c41a5..0000000000
--- a/lib/port/rte_port.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_H__
-#define __INCLUDE_RTE_PORT_H__
-
-/**
- * @file
- * RTE Port
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard interface to implement different types of packet ports.
- */
-
-#include <stdint.h>
-#include <rte_mbuf.h>
-
-/**@{
- * Macros to allow accessing metadata stored in the mbuf headroom
- * just beyond the end of the mbuf data structure returned by a port
- */
-#define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset) \
- (&((uint8_t *)(mbuf))[offset])
-#define RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset) \
- ((uint16_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset) \
- ((uint32_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset) \
- ((uint64_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-
-#define RTE_MBUF_METADATA_UINT8(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT16(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset))
-/**@}*/
-
-/*
- * Port IN
- */
-/** Maximum number of packets read from any input port in a single burst.
-Cannot be changed. */
-#define RTE_PORT_IN_BURST_SIZE_MAX 64
-
-/** Input port statistics */
-struct rte_port_in_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Input port create
- *
- * @param params
- * Parameters for input port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to input port instance
- */
-typedef void* (*rte_port_in_op_create)(void *params, int socket_id);
-
-/**
- * Input port free
- *
- * @param port
- * Handle to input port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_free)(void *port);
-
-/**
- * Input port packet burst RX
- *
- * @param port
- * Handle to input port instance
- * @param pkts
- * Burst of input packets
- * @param n_pkts
- * Number of packets in the input burst
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_rx)(
- void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts);
-
-/**
- * Input port stats get
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_in stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_in_op_stats_read)(
- void *port,
- struct rte_port_in_stats *stats,
- int clear);
-
-/** Input port interface defining the input port operation */
-struct rte_port_in_ops {
- rte_port_in_op_create f_create; /**< Create */
- rte_port_in_op_free f_free; /**< Free */
- rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
- rte_port_in_op_stats_read f_stats; /**< Stats */
-};
-
-/*
- * Port OUT
- */
-/** Output port statistics */
-struct rte_port_out_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Output port create
- *
- * @param params
- * Parameters for output port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to output port instance
- */
-typedef void* (*rte_port_out_op_create)(void *params, int socket_id);
-
-/**
- * Output port free
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_free)(void *port);
-
-/**
- * Output port single packet TX
- *
- * @param port
- * Handle to output port instance
- * @param pkt
- * Input packet
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx)(
- void *port,
- struct rte_mbuf *pkt);
-
-/**
- * Output port packet burst TX
- *
- * @param port
- * Handle to output port instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx_bulk)(
- void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask);
-
-/**
- * Output port flush
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_flush)(void *port);
-
-/**
- * Output port stats read
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_out stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_out_op_stats_read)(
- void *port,
- struct rte_port_out_stats *stats,
- int clear);
-
-/** Output port interface defining the output port operation */
-struct rte_port_out_ops {
- rte_port_out_op_create f_create; /**< Create */
- rte_port_out_op_free f_free; /**< Free */
- rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
- rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
- rte_port_out_op_flush f_flush; /**< Flush */
- rte_port_out_op_stats_read f_stats; /**< Stats */
-};
-
-#endif
diff --git a/lib/port/rte_port_ethdev.c b/lib/port/rte_port_ethdev.c
deleted file mode 100644
index bdab2fbf6c..0000000000
--- a/lib/port/rte_port_ethdev.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ethdev.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ethdev.h"
-
-#include "port_log.h"
-
-/*
- * Port ETHDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_reader {
- struct rte_port_in_stats stats;
-
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_reader_params *conf =
- params;
- struct rte_port_ethdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
-
- return port;
-}
-
-static int
-rte_port_ethdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ethdev_reader *p =
- port;
- uint16_t rx_pkt_cnt;
-
- rx_pkt_cnt = rte_eth_rx_burst(p->port_id, p->queue_id, pkts, n_pkts);
- RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(p, rx_pkt_cnt);
- return rx_pkt_cnt;
-}
-
-static int
-rte_port_ethdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ethdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_params *conf =
- params;
- struct rte_port_ethdev_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_ethdev_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst(p);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_flush(void *port)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_nodrop_params *conf =
- params;
- struct rte_port_ethdev_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ethdev_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id, p->tx_buf,
- p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf + nb_tx, p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to send all packets in single burst,
- * move remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ethdev_reader_ops)
-struct rte_port_in_ops rte_port_ethdev_reader_ops = {
- .f_create = rte_port_ethdev_reader_create,
- .f_free = rte_port_ethdev_reader_free,
- .f_rx = rte_port_ethdev_reader_rx,
- .f_stats = rte_port_ethdev_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_ops = {
- .f_create = rte_port_ethdev_writer_create,
- .f_free = rte_port_ethdev_writer_free,
- .f_tx = rte_port_ethdev_writer_tx,
- .f_tx_bulk = rte_port_ethdev_writer_tx_bulk,
- .f_flush = rte_port_ethdev_writer_flush,
- .f_stats = rte_port_ethdev_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops = {
- .f_create = rte_port_ethdev_writer_nodrop_create,
- .f_free = rte_port_ethdev_writer_nodrop_free,
- .f_tx = rte_port_ethdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ethdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ethdev_writer_nodrop_flush,
- .f_stats = rte_port_ethdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ethdev.h b/lib/port/rte_port_ethdev.h
deleted file mode 100644
index 7729ff0da3..0000000000
--- a/lib/port/rte_port_ethdev.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_ETHDEV_H__
-#define __INCLUDE_RTE_PORT_ETHDEV_H__
-
-/**
- * @file
- * RTE Port Ethernet Device
- *
- * ethdev_reader: input port built on top of pre-initialized NIC RX queue
- * ethdev_writer: output port built on top of pre-initialized NIC TX queue
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ethdev_reader port parameters */
-struct rte_port_ethdev_reader_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-};
-
-/** ethdev_reader port operations */
-extern struct rte_port_in_ops rte_port_ethdev_reader_ops;
-
-/** ethdev_writer port parameters */
-struct rte_port_ethdev_writer_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ethdev_writer port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_ops;
-
-/** ethdev_writer_nodrop port parameters */
-struct rte_port_ethdev_writer_nodrop_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ethdev_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_eventdev.c b/lib/port/rte_port_eventdev.c
deleted file mode 100644
index c3a287b834..0000000000
--- a/lib/port/rte_port_eventdev.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_eventdev.h"
-
-#include "port_log.h"
-
-/*
- * Port EVENTDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_reader {
- struct rte_port_in_stats stats;
-
- uint8_t eventdev_id;
- uint16_t port_id;
-
- struct rte_event ev[RTE_PORT_IN_BURST_SIZE_MAX];
-};
-
-static void *
-rte_port_eventdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_reader_params *conf =
- params;
- struct rte_port_eventdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
-
- return port;
-}
-
-static int
-rte_port_eventdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_eventdev_reader *p = port;
- uint16_t rx_evts_cnt, i;
-
- rx_evts_cnt = rte_event_dequeue_burst(p->eventdev_id, p->port_id,
- p->ev, n_pkts, 0);
-
- for (i = 0; i < rx_evts_cnt; i++)
- pkts[i] = p->ev[i].mbuf;
-
- RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(p, rx_evts_cnt);
-
- return rx_evts_cnt;
-}
-
-static int
-rte_port_eventdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_eventdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
-
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-static void *
-rte_port_eventdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_params *conf =
- params;
- struct rte_port_eventdev_writer *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_eventdev_writer *p)
-{
- uint32_t nb_enq;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->enq_buf_count -
- nb_enq);
-
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst(p);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[2 * RTE_PORT_IN_BURST_SIZE_MAX] = {};
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p,
- n_pkts - n_enq_ok);
- for (; n_enq_ok < n_pkts; n_enq_ok++)
- rte_pktmbuf_free(pkts[n_enq_ok]);
-
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_flush(void *port)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-
-static void *
-rte_port_eventdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_nodrop_params *conf =
- params;
- struct rte_port_eventdev_writer_nodrop *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
- /*
- * When n_retries is 0 it means that we should wait for every event to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_eventdev_writer_nodrop *p)
-{
- uint32_t nb_enq, i;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_enq += rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev + nb_enq,
- p->enq_buf_count - nb_enq);
-
- /* We sent all the events in more than one try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
- }
- /* We didn't send the events in maximum allowed attempts */
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->enq_buf_count - nb_enq);
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer_nodrop *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[RTE_PORT_IN_BURST_SIZE_MAX] = {};
-
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- if (n_enq_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to enqueue all events in single burst,
- * move remaining events to the buffer and call send burst.
- */
- for (; n_enq_ok < n_pkts; n_enq_ok++) {
- struct rte_mbuf *pkt = pkts[n_enq_ok];
- p->ev[p->enq_buf_count++].mbuf = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_reader_ops, 19.11)
-struct rte_port_in_ops rte_port_eventdev_reader_ops = {
- .f_create = rte_port_eventdev_reader_create,
- .f_free = rte_port_eventdev_reader_free,
- .f_rx = rte_port_eventdev_reader_rx,
- .f_stats = rte_port_eventdev_reader_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_ops = {
- .f_create = rte_port_eventdev_writer_create,
- .f_free = rte_port_eventdev_writer_free,
- .f_tx = rte_port_eventdev_writer_tx,
- .f_tx_bulk = rte_port_eventdev_writer_tx_bulk,
- .f_flush = rte_port_eventdev_writer_flush,
- .f_stats = rte_port_eventdev_writer_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_nodrop_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops = {
- .f_create = rte_port_eventdev_writer_nodrop_create,
- .f_free = rte_port_eventdev_writer_nodrop_free,
- .f_tx = rte_port_eventdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_eventdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_eventdev_writer_nodrop_flush,
- .f_stats = rte_port_eventdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_eventdev.h b/lib/port/rte_port_eventdev.h
deleted file mode 100644
index d9eccf07d4..0000000000
--- a/lib/port/rte_port_eventdev.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_EVENTDEV_H__
-#define __INCLUDE_RTE_PORT_EVENTDEV_H__
-
-/**
- * @file
- * RTE Port Eventdev Interface
- *
- * eventdev_reader: input port built on top of pre-initialized eventdev
- * interface
- * eventdev_writer: output port built on top of pre-initialized eventdev
- * interface
- */
-
-#include <stdint.h>
-#include <rte_eventdev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Eventdev_reader port parameters */
-struct rte_port_eventdev_reader_params {
- /** Eventdev Device ID */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID */
- uint8_t port_id;
-};
-
-/** Eventdev_reader port operations. */
-extern struct rte_port_in_ops rte_port_eventdev_reader_ops;
-
-/** Eventdev_writer port parameters. */
-struct rte_port_eventdev_writer_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint8_t port_id;
-
- /** Eventdev Queue ID. */
- uint8_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-};
-
-/** Eventdev_writer port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_ops;
-
-/** Event_writer_nodrop port parameters. */
-struct rte_port_eventdev_writer_nodrop_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint16_t port_id;
-
- /** Eventdev Queue ID. */
- uint16_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Eventdev_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_fd.c b/lib/port/rte_port_fd.c
deleted file mode 100644
index dbc9efef1b..0000000000
--- a/lib/port/rte_port_fd.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_fd.h"
-
-#include "port_log.h"
-
-/*
- * Port FD Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_reader {
- struct rte_port_in_stats stats;
- int fd;
- uint32_t mtu;
- struct rte_mempool *mempool;
-};
-
-static void *
-rte_port_fd_reader_create(void *params, int socket_id)
-{
- struct rte_port_fd_reader_params *conf =
- params;
- struct rte_port_fd_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
- if (conf->fd < 0) {
- PORT_LOG(ERR, "%s: Invalid file descriptor", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Invalid MTU", __func__);
- return NULL;
- }
- if (conf->mempool == NULL) {
- PORT_LOG(ERR, "%s: Invalid mempool", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->mtu = conf->mtu;
- port->mempool = conf->mempool;
-
- return port;
-}
-
-static int
-rte_port_fd_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_fd_reader *p = port;
- uint32_t i, j;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void *);
- ssize_t n_bytes;
-
- n_bytes = read(p->fd, pkt_data, (size_t) p->mtu);
- if (n_bytes <= 0)
- break;
-
- pkt->data_len = n_bytes;
- pkt->pkt_len = n_bytes;
- }
-
- for (j = i; j < n_pkts; j++)
- rte_pktmbuf_free(pkts[j]);
-
- RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(p, i);
-
- return i;
-}
-
-static int
-rte_port_fd_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_fd_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_params *conf =
- params;
- struct rte_port_fd_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_fd_writer *p)
-{
- uint32_t i;
-
- for (i = 0; i < p->tx_buf_count; i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret < 0)
- break;
- }
-
- RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_flush(void *port)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t n_retries;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_nodrop_params *conf =
- params;
- struct rte_port_fd_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->fd < 0) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_fd_writer_nodrop *p)
-{
- uint64_t n_retries;
- uint32_t i;
-
- n_retries = 0;
- for (i = 0; (i < p->tx_buf_count) && (n_retries < p->n_retries); i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
-
- for ( ; n_retries < p->n_retries; n_retries++) {
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret)
- break;
- }
- }
-
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_flush(void *port)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_nodrop_flush(port);
- rte_free(port);
-
-return 0;
-}
-
-static int rte_port_fd_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_fd_reader_ops)
-struct rte_port_in_ops rte_port_fd_reader_ops = {
- .f_create = rte_port_fd_reader_create,
- .f_free = rte_port_fd_reader_free,
- .f_rx = rte_port_fd_reader_rx,
- .f_stats = rte_port_fd_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_ops)
-struct rte_port_out_ops rte_port_fd_writer_ops = {
- .f_create = rte_port_fd_writer_create,
- .f_free = rte_port_fd_writer_free,
- .f_tx = rte_port_fd_writer_tx,
- .f_tx_bulk = rte_port_fd_writer_tx_bulk,
- .f_flush = rte_port_fd_writer_flush,
- .f_stats = rte_port_fd_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_fd_writer_nodrop_ops = {
- .f_create = rte_port_fd_writer_nodrop_create,
- .f_free = rte_port_fd_writer_nodrop_free,
- .f_tx = rte_port_fd_writer_nodrop_tx,
- .f_tx_bulk = rte_port_fd_writer_nodrop_tx_bulk,
- .f_flush = rte_port_fd_writer_nodrop_flush,
- .f_stats = rte_port_fd_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_fd.h b/lib/port/rte_port_fd.h
deleted file mode 100644
index 40a5e4a426..0000000000
--- a/lib/port/rte_port_fd.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_FD_H__
-#define __INCLUDE_RTE_PORT_FD_H__
-
-/**
- * @file
- * RTE Port FD Device
- *
- * fd_reader: input port built on top of valid non-blocking file descriptor
- * fd_writer: output port built on top of valid non-blocking file descriptor
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** fd_reader port parameters */
-struct rte_port_fd_reader_params {
- /** File descriptor */
- int fd;
-
- /** Maximum Transfer Unit (MTU) */
- uint32_t mtu;
-
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-};
-
-/** fd_reader port operations */
-extern struct rte_port_in_ops rte_port_fd_reader_ops;
-
-/** fd_writer port parameters */
-struct rte_port_fd_writer_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-};
-
-/** fd_writer port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_ops;
-
-/** fd_writer_nodrop port parameters */
-struct rte_port_fd_writer_nodrop_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** fd_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_frag.c b/lib/port/rte_port_frag.c
deleted file mode 100644
index 9444f5939c..0000000000
--- a/lib/port/rte_port_frag.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-
-#include "rte_port_frag.h"
-
-#include "port_log.h"
-
-/* Max number of fragments per packet allowed */
-#define RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET 0x80
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-typedef int32_t
- (*frag_op)(struct rte_mbuf *pkt_in,
- struct rte_mbuf **pkts_out,
- uint16_t nb_pkts_out,
- uint16_t mtu_size,
- struct rte_mempool *pool_direct,
- struct rte_mempool *pool_indirect);
-
-struct __rte_cache_aligned rte_port_ring_reader_frag {
- struct rte_port_in_stats stats;
-
- /* Input parameters */
- struct rte_ring *ring;
- uint32_t mtu;
- uint32_t metadata_size;
- struct rte_mempool *pool_direct;
- struct rte_mempool *pool_indirect;
-
- /* Internal buffers */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *frags[RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET];
- uint32_t n_pkts;
- uint32_t pos_pkts;
- uint32_t n_frags;
- uint32_t pos_frags;
-
- frag_op f_frag;
-};
-
-static void *
-rte_port_ring_reader_frag_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_reader_frag_params *conf =
- params;
- struct rte_port_ring_reader_frag *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Parameter mtu is invalid", __func__);
- return NULL;
- }
- if (conf->pool_direct == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_direct is NULL",
- __func__);
- return NULL;
- }
- if (conf->pool_indirect == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_indirect is NULL",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port), RTE_CACHE_LINE_SIZE,
- socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->mtu = conf->mtu;
- port->metadata_size = conf->metadata_size;
- port->pool_direct = conf->pool_direct;
- port->pool_indirect = conf->pool_indirect;
-
- port->n_pkts = 0;
- port->pos_pkts = 0;
- port->n_frags = 0;
- port->pos_frags = 0;
-
- port->f_frag = (is_ipv4) ?
- rte_ipv4_fragment_packet : rte_ipv6_fragment_packet;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_ipv4_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_reader_ipv6_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 0);
-}
-
-static int
-rte_port_ring_reader_frag_rx(void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader_frag *p =
- port;
- uint32_t n_pkts_out;
-
- n_pkts_out = 0;
-
- /* Get packets from the "frag" buffer */
- if (p->n_frags >= n_pkts) {
- memcpy(pkts, &p->frags[p->pos_frags], n_pkts * sizeof(void *));
- p->pos_frags += n_pkts;
- p->n_frags -= n_pkts;
-
- return n_pkts;
- }
-
- memcpy(pkts, &p->frags[p->pos_frags], p->n_frags * sizeof(void *));
- n_pkts_out = p->n_frags;
- p->n_frags = 0;
-
- /* Look to "pkts" buffer to get more packets */
- for ( ; ; ) {
- struct rte_mbuf *pkt;
- uint32_t n_pkts_to_provide, i;
- int status;
-
- /* If "pkts" buffer is empty, read packet burst from ring */
- if (p->n_pkts == 0) {
- p->n_pkts = rte_ring_sc_dequeue_burst(p->ring,
- (void **) p->pkts, RTE_PORT_IN_BURST_SIZE_MAX,
- NULL);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(p, p->n_pkts);
- if (p->n_pkts == 0)
- return n_pkts_out;
- p->pos_pkts = 0;
- }
-
- /* Read next packet from "pkts" buffer */
- pkt = p->pkts[p->pos_pkts++];
- p->n_pkts--;
-
- /* If not jumbo, pass current packet to output */
- if (pkt->pkt_len <= p->mtu) {
- pkts[n_pkts_out++] = pkt;
-
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (n_pkts_to_provide == 0)
- return n_pkts;
-
- continue;
- }
-
- /* Fragment current packet into the "frags" buffer */
- status = p->f_frag(
- pkt,
- p->frags,
- RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET,
- p->mtu,
- p->pool_direct,
- p->pool_indirect
- );
-
- if (status < 0) {
- rte_pktmbuf_free(pkt);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(p, 1);
- continue;
- }
-
- p->n_frags = (uint32_t) status;
- p->pos_frags = 0;
-
- /* Copy meta-data from input jumbo packet to its fragments */
- for (i = 0; i < p->n_frags; i++) {
- uint8_t *src =
- RTE_MBUF_METADATA_UINT8_PTR(pkt, sizeof(struct rte_mbuf));
- uint8_t *dst =
- RTE_MBUF_METADATA_UINT8_PTR(p->frags[i], sizeof(struct rte_mbuf));
-
- memcpy(dst, src, p->metadata_size);
- }
-
- /* Free input jumbo packet */
- rte_pktmbuf_free(pkt);
-
- /* Get packets from "frag" buffer */
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (p->n_frags >= n_pkts_to_provide) {
- memcpy(&pkts[n_pkts_out], p->frags,
- n_pkts_to_provide * sizeof(void *));
- p->n_frags -= n_pkts_to_provide;
- p->pos_frags += n_pkts_to_provide;
-
- return n_pkts;
- }
-
- memcpy(&pkts[n_pkts_out], p->frags,
- p->n_frags * sizeof(void *));
- n_pkts_out += p->n_frags;
- p->n_frags = 0;
- }
-}
-
-static int
-rte_port_ring_reader_frag_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_frag_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader_frag *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv4_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops = {
- .f_create = rte_port_ring_reader_ipv4_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv6_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops = {
- .f_create = rte_port_ring_reader_ipv6_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
diff --git a/lib/port/rte_port_frag.h b/lib/port/rte_port_frag.h
deleted file mode 100644
index 9a10f10523..0000000000
--- a/lib/port/rte_port_frag.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IP_FRAG_H__
-#define __INCLUDE_RTE_PORT_IP_FRAG_H__
-
-/**
- * @file
- * RTE Port for IPv4 Fragmentation
- *
- * This port is built on top of pre-initialized single consumer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP fragmentation functionality is executed on ring read operation,
- * hence this port is implemented as an input port. A regular ring_writer port
- * can be created to write to the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or jumbo
- * frames (i.e. IP packets with length bigger than provided MTU value). The
- * packets read from the ring are all non-jumbo frames. The complete IP
- * datagrams written to the ring are not changed. The jumbo frames are
- * fragmented into several IP packets with length less or equal to MTU.
- */
-
-#include <stdint.h>
-
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader_ipv4_frag port parameters */
-struct rte_port_ring_reader_frag_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Maximum Transfer Unit (MTU). Maximum IP packet size (in bytes). */
- uint32_t mtu;
-
- /** Size of application dependent meta-data stored per each input packet
- that has to be copied to each of the fragments originating from the
- same input IP datagram. */
- uint32_t metadata_size;
-
- /** Pre-initialized buffer pool used for allocating direct buffers for
- the output fragments. */
- struct rte_mempool *pool_direct;
-
- /** Pre-initialized buffer pool used for allocating indirect buffers for
- the output fragments. */
- struct rte_mempool *pool_indirect;
-};
-
-#define rte_port_ring_reader_ipv4_frag_params rte_port_ring_reader_frag_params
-
-#define rte_port_ring_reader_ipv6_frag_params rte_port_ring_reader_frag_params
-
-/** ring_reader_ipv4_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops;
-
-/** ring_reader_ipv6_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ras.c b/lib/port/rte_port_ras.c
deleted file mode 100644
index 58ab7a1c5b..0000000000
--- a/lib/port/rte_port_ras.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-#include <rte_cycles.h>
-#include <rte_log.h>
-
-#include "rte_port_ras.h"
-
-#include "port_log.h"
-
-#ifndef RTE_PORT_RAS_N_BUCKETS
-#define RTE_PORT_RAS_N_BUCKETS 4094
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES_PER_BUCKET
-#define RTE_PORT_RAS_N_ENTRIES_PER_BUCKET 8
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES
-#define RTE_PORT_RAS_N_ENTRIES (RTE_PORT_RAS_N_BUCKETS * RTE_PORT_RAS_N_ENTRIES_PER_BUCKET)
-#endif
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_ras;
-
-typedef void (*ras_op)(
- struct rte_port_ring_writer_ras *p,
- struct rte_mbuf *pkt);
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-
-struct rte_port_ring_writer_ras {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- struct rte_ip_frag_tbl *frag_tbl;
- struct rte_ip_frag_death_row death_row;
-
- ras_op f_ras;
-};
-
-static void *
-rte_port_ring_writer_ras_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_writer_ras_params *conf =
- params;
- struct rte_port_ring_writer_ras *port;
- uint64_t frag_cycles;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if ((conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Parameter tx_burst_sz is invalid",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate socket", __func__);
- return NULL;
- }
-
- /* Create fragmentation table */
- frag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * MS_PER_S;
- frag_cycles *= 100;
-
- port->frag_tbl = rte_ip_frag_table_create(
- RTE_PORT_RAS_N_BUCKETS,
- RTE_PORT_RAS_N_ENTRIES_PER_BUCKET,
- RTE_PORT_RAS_N_ENTRIES,
- frag_cycles,
- socket_id);
-
- if (port->frag_tbl == NULL) {
- PORT_LOG(ERR, "%s: rte_ip_frag_table_create failed",
- __func__);
- rte_free(port);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- port->f_ras = (is_ipv4 == 1) ? process_ipv4 : process_ipv6;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_ipv4_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_writer_ipv6_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 0);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer_ras *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv4_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv4_hdr *);
-
- /* Get "More fragments" flag and fragment offset */
- uint16_t frag_field = rte_be_to_cpu_16(pkt_hdr->fragment_offset);
- uint16_t frag_offset = (uint16_t)(frag_field & RTE_IPV4_HDR_OFFSET_MASK);
- uint16_t frag_flag = (uint16_t)(frag_field & RTE_IPV4_HDR_MF_FLAG);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_flag == 0) && (frag_offset == 0))
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr);
-
- /* Process this fragment */
- mo = rte_ipv4_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(),
- pkt_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv6_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv6_hdr *);
-
- struct rte_ipv6_fragment_ext *frag_hdr;
- uint16_t frag_data = 0;
- frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt_hdr);
- if (frag_hdr != NULL)
- frag_data = rte_be_to_cpu_16(frag_hdr->frag_data);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_data & RTE_IPV6_FRAG_USED_MASK) == 0)
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr) + sizeof(*frag_hdr);
-
- /* Process this fragment */
- mo = rte_ipv6_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(), pkt_hdr,
- frag_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static int
-rte_port_ring_writer_ras_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_flush(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_free(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_port_ring_writer_ras_flush(port);
- rte_ip_frag_table_destroy(p->frag_tbl);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ras_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv4_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops = {
- .f_create = rte_port_ring_writer_ipv4_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv6_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops = {
- .f_create = rte_port_ring_writer_ipv6_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
diff --git a/lib/port/rte_port_ras.h b/lib/port/rte_port_ras.h
deleted file mode 100644
index 86e36f5362..0000000000
--- a/lib/port/rte_port_ras.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RAS_H__
-#define __INCLUDE_RTE_PORT_RAS_H__
-
-/**
- * @file
- * RTE Port for IPv4 Reassembly
- *
- * This port is built on top of pre-initialized single producer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP reassembly functionality is executed on ring write operation,
- * hence this port is implemented as an output port. A regular ring_reader port
- * can be created to read from the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or IP
- * fragments. The packets read from the ring are all complete IP datagrams,
- * either jumbo frames (i.e. IP packets with length bigger than MTU) or not.
- * The complete IP datagrams written to the ring are not changed. The IP
- * fragments written to the ring are first reassembled and into complete IP
- * datagrams or dropped on error or IP reassembly time-out.
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_writer_ipv4_ras port parameters */
-struct rte_port_ring_writer_ras_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be bigger
- or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-#define rte_port_ring_writer_ipv4_ras_params rte_port_ring_writer_ras_params
-
-#define rte_port_ring_writer_ipv6_ras_params rte_port_ring_writer_ras_params
-
-/** ring_writer_ipv4_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops;
-
-/** ring_writer_ipv6_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ring.c b/lib/port/rte_port_ring.c
deleted file mode 100644
index 307a576d65..0000000000
--- a/lib/port/rte_port_ring.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ring.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ring.h"
-
-#include "port_log.h"
-
-/*
- * Port RING Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_reader {
- struct rte_port_in_stats stats;
-
- struct rte_ring *ring;
-};
-
-static void *
-rte_port_ring_reader_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_reader_params *conf =
- params;
- struct rte_port_ring_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_cons_single(conf->ring) && is_multi) ||
- (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 1);
-}
-
-static int
-rte_port_ring_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_sc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_multi_reader_rx(void *port, struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_mc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_params *conf =
- params;
- struct rte_port_ring_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
-
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok = rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok = rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_free(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_flush(port);
- else
- rte_port_ring_writer_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop_params *conf =
- params;
- struct rte_port_ring_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_sp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_mp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_nodrop_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
-
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok =
- rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok =
- rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we didn't manage to send all packets in single burst, move
- * remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_free(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_nodrop_flush(port);
- else
- rte_port_ring_writer_nodrop_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ops)
-struct rte_port_in_ops rte_port_ring_reader_ops = {
- .f_create = rte_port_ring_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ops)
-struct rte_port_out_ops rte_port_ring_writer_ops = {
- .f_create = rte_port_ring_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_writer_tx,
- .f_tx_bulk = rte_port_ring_writer_tx_bulk,
- .f_flush = rte_port_ring_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_writer_nodrop_ops = {
- .f_create = rte_port_ring_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_reader_ops)
-struct rte_port_in_ops rte_port_ring_multi_reader_ops = {
- .f_create = rte_port_ring_multi_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_multi_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_ops = {
- .f_create = rte_port_ring_multi_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_multi_writer_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops = {
- .f_create = rte_port_ring_multi_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_multi_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ring.h b/lib/port/rte_port_ring.h
deleted file mode 100644
index 2089d0889b..0000000000
--- a/lib/port/rte_port_ring.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RING_H__
-#define __INCLUDE_RTE_PORT_RING_H__
-
-/**
- * @file
- * RTE Port Ring
- *
- * ring_reader:
- * input port built on top of pre-initialized single consumer ring
- * ring_writer:
- * output port built on top of pre-initialized single producer ring
- * ring_multi_reader:
- * input port built on top of pre-initialized multi consumers ring
- * ring_multi_writer:
- * output port built on top of pre-initialized multi producers ring
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader port parameters */
-struct rte_port_ring_reader_params {
- /** Underlying consumer ring that has to be pre-initialized */
- struct rte_ring *ring;
-};
-
-/** ring_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ops;
-
-/** ring_writer port parameters */
-struct rte_port_ring_writer_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ring_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ops;
-
-/** ring_writer_nodrop port parameters */
-struct rte_port_ring_writer_nodrop_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ring_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_nodrop_ops;
-
-/** ring_multi_reader port parameters */
-#define rte_port_ring_multi_reader_params rte_port_ring_reader_params
-
-/** ring_multi_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_multi_reader_ops;
-
-/** ring_multi_writer port parameters */
-#define rte_port_ring_multi_writer_params rte_port_ring_writer_params
-
-/** ring_multi_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_ops;
-
-/** ring_multi_writer_nodrop port parameters */
-#define rte_port_ring_multi_writer_nodrop_params \
- rte_port_ring_writer_nodrop_params
-
-/** ring_multi_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sched.c b/lib/port/rte_port_sched.c
deleted file mode 100644
index 3091078aa1..0000000000
--- a/lib/port/rte_port_sched.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sched.h"
-
-#include "port_log.h"
-
-/*
- * Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_reader {
- struct rte_port_in_stats stats;
-
- struct rte_sched_port *sched;
-};
-
-static void *
-rte_port_sched_reader_create(void *params, int socket_id)
-{
- struct rte_port_sched_reader_params *conf =
- params;
- struct rte_port_sched_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
-
- return port;
-}
-
-static int
-rte_port_sched_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sched_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_sched_port_dequeue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_READER_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_sched_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sched_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_sched_port *sched;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-};
-
-static void *
-rte_port_sched_writer_create(void *params, int socket_id)
-{
- struct rte_port_sched_writer_params *conf =
- params;
- struct rte_port_sched_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static int
-rte_port_sched_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- __rte_unused uint32_t nb_tx;
- uint64_t n_pkts = rte_popcount64(pkts_mask);
-
- if (tx_buf_count) {
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- nb_tx = rte_sched_port_enqueue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - nb_tx);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
- p->tx_buf_count = tx_buf_count;
-
- if (tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_flush(void *port)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- if (p->tx_buf_count) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sched_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sched_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sched_reader_ops)
-struct rte_port_in_ops rte_port_sched_reader_ops = {
- .f_create = rte_port_sched_reader_create,
- .f_free = rte_port_sched_reader_free,
- .f_rx = rte_port_sched_reader_rx,
- .f_stats = rte_port_sched_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sched_writer_ops)
-struct rte_port_out_ops rte_port_sched_writer_ops = {
- .f_create = rte_port_sched_writer_create,
- .f_free = rte_port_sched_writer_free,
- .f_tx = rte_port_sched_writer_tx,
- .f_tx_bulk = rte_port_sched_writer_tx_bulk,
- .f_flush = rte_port_sched_writer_flush,
- .f_stats = rte_port_sched_writer_stats_read,
-};
diff --git a/lib/port/rte_port_sched.h b/lib/port/rte_port_sched.h
deleted file mode 100644
index 1bf08ae6a9..0000000000
--- a/lib/port/rte_port_sched.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SCHED_H__
-#define __INCLUDE_RTE_PORT_SCHED_H__
-
-/**
- * @file
- * RTE Port Hierarchical Scheduler
- *
- * sched_reader: input port built on top of pre-initialized rte_sched_port
- * sched_writer: output port built on top of pre-initialized rte_sched_port
- */
-
-#include <stdint.h>
-
-#include <rte_sched.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** sched_reader port parameters */
-struct rte_port_sched_reader_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-};
-
-/** sched_reader port operations */
-extern struct rte_port_in_ops rte_port_sched_reader_ops;
-
-/** sched_writer port parameters */
-struct rte_port_sched_writer_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-
- /** Recommended burst size. The actual burst size can be bigger or
- smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** sched_writer port operations */
-extern struct rte_port_out_ops rte_port_sched_writer_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_source_sink.c b/lib/port/rte_port_source_sink.c
deleted file mode 100644
index 0557e12506..0000000000
--- a/lib/port/rte_port_source_sink.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-#include <stdint.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-
-#ifdef RTE_PORT_PCAP
-#include <rte_ether.h>
-#include <pcap.h>
-#endif
-
-#include "rte_port_source_sink.h"
-
-#include "port_log.h"
-
-/*
- * Port SOURCE
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_source {
- struct rte_port_in_stats stats;
-
- struct rte_mempool *mempool;
-
- /* PCAP buffers and indices */
- uint8_t **pkts;
- uint8_t *pkt_buff;
- uint32_t *pkt_len;
- uint32_t n_pkts;
- uint32_t pkt_index;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_source_load(struct rte_port_source *port,
- const char *file_name,
- uint32_t n_bytes_per_pkt,
- int socket_id)
-{
- uint32_t n_pkts = 0;
- uint32_t i;
- uint32_t *pkt_len_aligns = NULL;
- size_t total_buff_len = 0;
- pcap_t *pcap_handle;
- char pcap_errbuf[PCAP_ERRBUF_SIZE];
- uint32_t max_len;
- struct pcap_pkthdr pcap_hdr;
- const uint8_t *pkt;
- uint8_t *buff = NULL;
- uint32_t pktmbuf_maxlen = (uint32_t)
- (rte_pktmbuf_data_room_size(port->mempool) -
- RTE_PKTMBUF_HEADROOM);
-
- if (n_bytes_per_pkt == 0)
- max_len = pktmbuf_maxlen;
- else
- max_len = RTE_MIN(n_bytes_per_pkt, pktmbuf_maxlen);
-
- /* first time open, get packet number */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- while ((pkt = pcap_next(pcap_handle, &pcap_hdr)) != NULL)
- n_pkts++;
-
- pcap_close(pcap_handle);
-
- port->pkt_len = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkt_len) * n_pkts), 0, socket_id);
- if (port->pkt_len == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- pkt_len_aligns = rte_malloc("PCAP",
- (sizeof(*pkt_len_aligns) * n_pkts), 0);
- if (pkt_len_aligns == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkts = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkts) * n_pkts), 0, socket_id);
- if (port->pkts == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- /* open 2nd time, get pkt_len */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pcap_next(pcap_handle, &pcap_hdr);
- port->pkt_len[i] = RTE_MIN(max_len, pcap_hdr.len);
- pkt_len_aligns[i] = RTE_CACHE_LINE_ROUNDUP(
- port->pkt_len[i]);
- total_buff_len += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- /* allocate a big trunk of data for pcap file load */
- buff = rte_zmalloc_socket("PCAP",
- total_buff_len, 0, socket_id);
- if (buff == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkt_buff = buff;
-
- /* open file one last time to copy the pkt content */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pkt = pcap_next(pcap_handle, &pcap_hdr);
- rte_memcpy(buff, pkt, port->pkt_len[i]);
- port->pkts[i] = buff;
- buff += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- port->n_pkts = n_pkts;
-
- rte_free(pkt_len_aligns);
-
- PORT_LOG(INFO, "Successfully load pcap file "
- "'%s' with %u pkts",
- file_name, port->n_pkts);
-
- return 0;
-
-error_exit:
- rte_free(pkt_len_aligns);
- rte_free(port->pkt_len);
- rte_free(port->pkts);
- rte_free(port->pkt_buff);
-
- return -1;
-}
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
- pcap_source_load(port, file_name, n_bytes, socket_id)
-
-#else /* RTE_PORT_PCAP */
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Source port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#endif /* RTE_PORT_PCAP */
-
-static void *
-rte_port_source_create(void *params, int socket_id)
-{
- struct rte_port_source_params *p =
- params;
- struct rte_port_source *port;
-
- /* Check input arguments*/
- if ((p == NULL) || (p->mempool == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->mempool = (struct rte_mempool *) p->mempool;
-
- if (p->file_name) {
- int status = PCAP_SOURCE_LOAD(port, p->file_name,
- p->n_bytes_per_pkt, socket_id);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_source_free(void *port)
-{
- struct rte_port_source *p =
- port;
-
- /* Check input parameters */
- if (p == NULL)
- return 0;
-
- rte_free(p->pkt_len);
- rte_free(p->pkts);
- rte_free(p->pkt_buff);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_source_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_source *p = port;
- uint32_t i;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- if (p->pkt_buff != NULL) {
- for (i = 0; i < n_pkts; i++) {
- uint8_t *pkt_data = rte_pktmbuf_mtod(pkts[i],
- uint8_t *);
-
- rte_memcpy(pkt_data, p->pkts[p->pkt_index],
- p->pkt_len[p->pkt_index]);
- pkts[i]->data_len = p->pkt_len[p->pkt_index];
- pkts[i]->pkt_len = pkts[i]->data_len;
-
- p->pkt_index++;
- if (p->pkt_index >= p->n_pkts)
- p->pkt_index = 0;
- }
- }
-
- RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(p, n_pkts);
-
- return n_pkts;
-}
-
-static int
-rte_port_source_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_source *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port SINK
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val) \
- (port->stats.n_pkts_in += val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val) \
- (port->stats.n_pkts_drop += val)
-
-#else
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sink {
- struct rte_port_out_stats stats;
-
- /* PCAP dumper handle and pkts number */
- void *dumper;
- uint32_t max_pkts;
- uint32_t pkt_index;
- uint32_t dump_finish;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_sink_open(struct rte_port_sink *port,
- const char *file_name,
- uint32_t max_n_pkts)
-{
- pcap_t *tx_pcap;
- pcap_dumper_t *pcap_dumper;
-
- /** Open a dead pcap handler for opening dumper file */
- tx_pcap = pcap_open_dead(DLT_EN10MB, 65535);
- if (tx_pcap == NULL) {
- PORT_LOG(ERR, "Cannot open pcap dead handler");
- return -1;
- }
-
- /* The dumper is created using the previous pcap_t reference */
- pcap_dumper = pcap_dump_open(tx_pcap, file_name);
- if (pcap_dumper == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "\"%s\" for writing", file_name);
- return -1;
- }
-
- port->dumper = pcap_dumper;
- port->max_pkts = max_n_pkts;
- port->pkt_index = 0;
- port->dump_finish = 0;
-
- PORT_LOG(INFO, "Ready to dump packets to file \"%s\"",
- file_name);
-
- return 0;
-}
-
-static void
-pcap_sink_write_pkt(struct rte_port_sink *port, struct rte_mbuf *mbuf)
-{
- uint8_t *pcap_dumper = (port->dumper);
- struct pcap_pkthdr pcap_hdr;
- uint8_t jumbo_pkt_buf[RTE_ETHER_MAX_JUMBO_FRAME_LEN];
- uint8_t *pkt;
-
- /* Maximum num packets already reached */
- if (port->dump_finish)
- return;
-
- pkt = rte_pktmbuf_mtod(mbuf, uint8_t *);
-
- pcap_hdr.len = mbuf->pkt_len;
- pcap_hdr.caplen = pcap_hdr.len;
- gettimeofday(&(pcap_hdr.ts), NULL);
-
- if (mbuf->nb_segs > 1) {
- struct rte_mbuf *jumbo_mbuf;
- uint32_t pkt_index = 0;
-
- /* if packet size longer than RTE_ETHER_MAX_JUMBO_FRAME_LEN,
- * ignore it.
- */
- if (mbuf->pkt_len > RTE_ETHER_MAX_JUMBO_FRAME_LEN)
- return;
-
- for (jumbo_mbuf = mbuf; jumbo_mbuf != NULL;
- jumbo_mbuf = jumbo_mbuf->next) {
- rte_memcpy(&jumbo_pkt_buf[pkt_index],
- rte_pktmbuf_mtod(jumbo_mbuf, uint8_t *),
- jumbo_mbuf->data_len);
- pkt_index += jumbo_mbuf->data_len;
- }
-
- jumbo_pkt_buf[pkt_index] = '\0';
-
- pkt = jumbo_pkt_buf;
- }
-
- pcap_dump(pcap_dumper, &pcap_hdr, pkt);
-
- port->pkt_index++;
-
- if ((port->max_pkts != 0) && (port->pkt_index >= port->max_pkts)) {
- port->dump_finish = 1;
- PORT_LOG(INFO, "Dumped %u packets to file",
- port->pkt_index);
- }
-
-}
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
- pcap_sink_open(port, file_name, max_n_pkts)
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) \
- pcap_sink_write_pkt(port, mbuf)
-
-#define PCAP_SINK_FLUSH_PKT(dumper) \
-do { \
- if (dumper) \
- pcap_dump_flush((pcap_dumper_t *)dumper); \
-} while (0)
-
-#define PCAP_SINK_CLOSE(dumper) \
-do { \
- if (dumper) \
- pcap_dump_close((pcap_dumper_t *)dumper); \
-} while (0)
-
-#else
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Sink port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) {}
-
-#define PCAP_SINK_FLUSH_PKT(dumper)
-
-#define PCAP_SINK_CLOSE(dumper)
-
-#endif
-
-static void *
-rte_port_sink_create(void *params, int socket_id)
-{
- struct rte_port_sink *port;
- struct rte_port_sink_params *p = params;
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- if (!p)
- return port;
-
- if (p->file_name) {
- int status = PCAP_SINK_OPEN(port, p->file_name,
- p->max_n_pkts);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_sink_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sink *p = port;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- if (p->dumper != NULL)
- PCAP_SINK_WRITE_PKT(p, pkt);
- rte_pktmbuf_free(pkt);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
-
- return 0;
-}
-
-static int
-rte_port_sink_tx_bulk(void *port, struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sink *p = port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, n_pkts);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, n_pkts);
-
- if (p->dumper) {
- for (i = 0; i < n_pkts; i++)
- PCAP_SINK_WRITE_PKT(p, pkts[i]);
- }
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- rte_pktmbuf_free(pkt);
- }
-
- } else {
- if (p->dumper) {
- uint64_t dump_pkts_mask = pkts_mask;
- uint32_t pkt_index;
-
- for ( ; dump_pkts_mask; ) {
- pkt_index = rte_ctz64(
- dump_pkts_mask);
- PCAP_SINK_WRITE_PKT(p, pkts[pkt_index]);
- dump_pkts_mask &= ~(1LLU << pkt_index);
- }
- }
-
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
- rte_pktmbuf_free(pkt);
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sink_flush(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_FLUSH_PKT(p->dumper);
-
- return 0;
-}
-
-static int
-rte_port_sink_free(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_CLOSE(p->dumper);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_sink_stats_read(void *port, struct rte_port_out_stats *stats,
- int clear)
-{
- struct rte_port_sink *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_source_ops)
-struct rte_port_in_ops rte_port_source_ops = {
- .f_create = rte_port_source_create,
- .f_free = rte_port_source_free,
- .f_rx = rte_port_source_rx,
- .f_stats = rte_port_source_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sink_ops)
-struct rte_port_out_ops rte_port_sink_ops = {
- .f_create = rte_port_sink_create,
- .f_free = rte_port_sink_free,
- .f_tx = rte_port_sink_tx,
- .f_tx_bulk = rte_port_sink_tx_bulk,
- .f_flush = rte_port_sink_flush,
- .f_stats = rte_port_sink_stats_read,
-};
diff --git a/lib/port/rte_port_source_sink.h b/lib/port/rte_port_source_sink.h
deleted file mode 100644
index 3122dd5038..0000000000
--- a/lib/port/rte_port_source_sink.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-#define __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-
-/**
- * @file
- * RTE Port Source/Sink
- *
- * source: input port that can be used to generate packets
- * sink: output port that drops all packets written to it
- */
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** source port parameters */
-struct rte_port_source_params {
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-
- /** The full path of the pcap file to read packets from */
- const char *file_name;
- /** The number of bytes to be read from each packet in the
- * pcap file. If this value is 0, the whole packet is read;
- * if it is bigger than packet size, the generated packets
- * will contain the whole packet */
- uint32_t n_bytes_per_pkt;
-};
-
-/** source port operations */
-extern struct rte_port_in_ops rte_port_source_ops;
-
-/** sink port parameters */
-struct rte_port_sink_params {
- /** The full path of the pcap file to write the packets to */
- const char *file_name;
- /** The maximum number of packets write to the pcap file.
- * If this value is 0, the "infinite" write will be carried
- * out.
- */
- uint32_t max_n_pkts;
-};
-
-/** sink port operations */
-extern struct rte_port_out_ops rte_port_sink_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sym_crypto.c b/lib/port/rte_port_sym_crypto.c
deleted file mode 100644
index 30c9d1283e..0000000000
--- a/lib/port/rte_port_sym_crypto.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sym_crypto.h"
-
-#include "port_log.h"
-
-/*
- * Port Crypto Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_reader {
- struct rte_port_in_stats stats;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- struct rte_crypto_op *ops[RTE_PORT_IN_BURST_SIZE_MAX];
- rte_port_sym_crypto_reader_callback_fn f_callback;
- void *arg_callback;
-};
-
-static void *
-rte_port_sym_crypto_reader_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_reader_params *conf =
- params;
- struct rte_port_sym_crypto_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->f_callback = conf->f_callback;
- port->arg_callback = conf->arg_callback;
-
- return port;
-}
-
-static int
-rte_port_sym_crypto_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
- uint16_t rx_ops_cnt, i, n = 0;
-
- rx_ops_cnt = rte_cryptodev_dequeue_burst(p->cryptodev_id, p->queue_id,
- p->ops, n_pkts);
-
- for (i = 0; i < rx_ops_cnt; i++) {
- struct rte_crypto_op *op = p->ops[i];
-
- /** Drop failed pkts */
- if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)) {
- rte_pktmbuf_free(op->sym->m_src);
- continue;
- }
-
- pkts[n++] = op->sym->m_src;
- }
-
- if (p->f_callback)
- (*p->f_callback)(pkts, n, p->arg_callback);
-
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(p, n);
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(p, rx_ops_cnt - n);
-
- return n;
-}
-
-static int
-rte_port_sym_crypto_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_params *conf =
- params;
- struct rte_port_sym_crypto_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_sym_crypto_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count -
- nb_tx);
- for (; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_flush(void *port)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_nodrop_params *conf =
- params;
- struct rte_port_sym_crypto_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_sym_crypto_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_cryptodev_enqueue_burst(p->cryptodev_id,
- p->queue_id, p->tx_buf + nb_tx,
- p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p,
- 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_flush(void *port)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_reader_ops)
-struct rte_port_in_ops rte_port_sym_crypto_reader_ops = {
- .f_create = rte_port_sym_crypto_reader_create,
- .f_free = rte_port_sym_crypto_reader_free,
- .f_rx = rte_port_sym_crypto_reader_rx,
- .f_stats = rte_port_sym_crypto_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_ops = {
- .f_create = rte_port_sym_crypto_writer_create,
- .f_free = rte_port_sym_crypto_writer_free,
- .f_tx = rte_port_sym_crypto_writer_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_flush,
- .f_stats = rte_port_sym_crypto_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops = {
- .f_create = rte_port_sym_crypto_writer_nodrop_create,
- .f_free = rte_port_sym_crypto_writer_nodrop_free,
- .f_tx = rte_port_sym_crypto_writer_nodrop_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_nodrop_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_nodrop_flush,
- .f_stats = rte_port_sym_crypto_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_sym_crypto.h b/lib/port/rte_port_sym_crypto.h
deleted file mode 100644
index d03cdc1e8b..0000000000
--- a/lib/port/rte_port_sym_crypto.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-#define __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-
-/**
- * @file
- * RTE Port sym crypto Interface
- *
- * crypto_reader: input port built on top of pre-initialized crypto interface
- * crypto_writer: output port built on top of pre-initialized crypto interface
- */
-
-#include <stdint.h>
-
-#include <rte_cryptodev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Function prototype for reader post action. */
-typedef void (*rte_port_sym_crypto_reader_callback_fn)(struct rte_mbuf **pkts,
- uint16_t n_pkts, void *arg);
-
-/** Crypto_reader port parameters */
-struct rte_port_sym_crypto_reader_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** Crypto reader post callback function. */
- rte_port_sym_crypto_reader_callback_fn f_callback;
-
- /** Crypto reader post callback function arguments. */
- void *arg_callback;
-};
-
-/** Crypto_reader port operations. */
-extern struct rte_port_in_ops rte_port_sym_crypto_reader_ops;
-
-
-/** Crypto_writer port parameters. */
-struct rte_port_sym_crypto_writer_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-};
-
-/** Crypto_writer port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_ops;
-
-/** Crypto_writer_nodrop port parameters. */
-struct rte_port_sym_crypto_writer_nodrop_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev queue pair id. */
- uint16_t queue_id;
-
- /** Offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Crypto_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH 0/6] remove legacy Packet Framework API
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (4 preceding siblings ...)
2026-07-24 16:44 ` [RFC 6/6] port: " Stephen Hemminger
@ 2026-07-25 7:54 ` David Marchand
2026-07-25 13:36 ` Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 0/6] remove legacy packet framework Stephen Hemminger
` (9 subsequent siblings)
15 siblings, 1 reply; 29+ messages in thread
From: David Marchand @ 2026-07-25 7:54 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On Fri, 24 Jul 2026 at 18:45, Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> The legacy Packet Framework APIs were announced for removal in the
> 24.11 release but the removal never happened:
>
> * pipeline: The pipeline library legacy API (functions rte_pipeline_*)
> * table: The table library legacy API (functions rte_table_*)
> * port: The port library legacy API (functions rte_port_*)
>
> Do the removal now, in the 26.11 ABI window. The SWX API in the same
> libraries (rte_swx_*) is unaffected and remains the Packet Framework
> API. The softnic driver and the pipeline example already use only the
> SWX API.
>
> The applications built on the legacy API (test-pipeline, ip_pipeline)
> and the unit tests are removed first, then the legacy half of each
> library, pipeline before table before port to follow the dependency
> chain. Library dependencies and the programmer's guide are trimmed
> accordingly.
>
> Follow-up candidates, kept out of this series: the stale comments in
> lib/ethdev/ethdev_trace.h still refer to examples/ip_pipeline, and
> struct rte_pipeline_acl_rule in the removed rte_table_acl.c was only
> a local name.
>
>
> Stephen Hemminger (6):
> app/test: remove packet framework tests
> app/test-pipeline: remove application
> examples/ip_pipeline: remove example
> pipeline: remove legacy API
> table: remove legacy API
> port: remove legacy API
>
> MAINTAINERS | 5 -
> app/meson.build | 1 -
> app/test-pipeline/config.c | 230 -
> app/test-pipeline/init.c | 273 -
> app/test-pipeline/main.c | 188 -
> app/test-pipeline/main.h | 132 -
> app/test-pipeline/meson.build | 21 -
> app/test-pipeline/pipeline_acl.c | 251 -
> app/test-pipeline/pipeline_hash.c | 471 --
> app/test-pipeline/pipeline_lpm.c | 175 -
> app/test-pipeline/pipeline_lpm_ipv6.c | 168 -
> app/test-pipeline/pipeline_stub.c | 137 -
> app/test-pipeline/runtime.c | 160 -
> app/test/meson.build | 6 -
> app/test/test_table.c | 209 -
> app/test/test_table.h | 184 -
> app/test/test_table_acl.c | 728 --
> app/test/test_table_acl.h | 6 -
> app/test/test_table_combined.c | 846 --
> app/test/test_table_combined.h | 27 -
> app/test/test_table_pipeline.c | 575 --
> app/test/test_table_pipeline.h | 6 -
> app/test/test_table_ports.c | 195 -
> app/test/test_table_ports.h | 13 -
> app/test/test_table_tables.c | 1058 ---
> app/test/test_table_tables.h | 22 -
> doc/api/doxy-api-index.md | 17 -
> doc/guides/nics/softnic.rst | 3 +-
> doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
> doc/guides/prog_guide/img/figure33.png | Bin 65216 -> 0 bytes
> doc/guides/prog_guide/img/figure34.png | Bin 11581 -> 0 bytes
> doc/guides/prog_guide/img/figure35.png | Bin 75012 -> 0 bytes
> doc/guides/prog_guide/img/figure37.png | Bin 6934 -> 0 bytes
> doc/guides/prog_guide/img/figure38.png | Bin 7372 -> 0 bytes
> doc/guides/prog_guide/img/figure39.png | Bin 55986 -> 0 bytes
> doc/guides/prog_guide/packet_framework.rst | 1146 +--
> doc/guides/rel_notes/deprecation.rst | 15 -
> doc/guides/rel_notes/release_26_11.rst | 17 +
> .../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
> doc/guides/sample_app_ug/index.rst | 2 -
> doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
> doc/guides/sample_app_ug/test_pipeline.rst | 237 -
> examples/ip_pipeline/Makefile | 60 -
> examples/ip_pipeline/action.c | 391 -
> examples/ip_pipeline/action.h | 78 -
> examples/ip_pipeline/cli.c | 6791 -----------------
> examples/ip_pipeline/cli.h | 18 -
> examples/ip_pipeline/common.h | 12 -
> examples/ip_pipeline/conn.c | 330 -
> examples/ip_pipeline/conn.h | 47 -
> examples/ip_pipeline/cryptodev.c | 160 -
> examples/ip_pipeline/cryptodev.h | 46 -
> examples/ip_pipeline/examples/firewall.cli | 59 -
> examples/ip_pipeline/examples/flow.cli | 60 -
> examples/ip_pipeline/examples/flow_crypto.cli | 57 -
> examples/ip_pipeline/examples/l2fwd.cli | 51 -
> examples/ip_pipeline/examples/route.cli | 60 -
> examples/ip_pipeline/examples/route_ecmp.cli | 57 -
> examples/ip_pipeline/examples/rss.cli | 112 -
> examples/ip_pipeline/examples/tap.cli | 66 -
> examples/ip_pipeline/link.c | 270 -
> examples/ip_pipeline/link.h | 66 -
> examples/ip_pipeline/main.c | 260 -
> examples/ip_pipeline/mempool.c | 82 -
> examples/ip_pipeline/mempool.h | 40 -
> examples/ip_pipeline/meson.build | 30 -
> examples/ip_pipeline/parser.c | 506 --
> examples/ip_pipeline/parser.h | 56 -
> examples/ip_pipeline/pipeline.c | 1078 ---
> examples/ip_pipeline/pipeline.h | 425 --
> examples/ip_pipeline/swq.c | 76 -
> examples/ip_pipeline/swq.h | 37 -
> examples/ip_pipeline/tap.c | 102 -
> examples/ip_pipeline/tap.h | 29 -
> examples/ip_pipeline/thread.c | 3137 --------
> examples/ip_pipeline/thread.h | 24 -
> examples/ip_pipeline/tmgr.c | 248 -
> examples/ip_pipeline/tmgr.h | 74 -
> examples/meson.build | 1 -
> lib/pipeline/meson.build | 8 +-
> lib/pipeline/rte_pipeline.c | 1640 ----
> lib/pipeline/rte_pipeline.h | 840 --
> lib/pipeline/rte_port_in_action.c | 539 --
> lib/pipeline/rte_port_in_action.h | 311 -
> lib/pipeline/rte_table_action.c | 3483 ---------
> lib/pipeline/rte_table_action.h | 1137 ---
> lib/port/meson.build | 22 +-
> lib/port/port_log.c | 7 -
> lib/port/port_log.h | 11 -
> lib/port/rte_port.h | 223 -
> lib/port/rte_port_ethdev.c | 530 --
> lib/port/rte_port_ethdev.h | 75 -
> lib/port/rte_port_eventdev.c | 590 --
> lib/port/rte_port_eventdev.h | 94 -
> lib/port/rte_port_fd.c | 524 --
> lib/port/rte_port_fd.h | 74 -
> lib/port/rte_port_frag.c | 280 -
> lib/port/rte_port_frag.h | 70 -
> lib/port/rte_port_ras.c | 336 -
> lib/port/rte_port_ras.h | 58 -
> lib/port/rte_port_ring.c | 796 --
> lib/port/rte_port_ring.h | 91 -
> lib/port/rte_port_sched.c | 298 -
> lib/port/rte_port_sched.h | 52 -
> lib/port/rte_port_source_sink.c | 616 --
> lib/port/rte_port_source_sink.h | 57 -
> lib/port/rte_port_sym_crypto.c | 558 --
> lib/port/rte_port_sym_crypto.h | 92 -
> lib/table/meson.build | 30 +-
> lib/table/rte_lru.h | 85 -
> lib/table/rte_lru_arm64.h | 61 -
> lib/table/rte_lru_x86.h | 96 -
> lib/table/rte_table.h | 263 -
> lib/table/rte_table_acl.c | 795 --
> lib/table/rte_table_acl.h | 65 -
> lib/table/rte_table_array.c | 210 -
> lib/table/rte_table_array.h | 46 -
> lib/table/rte_table_hash.h | 106 -
> lib/table/rte_table_hash_cuckoo.c | 327 -
> lib/table/rte_table_hash_cuckoo.h | 57 -
> lib/table/rte_table_hash_ext.c | 1011 ---
> lib/table/rte_table_hash_func.h | 263 -
> lib/table/rte_table_hash_func_arm64.h | 21 -
> lib/table/rte_table_hash_key16.c | 1190 ---
> lib/table/rte_table_hash_key32.c | 1223 ---
> lib/table/rte_table_hash_key8.c | 1157 ---
> lib/table/rte_table_hash_lru.c | 959 ---
> lib/table/rte_table_lpm.c | 369 -
> lib/table/rte_table_lpm.h | 94 -
> lib/table/rte_table_lpm_ipv6.c | 370 -
> lib/table/rte_table_lpm_ipv6.h | 95 -
> lib/table/rte_table_stub.c | 95 -
> lib/table/rte_table_stub.h | 30 -
> lib/table/table_log.c | 7 -
> lib/table/table_log.h | 11 -
> 135 files changed, 27 insertions(+), 45472 deletions(-)
> delete mode 100644 app/test-pipeline/config.c
> delete mode 100644 app/test-pipeline/init.c
> delete mode 100644 app/test-pipeline/main.c
> delete mode 100644 app/test-pipeline/main.h
> delete mode 100644 app/test-pipeline/meson.build
> delete mode 100644 app/test-pipeline/pipeline_acl.c
> delete mode 100644 app/test-pipeline/pipeline_hash.c
> delete mode 100644 app/test-pipeline/pipeline_lpm.c
> delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
> delete mode 100644 app/test-pipeline/pipeline_stub.c
> delete mode 100644 app/test-pipeline/runtime.c
> delete mode 100644 app/test/test_table.c
> delete mode 100644 app/test/test_table.h
> delete mode 100644 app/test/test_table_acl.c
> delete mode 100644 app/test/test_table_acl.h
> delete mode 100644 app/test/test_table_combined.c
> delete mode 100644 app/test/test_table_combined.h
> delete mode 100644 app/test/test_table_pipeline.c
> delete mode 100644 app/test/test_table_pipeline.h
> delete mode 100644 app/test/test_table_ports.c
> delete mode 100644 app/test/test_table_ports.h
> delete mode 100644 app/test/test_table_tables.c
> delete mode 100644 app/test/test_table_tables.h
> delete mode 100644 doc/guides/prog_guide/img/figure32.png
> delete mode 100644 doc/guides/prog_guide/img/figure33.png
> delete mode 100644 doc/guides/prog_guide/img/figure34.png
> delete mode 100644 doc/guides/prog_guide/img/figure35.png
> delete mode 100644 doc/guides/prog_guide/img/figure37.png
> delete mode 100644 doc/guides/prog_guide/img/figure38.png
> delete mode 100644 doc/guides/prog_guide/img/figure39.png
> delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
> delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
> delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
> delete mode 100644 examples/ip_pipeline/Makefile
> delete mode 100644 examples/ip_pipeline/action.c
> delete mode 100644 examples/ip_pipeline/action.h
> delete mode 100644 examples/ip_pipeline/cli.c
> delete mode 100644 examples/ip_pipeline/cli.h
> delete mode 100644 examples/ip_pipeline/common.h
> delete mode 100644 examples/ip_pipeline/conn.c
> delete mode 100644 examples/ip_pipeline/conn.h
> delete mode 100644 examples/ip_pipeline/cryptodev.c
> delete mode 100644 examples/ip_pipeline/cryptodev.h
> delete mode 100644 examples/ip_pipeline/examples/firewall.cli
> delete mode 100644 examples/ip_pipeline/examples/flow.cli
> delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
> delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
> delete mode 100644 examples/ip_pipeline/examples/route.cli
> delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
> delete mode 100644 examples/ip_pipeline/examples/rss.cli
> delete mode 100644 examples/ip_pipeline/examples/tap.cli
> delete mode 100644 examples/ip_pipeline/link.c
> delete mode 100644 examples/ip_pipeline/link.h
> delete mode 100644 examples/ip_pipeline/main.c
> delete mode 100644 examples/ip_pipeline/mempool.c
> delete mode 100644 examples/ip_pipeline/mempool.h
> delete mode 100644 examples/ip_pipeline/meson.build
> delete mode 100644 examples/ip_pipeline/parser.c
> delete mode 100644 examples/ip_pipeline/parser.h
> delete mode 100644 examples/ip_pipeline/pipeline.c
> delete mode 100644 examples/ip_pipeline/pipeline.h
> delete mode 100644 examples/ip_pipeline/swq.c
> delete mode 100644 examples/ip_pipeline/swq.h
> delete mode 100644 examples/ip_pipeline/tap.c
> delete mode 100644 examples/ip_pipeline/tap.h
> delete mode 100644 examples/ip_pipeline/thread.c
> delete mode 100644 examples/ip_pipeline/thread.h
> delete mode 100644 examples/ip_pipeline/tmgr.c
> delete mode 100644 examples/ip_pipeline/tmgr.h
> delete mode 100644 lib/pipeline/rte_pipeline.c
> delete mode 100644 lib/pipeline/rte_pipeline.h
> delete mode 100644 lib/pipeline/rte_port_in_action.c
> delete mode 100644 lib/pipeline/rte_port_in_action.h
> delete mode 100644 lib/pipeline/rte_table_action.c
> delete mode 100644 lib/pipeline/rte_table_action.h
> delete mode 100644 lib/port/port_log.c
> delete mode 100644 lib/port/port_log.h
> delete mode 100644 lib/port/rte_port.h
> delete mode 100644 lib/port/rte_port_ethdev.c
> delete mode 100644 lib/port/rte_port_ethdev.h
> delete mode 100644 lib/port/rte_port_eventdev.c
> delete mode 100644 lib/port/rte_port_eventdev.h
> delete mode 100644 lib/port/rte_port_fd.c
> delete mode 100644 lib/port/rte_port_fd.h
> delete mode 100644 lib/port/rte_port_frag.c
> delete mode 100644 lib/port/rte_port_frag.h
> delete mode 100644 lib/port/rte_port_ras.c
> delete mode 100644 lib/port/rte_port_ras.h
> delete mode 100644 lib/port/rte_port_ring.c
> delete mode 100644 lib/port/rte_port_ring.h
> delete mode 100644 lib/port/rte_port_sched.c
> delete mode 100644 lib/port/rte_port_sched.h
> delete mode 100644 lib/port/rte_port_source_sink.c
> delete mode 100644 lib/port/rte_port_source_sink.h
> delete mode 100644 lib/port/rte_port_sym_crypto.c
> delete mode 100644 lib/port/rte_port_sym_crypto.h
> delete mode 100644 lib/table/rte_lru.h
> delete mode 100644 lib/table/rte_lru_arm64.h
> delete mode 100644 lib/table/rte_lru_x86.h
> delete mode 100644 lib/table/rte_table.h
> delete mode 100644 lib/table/rte_table_acl.c
> delete mode 100644 lib/table/rte_table_acl.h
> delete mode 100644 lib/table/rte_table_array.c
> delete mode 100644 lib/table/rte_table_array.h
> delete mode 100644 lib/table/rte_table_hash.h
> delete mode 100644 lib/table/rte_table_hash_cuckoo.c
> delete mode 100644 lib/table/rte_table_hash_cuckoo.h
> delete mode 100644 lib/table/rte_table_hash_ext.c
> delete mode 100644 lib/table/rte_table_hash_func.h
> delete mode 100644 lib/table/rte_table_hash_func_arm64.h
> delete mode 100644 lib/table/rte_table_hash_key16.c
> delete mode 100644 lib/table/rte_table_hash_key32.c
> delete mode 100644 lib/table/rte_table_hash_key8.c
> delete mode 100644 lib/table/rte_table_hash_lru.c
> delete mode 100644 lib/table/rte_table_lpm.c
> delete mode 100644 lib/table/rte_table_lpm.h
> delete mode 100644 lib/table/rte_table_lpm_ipv6.c
> delete mode 100644 lib/table/rte_table_lpm_ipv6.h
> delete mode 100644 lib/table/rte_table_stub.c
> delete mode 100644 lib/table/rte_table_stub.h
> delete mode 100644 lib/table/table_log.c
> delete mode 100644 lib/table/table_log.h
Sorry, it seems this series (and only this series iiuc) fell through
the cracks while patchwork and other dpdk.org services were under
heavy load...
Could you resend?
--
David Marchand
^ permalink raw reply [flat|nested] 29+ messages in thread* Re: [PATCH 0/6] remove legacy Packet Framework API
2026-07-25 7:54 ` [PATCH 0/6] remove legacy Packet Framework API David Marchand
@ 2026-07-25 13:36 ` Stephen Hemminger
0 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-25 13:36 UTC (permalink / raw)
To: David Marchand; +Cc: dev
On Sat, 25 Jul 2026 09:54:48 +0200
David Marchand <david.marchand@redhat.com> wrote:
> On Fri, 24 Jul 2026 at 18:45, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> >
> > The legacy Packet Framework APIs were announced for removal in the
> > 24.11 release but the removal never happened:
> >
> > * pipeline: The pipeline library legacy API (functions rte_pipeline_*)
> > * table: The table library legacy API (functions rte_table_*)
> > * port: The port library legacy API (functions rte_port_*)
> >
> > Do the removal now, in the 26.11 ABI window. The SWX API in the same
> > libraries (rte_swx_*) is unaffected and remains the Packet Framework
> > API. The softnic driver and the pipeline example already use only the
> > SWX API.
> >
> > The applications built on the legacy API (test-pipeline, ip_pipeline)
> > and the unit tests are removed first, then the legacy half of each
> > library, pipeline before table before port to follow the dependency
> > chain. Library dependencies and the programmer's guide are trimmed
> > accordingly.
> >
> > Follow-up candidates, kept out of this series: the stale comments in
> > lib/ethdev/ethdev_trace.h still refer to examples/ip_pipeline, and
> > struct rte_pipeline_acl_rule in the removed rte_table_acl.c was only
> > a local name.
> >
> >
> > Stephen Hemminger (6):
> > app/test: remove packet framework tests
> > app/test-pipeline: remove application
> > examples/ip_pipeline: remove example
> > pipeline: remove legacy API
> > table: remove legacy API
> > port: remove legacy API
> >
> > MAINTAINERS | 5 -
> > app/meson.build | 1 -
> > app/test-pipeline/config.c | 230 -
> > app/test-pipeline/init.c | 273 -
> > app/test-pipeline/main.c | 188 -
> > app/test-pipeline/main.h | 132 -
> > app/test-pipeline/meson.build | 21 -
> > app/test-pipeline/pipeline_acl.c | 251 -
> > app/test-pipeline/pipeline_hash.c | 471 --
> > app/test-pipeline/pipeline_lpm.c | 175 -
> > app/test-pipeline/pipeline_lpm_ipv6.c | 168 -
> > app/test-pipeline/pipeline_stub.c | 137 -
> > app/test-pipeline/runtime.c | 160 -
> > app/test/meson.build | 6 -
> > app/test/test_table.c | 209 -
> > app/test/test_table.h | 184 -
> > app/test/test_table_acl.c | 728 --
> > app/test/test_table_acl.h | 6 -
> > app/test/test_table_combined.c | 846 --
> > app/test/test_table_combined.h | 27 -
> > app/test/test_table_pipeline.c | 575 --
> > app/test/test_table_pipeline.h | 6 -
> > app/test/test_table_ports.c | 195 -
> > app/test/test_table_ports.h | 13 -
> > app/test/test_table_tables.c | 1058 ---
> > app/test/test_table_tables.h | 22 -
> > doc/api/doxy-api-index.md | 17 -
> > doc/guides/nics/softnic.rst | 3 +-
> > doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
> > doc/guides/prog_guide/img/figure33.png | Bin 65216 -> 0 bytes
> > doc/guides/prog_guide/img/figure34.png | Bin 11581 -> 0 bytes
> > doc/guides/prog_guide/img/figure35.png | Bin 75012 -> 0 bytes
> > doc/guides/prog_guide/img/figure37.png | Bin 6934 -> 0 bytes
> > doc/guides/prog_guide/img/figure38.png | Bin 7372 -> 0 bytes
> > doc/guides/prog_guide/img/figure39.png | Bin 55986 -> 0 bytes
> > doc/guides/prog_guide/packet_framework.rst | 1146 +--
> > doc/guides/rel_notes/deprecation.rst | 15 -
> > doc/guides/rel_notes/release_26_11.rst | 17 +
> > .../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
> > doc/guides/sample_app_ug/index.rst | 2 -
> > doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
> > doc/guides/sample_app_ug/test_pipeline.rst | 237 -
> > examples/ip_pipeline/Makefile | 60 -
> > examples/ip_pipeline/action.c | 391 -
> > examples/ip_pipeline/action.h | 78 -
> > examples/ip_pipeline/cli.c | 6791 -----------------
> > examples/ip_pipeline/cli.h | 18 -
> > examples/ip_pipeline/common.h | 12 -
> > examples/ip_pipeline/conn.c | 330 -
> > examples/ip_pipeline/conn.h | 47 -
> > examples/ip_pipeline/cryptodev.c | 160 -
> > examples/ip_pipeline/cryptodev.h | 46 -
> > examples/ip_pipeline/examples/firewall.cli | 59 -
> > examples/ip_pipeline/examples/flow.cli | 60 -
> > examples/ip_pipeline/examples/flow_crypto.cli | 57 -
> > examples/ip_pipeline/examples/l2fwd.cli | 51 -
> > examples/ip_pipeline/examples/route.cli | 60 -
> > examples/ip_pipeline/examples/route_ecmp.cli | 57 -
> > examples/ip_pipeline/examples/rss.cli | 112 -
> > examples/ip_pipeline/examples/tap.cli | 66 -
> > examples/ip_pipeline/link.c | 270 -
> > examples/ip_pipeline/link.h | 66 -
> > examples/ip_pipeline/main.c | 260 -
> > examples/ip_pipeline/mempool.c | 82 -
> > examples/ip_pipeline/mempool.h | 40 -
> > examples/ip_pipeline/meson.build | 30 -
> > examples/ip_pipeline/parser.c | 506 --
> > examples/ip_pipeline/parser.h | 56 -
> > examples/ip_pipeline/pipeline.c | 1078 ---
> > examples/ip_pipeline/pipeline.h | 425 --
> > examples/ip_pipeline/swq.c | 76 -
> > examples/ip_pipeline/swq.h | 37 -
> > examples/ip_pipeline/tap.c | 102 -
> > examples/ip_pipeline/tap.h | 29 -
> > examples/ip_pipeline/thread.c | 3137 --------
> > examples/ip_pipeline/thread.h | 24 -
> > examples/ip_pipeline/tmgr.c | 248 -
> > examples/ip_pipeline/tmgr.h | 74 -
> > examples/meson.build | 1 -
> > lib/pipeline/meson.build | 8 +-
> > lib/pipeline/rte_pipeline.c | 1640 ----
> > lib/pipeline/rte_pipeline.h | 840 --
> > lib/pipeline/rte_port_in_action.c | 539 --
> > lib/pipeline/rte_port_in_action.h | 311 -
> > lib/pipeline/rte_table_action.c | 3483 ---------
> > lib/pipeline/rte_table_action.h | 1137 ---
> > lib/port/meson.build | 22 +-
> > lib/port/port_log.c | 7 -
> > lib/port/port_log.h | 11 -
> > lib/port/rte_port.h | 223 -
> > lib/port/rte_port_ethdev.c | 530 --
> > lib/port/rte_port_ethdev.h | 75 -
> > lib/port/rte_port_eventdev.c | 590 --
> > lib/port/rte_port_eventdev.h | 94 -
> > lib/port/rte_port_fd.c | 524 --
> > lib/port/rte_port_fd.h | 74 -
> > lib/port/rte_port_frag.c | 280 -
> > lib/port/rte_port_frag.h | 70 -
> > lib/port/rte_port_ras.c | 336 -
> > lib/port/rte_port_ras.h | 58 -
> > lib/port/rte_port_ring.c | 796 --
> > lib/port/rte_port_ring.h | 91 -
> > lib/port/rte_port_sched.c | 298 -
> > lib/port/rte_port_sched.h | 52 -
> > lib/port/rte_port_source_sink.c | 616 --
> > lib/port/rte_port_source_sink.h | 57 -
> > lib/port/rte_port_sym_crypto.c | 558 --
> > lib/port/rte_port_sym_crypto.h | 92 -
> > lib/table/meson.build | 30 +-
> > lib/table/rte_lru.h | 85 -
> > lib/table/rte_lru_arm64.h | 61 -
> > lib/table/rte_lru_x86.h | 96 -
> > lib/table/rte_table.h | 263 -
> > lib/table/rte_table_acl.c | 795 --
> > lib/table/rte_table_acl.h | 65 -
> > lib/table/rte_table_array.c | 210 -
> > lib/table/rte_table_array.h | 46 -
> > lib/table/rte_table_hash.h | 106 -
> > lib/table/rte_table_hash_cuckoo.c | 327 -
> > lib/table/rte_table_hash_cuckoo.h | 57 -
> > lib/table/rte_table_hash_ext.c | 1011 ---
> > lib/table/rte_table_hash_func.h | 263 -
> > lib/table/rte_table_hash_func_arm64.h | 21 -
> > lib/table/rte_table_hash_key16.c | 1190 ---
> > lib/table/rte_table_hash_key32.c | 1223 ---
> > lib/table/rte_table_hash_key8.c | 1157 ---
> > lib/table/rte_table_hash_lru.c | 959 ---
> > lib/table/rte_table_lpm.c | 369 -
> > lib/table/rte_table_lpm.h | 94 -
> > lib/table/rte_table_lpm_ipv6.c | 370 -
> > lib/table/rte_table_lpm_ipv6.h | 95 -
> > lib/table/rte_table_stub.c | 95 -
> > lib/table/rte_table_stub.h | 30 -
> > lib/table/table_log.c | 7 -
> > lib/table/table_log.h | 11 -
> > 135 files changed, 27 insertions(+), 45472 deletions(-)
> > delete mode 100644 app/test-pipeline/config.c
> > delete mode 100644 app/test-pipeline/init.c
> > delete mode 100644 app/test-pipeline/main.c
> > delete mode 100644 app/test-pipeline/main.h
> > delete mode 100644 app/test-pipeline/meson.build
> > delete mode 100644 app/test-pipeline/pipeline_acl.c
> > delete mode 100644 app/test-pipeline/pipeline_hash.c
> > delete mode 100644 app/test-pipeline/pipeline_lpm.c
> > delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
> > delete mode 100644 app/test-pipeline/pipeline_stub.c
> > delete mode 100644 app/test-pipeline/runtime.c
> > delete mode 100644 app/test/test_table.c
> > delete mode 100644 app/test/test_table.h
> > delete mode 100644 app/test/test_table_acl.c
> > delete mode 100644 app/test/test_table_acl.h
> > delete mode 100644 app/test/test_table_combined.c
> > delete mode 100644 app/test/test_table_combined.h
> > delete mode 100644 app/test/test_table_pipeline.c
> > delete mode 100644 app/test/test_table_pipeline.h
> > delete mode 100644 app/test/test_table_ports.c
> > delete mode 100644 app/test/test_table_ports.h
> > delete mode 100644 app/test/test_table_tables.c
> > delete mode 100644 app/test/test_table_tables.h
> > delete mode 100644 doc/guides/prog_guide/img/figure32.png
> > delete mode 100644 doc/guides/prog_guide/img/figure33.png
> > delete mode 100644 doc/guides/prog_guide/img/figure34.png
> > delete mode 100644 doc/guides/prog_guide/img/figure35.png
> > delete mode 100644 doc/guides/prog_guide/img/figure37.png
> > delete mode 100644 doc/guides/prog_guide/img/figure38.png
> > delete mode 100644 doc/guides/prog_guide/img/figure39.png
> > delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
> > delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
> > delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
> > delete mode 100644 examples/ip_pipeline/Makefile
> > delete mode 100644 examples/ip_pipeline/action.c
> > delete mode 100644 examples/ip_pipeline/action.h
> > delete mode 100644 examples/ip_pipeline/cli.c
> > delete mode 100644 examples/ip_pipeline/cli.h
> > delete mode 100644 examples/ip_pipeline/common.h
> > delete mode 100644 examples/ip_pipeline/conn.c
> > delete mode 100644 examples/ip_pipeline/conn.h
> > delete mode 100644 examples/ip_pipeline/cryptodev.c
> > delete mode 100644 examples/ip_pipeline/cryptodev.h
> > delete mode 100644 examples/ip_pipeline/examples/firewall.cli
> > delete mode 100644 examples/ip_pipeline/examples/flow.cli
> > delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
> > delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
> > delete mode 100644 examples/ip_pipeline/examples/route.cli
> > delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
> > delete mode 100644 examples/ip_pipeline/examples/rss.cli
> > delete mode 100644 examples/ip_pipeline/examples/tap.cli
> > delete mode 100644 examples/ip_pipeline/link.c
> > delete mode 100644 examples/ip_pipeline/link.h
> > delete mode 100644 examples/ip_pipeline/main.c
> > delete mode 100644 examples/ip_pipeline/mempool.c
> > delete mode 100644 examples/ip_pipeline/mempool.h
> > delete mode 100644 examples/ip_pipeline/meson.build
> > delete mode 100644 examples/ip_pipeline/parser.c
> > delete mode 100644 examples/ip_pipeline/parser.h
> > delete mode 100644 examples/ip_pipeline/pipeline.c
> > delete mode 100644 examples/ip_pipeline/pipeline.h
> > delete mode 100644 examples/ip_pipeline/swq.c
> > delete mode 100644 examples/ip_pipeline/swq.h
> > delete mode 100644 examples/ip_pipeline/tap.c
> > delete mode 100644 examples/ip_pipeline/tap.h
> > delete mode 100644 examples/ip_pipeline/thread.c
> > delete mode 100644 examples/ip_pipeline/thread.h
> > delete mode 100644 examples/ip_pipeline/tmgr.c
> > delete mode 100644 examples/ip_pipeline/tmgr.h
> > delete mode 100644 lib/pipeline/rte_pipeline.c
> > delete mode 100644 lib/pipeline/rte_pipeline.h
> > delete mode 100644 lib/pipeline/rte_port_in_action.c
> > delete mode 100644 lib/pipeline/rte_port_in_action.h
> > delete mode 100644 lib/pipeline/rte_table_action.c
> > delete mode 100644 lib/pipeline/rte_table_action.h
> > delete mode 100644 lib/port/port_log.c
> > delete mode 100644 lib/port/port_log.h
> > delete mode 100644 lib/port/rte_port.h
> > delete mode 100644 lib/port/rte_port_ethdev.c
> > delete mode 100644 lib/port/rte_port_ethdev.h
> > delete mode 100644 lib/port/rte_port_eventdev.c
> > delete mode 100644 lib/port/rte_port_eventdev.h
> > delete mode 100644 lib/port/rte_port_fd.c
> > delete mode 100644 lib/port/rte_port_fd.h
> > delete mode 100644 lib/port/rte_port_frag.c
> > delete mode 100644 lib/port/rte_port_frag.h
> > delete mode 100644 lib/port/rte_port_ras.c
> > delete mode 100644 lib/port/rte_port_ras.h
> > delete mode 100644 lib/port/rte_port_ring.c
> > delete mode 100644 lib/port/rte_port_ring.h
> > delete mode 100644 lib/port/rte_port_sched.c
> > delete mode 100644 lib/port/rte_port_sched.h
> > delete mode 100644 lib/port/rte_port_source_sink.c
> > delete mode 100644 lib/port/rte_port_source_sink.h
> > delete mode 100644 lib/port/rte_port_sym_crypto.c
> > delete mode 100644 lib/port/rte_port_sym_crypto.h
> > delete mode 100644 lib/table/rte_lru.h
> > delete mode 100644 lib/table/rte_lru_arm64.h
> > delete mode 100644 lib/table/rte_lru_x86.h
> > delete mode 100644 lib/table/rte_table.h
> > delete mode 100644 lib/table/rte_table_acl.c
> > delete mode 100644 lib/table/rte_table_acl.h
> > delete mode 100644 lib/table/rte_table_array.c
> > delete mode 100644 lib/table/rte_table_array.h
> > delete mode 100644 lib/table/rte_table_hash.h
> > delete mode 100644 lib/table/rte_table_hash_cuckoo.c
> > delete mode 100644 lib/table/rte_table_hash_cuckoo.h
> > delete mode 100644 lib/table/rte_table_hash_ext.c
> > delete mode 100644 lib/table/rte_table_hash_func.h
> > delete mode 100644 lib/table/rte_table_hash_func_arm64.h
> > delete mode 100644 lib/table/rte_table_hash_key16.c
> > delete mode 100644 lib/table/rte_table_hash_key32.c
> > delete mode 100644 lib/table/rte_table_hash_key8.c
> > delete mode 100644 lib/table/rte_table_hash_lru.c
> > delete mode 100644 lib/table/rte_table_lpm.c
> > delete mode 100644 lib/table/rte_table_lpm.h
> > delete mode 100644 lib/table/rte_table_lpm_ipv6.c
> > delete mode 100644 lib/table/rte_table_lpm_ipv6.h
> > delete mode 100644 lib/table/rte_table_stub.c
> > delete mode 100644 lib/table/rte_table_stub.h
> > delete mode 100644 lib/table/table_log.c
> > delete mode 100644 lib/table/table_log.h
>
> Sorry, it seems this series (and only this series iiuc) fell through
> the cracks while patchwork and other dpdk.org services were under
> heavy load...
> Could you resend?
>
>
I suspect there maybe feedbacks, will send again on Monday.
^ permalink raw reply [flat|nested] 29+ messages in thread
* [RFC v2 0/6] remove legacy packet framework
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (5 preceding siblings ...)
2026-07-25 7:54 ` [PATCH 0/6] remove legacy Packet Framework API David Marchand
@ 2026-07-27 23:11 ` Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 1/6] app/test: remove packet framework tests Stephen Hemminger
` (4 more replies)
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
` (8 subsequent siblings)
15 siblings, 5 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-27 23:11 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
The legacy Packet Framework APIs were announced for removal in the
24.11 release but the removal never happened:
* pipeline: The pipeline library legacy API (functions rte_pipeline_*)
* table: The table library legacy API (functions rte_table_*)
* port: The port library legacy API (functions rte_port_*)
Do the removal now, in the 26.11 ABI window. The SWX API in the same
libraries (rte_swx_*) is unaffected and remains the Packet Framework
API. The softnic driver and the pipeline example already use only the
SWX API.
The applications built on the legacy API (test-pipeline, ip_pipeline)
and the unit tests are removed first, then the legacy half of each
library, pipeline before table before port to follow the dependency
chain. Library dependencies and the programmer's guide are trimmed
accordingly.
Stephen Hemminger (6):
app/test: remove packet framework tests
app/test-pipeline: remove application
examples/ip_pipeline: remove example
pipeline: remove legacy API
table: remove legacy API
port: remove legacy API
MAINTAINERS | 5 -
app/meson.build | 1 -
app/test-pipeline/config.c | 230 -
app/test-pipeline/init.c | 273 -
app/test-pipeline/main.c | 188 -
app/test-pipeline/main.h | 132 -
app/test-pipeline/meson.build | 21 -
app/test-pipeline/pipeline_acl.c | 251 -
app/test-pipeline/pipeline_hash.c | 471 --
app/test-pipeline/pipeline_lpm.c | 175 -
app/test-pipeline/pipeline_lpm_ipv6.c | 168 -
app/test-pipeline/pipeline_stub.c | 137 -
app/test-pipeline/runtime.c | 160 -
app/test/meson.build | 6 -
app/test/test_table.c | 209 -
app/test/test_table.h | 184 -
app/test/test_table_acl.c | 728 --
app/test/test_table_acl.h | 6 -
app/test/test_table_combined.c | 846 --
app/test/test_table_combined.h | 27 -
app/test/test_table_pipeline.c | 575 --
app/test/test_table_pipeline.h | 6 -
app/test/test_table_ports.c | 195 -
app/test/test_table_ports.h | 13 -
app/test/test_table_tables.c | 1058 ---
app/test/test_table_tables.h | 22 -
doc/api/doxy-api-index.md | 17 -
doc/guides/nics/softnic.rst | 3 +-
doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
doc/guides/prog_guide/img/figure33.png | Bin 65216 -> 0 bytes
doc/guides/prog_guide/img/figure34.png | Bin 11581 -> 0 bytes
doc/guides/prog_guide/img/figure35.png | Bin 75012 -> 0 bytes
doc/guides/prog_guide/img/figure37.png | Bin 6934 -> 0 bytes
doc/guides/prog_guide/img/figure38.png | Bin 7372 -> 0 bytes
doc/guides/prog_guide/img/figure39.png | Bin 55986 -> 0 bytes
doc/guides/prog_guide/packet_framework.rst | 1146 +--
doc/guides/rel_notes/deprecation.rst | 15 -
doc/guides/rel_notes/release_26_11.rst | 17 +
.../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
doc/guides/sample_app_ug/index.rst | 2 -
doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
doc/guides/sample_app_ug/test_pipeline.rst | 237 -
examples/ip_pipeline/Makefile | 60 -
examples/ip_pipeline/action.c | 391 -
examples/ip_pipeline/action.h | 78 -
examples/ip_pipeline/cli.c | 6791 -----------------
examples/ip_pipeline/cli.h | 18 -
examples/ip_pipeline/common.h | 12 -
examples/ip_pipeline/conn.c | 330 -
examples/ip_pipeline/conn.h | 47 -
examples/ip_pipeline/cryptodev.c | 160 -
examples/ip_pipeline/cryptodev.h | 46 -
examples/ip_pipeline/examples/firewall.cli | 59 -
examples/ip_pipeline/examples/flow.cli | 60 -
examples/ip_pipeline/examples/flow_crypto.cli | 57 -
examples/ip_pipeline/examples/l2fwd.cli | 51 -
examples/ip_pipeline/examples/route.cli | 60 -
examples/ip_pipeline/examples/route_ecmp.cli | 57 -
examples/ip_pipeline/examples/rss.cli | 112 -
examples/ip_pipeline/examples/tap.cli | 66 -
examples/ip_pipeline/link.c | 270 -
examples/ip_pipeline/link.h | 66 -
examples/ip_pipeline/main.c | 260 -
examples/ip_pipeline/mempool.c | 82 -
examples/ip_pipeline/mempool.h | 40 -
examples/ip_pipeline/meson.build | 30 -
examples/ip_pipeline/parser.c | 506 --
examples/ip_pipeline/parser.h | 56 -
examples/ip_pipeline/pipeline.c | 1078 ---
examples/ip_pipeline/pipeline.h | 425 --
examples/ip_pipeline/swq.c | 76 -
examples/ip_pipeline/swq.h | 37 -
examples/ip_pipeline/tap.c | 102 -
examples/ip_pipeline/tap.h | 29 -
examples/ip_pipeline/thread.c | 3137 --------
examples/ip_pipeline/thread.h | 24 -
examples/ip_pipeline/tmgr.c | 248 -
examples/ip_pipeline/tmgr.h | 74 -
examples/meson.build | 1 -
lib/pipeline/meson.build | 8 +-
lib/pipeline/rte_pipeline.c | 1640 ----
lib/pipeline/rte_pipeline.h | 840 --
lib/pipeline/rte_port_in_action.c | 539 --
lib/pipeline/rte_port_in_action.h | 311 -
lib/pipeline/rte_table_action.c | 3483 ---------
lib/pipeline/rte_table_action.h | 1137 ---
lib/port/meson.build | 22 +-
lib/port/port_log.c | 7 -
lib/port/port_log.h | 11 -
lib/port/rte_port.h | 223 -
lib/port/rte_port_ethdev.c | 530 --
lib/port/rte_port_ethdev.h | 75 -
lib/port/rte_port_eventdev.c | 590 --
lib/port/rte_port_eventdev.h | 94 -
lib/port/rte_port_fd.c | 524 --
lib/port/rte_port_fd.h | 74 -
lib/port/rte_port_frag.c | 280 -
lib/port/rte_port_frag.h | 70 -
lib/port/rte_port_ras.c | 336 -
lib/port/rte_port_ras.h | 58 -
lib/port/rte_port_ring.c | 796 --
lib/port/rte_port_ring.h | 91 -
lib/port/rte_port_sched.c | 298 -
lib/port/rte_port_sched.h | 52 -
lib/port/rte_port_source_sink.c | 616 --
lib/port/rte_port_source_sink.h | 57 -
lib/port/rte_port_sym_crypto.c | 558 --
lib/port/rte_port_sym_crypto.h | 92 -
lib/table/meson.build | 30 +-
lib/table/rte_lru.h | 85 -
lib/table/rte_lru_arm64.h | 61 -
lib/table/rte_lru_x86.h | 96 -
lib/table/rte_table.h | 263 -
lib/table/rte_table_acl.c | 795 --
lib/table/rte_table_acl.h | 65 -
lib/table/rte_table_array.c | 210 -
lib/table/rte_table_array.h | 46 -
lib/table/rte_table_hash.h | 106 -
lib/table/rte_table_hash_cuckoo.c | 327 -
lib/table/rte_table_hash_cuckoo.h | 57 -
lib/table/rte_table_hash_ext.c | 1011 ---
lib/table/rte_table_hash_func.h | 263 -
lib/table/rte_table_hash_func_arm64.h | 21 -
lib/table/rte_table_hash_key16.c | 1190 ---
lib/table/rte_table_hash_key32.c | 1223 ---
lib/table/rte_table_hash_key8.c | 1157 ---
lib/table/rte_table_hash_lru.c | 959 ---
lib/table/rte_table_lpm.c | 369 -
lib/table/rte_table_lpm.h | 94 -
lib/table/rte_table_lpm_ipv6.c | 370 -
lib/table/rte_table_stub.c | 95 -
lib/table/rte_table_stub.h | 30 -
lib/table/table_log.c | 7 -
lib/table/table_log.h | 11 -
134 files changed, 27 insertions(+), 45377 deletions(-)
delete mode 100644 app/test-pipeline/config.c
delete mode 100644 app/test-pipeline/init.c
delete mode 100644 app/test-pipeline/main.c
delete mode 100644 app/test-pipeline/main.h
delete mode 100644 app/test-pipeline/meson.build
delete mode 100644 app/test-pipeline/pipeline_acl.c
delete mode 100644 app/test-pipeline/pipeline_hash.c
delete mode 100644 app/test-pipeline/pipeline_lpm.c
delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
delete mode 100644 app/test-pipeline/pipeline_stub.c
delete mode 100644 app/test-pipeline/runtime.c
delete mode 100644 app/test/test_table.c
delete mode 100644 app/test/test_table.h
delete mode 100644 app/test/test_table_acl.c
delete mode 100644 app/test/test_table_acl.h
delete mode 100644 app/test/test_table_combined.c
delete mode 100644 app/test/test_table_combined.h
delete mode 100644 app/test/test_table_pipeline.c
delete mode 100644 app/test/test_table_pipeline.h
delete mode 100644 app/test/test_table_ports.c
delete mode 100644 app/test/test_table_ports.h
delete mode 100644 app/test/test_table_tables.c
delete mode 100644 app/test/test_table_tables.h
delete mode 100644 doc/guides/prog_guide/img/figure32.png
delete mode 100644 doc/guides/prog_guide/img/figure33.png
delete mode 100644 doc/guides/prog_guide/img/figure34.png
delete mode 100644 doc/guides/prog_guide/img/figure35.png
delete mode 100644 doc/guides/prog_guide/img/figure37.png
delete mode 100644 doc/guides/prog_guide/img/figure38.png
delete mode 100644 doc/guides/prog_guide/img/figure39.png
delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
delete mode 100644 examples/ip_pipeline/Makefile
delete mode 100644 examples/ip_pipeline/action.c
delete mode 100644 examples/ip_pipeline/action.h
delete mode 100644 examples/ip_pipeline/cli.c
delete mode 100644 examples/ip_pipeline/cli.h
delete mode 100644 examples/ip_pipeline/common.h
delete mode 100644 examples/ip_pipeline/conn.c
delete mode 100644 examples/ip_pipeline/conn.h
delete mode 100644 examples/ip_pipeline/cryptodev.c
delete mode 100644 examples/ip_pipeline/cryptodev.h
delete mode 100644 examples/ip_pipeline/examples/firewall.cli
delete mode 100644 examples/ip_pipeline/examples/flow.cli
delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
delete mode 100644 examples/ip_pipeline/examples/route.cli
delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
delete mode 100644 examples/ip_pipeline/examples/rss.cli
delete mode 100644 examples/ip_pipeline/examples/tap.cli
delete mode 100644 examples/ip_pipeline/link.c
delete mode 100644 examples/ip_pipeline/link.h
delete mode 100644 examples/ip_pipeline/main.c
delete mode 100644 examples/ip_pipeline/mempool.c
delete mode 100644 examples/ip_pipeline/mempool.h
delete mode 100644 examples/ip_pipeline/meson.build
delete mode 100644 examples/ip_pipeline/parser.c
delete mode 100644 examples/ip_pipeline/parser.h
delete mode 100644 examples/ip_pipeline/pipeline.c
delete mode 100644 examples/ip_pipeline/pipeline.h
delete mode 100644 examples/ip_pipeline/swq.c
delete mode 100644 examples/ip_pipeline/swq.h
delete mode 100644 examples/ip_pipeline/tap.c
delete mode 100644 examples/ip_pipeline/tap.h
delete mode 100644 examples/ip_pipeline/thread.c
delete mode 100644 examples/ip_pipeline/thread.h
delete mode 100644 examples/ip_pipeline/tmgr.c
delete mode 100644 examples/ip_pipeline/tmgr.h
delete mode 100644 lib/pipeline/rte_pipeline.c
delete mode 100644 lib/pipeline/rte_pipeline.h
delete mode 100644 lib/pipeline/rte_port_in_action.c
delete mode 100644 lib/pipeline/rte_port_in_action.h
delete mode 100644 lib/pipeline/rte_table_action.c
delete mode 100644 lib/pipeline/rte_table_action.h
delete mode 100644 lib/port/port_log.c
delete mode 100644 lib/port/port_log.h
delete mode 100644 lib/port/rte_port.h
delete mode 100644 lib/port/rte_port_ethdev.c
delete mode 100644 lib/port/rte_port_ethdev.h
delete mode 100644 lib/port/rte_port_eventdev.c
delete mode 100644 lib/port/rte_port_eventdev.h
delete mode 100644 lib/port/rte_port_fd.c
delete mode 100644 lib/port/rte_port_fd.h
delete mode 100644 lib/port/rte_port_frag.c
delete mode 100644 lib/port/rte_port_frag.h
delete mode 100644 lib/port/rte_port_ras.c
delete mode 100644 lib/port/rte_port_ras.h
delete mode 100644 lib/port/rte_port_ring.c
delete mode 100644 lib/port/rte_port_ring.h
delete mode 100644 lib/port/rte_port_sched.c
delete mode 100644 lib/port/rte_port_sched.h
delete mode 100644 lib/port/rte_port_source_sink.c
delete mode 100644 lib/port/rte_port_source_sink.h
delete mode 100644 lib/port/rte_port_sym_crypto.c
delete mode 100644 lib/port/rte_port_sym_crypto.h
delete mode 100644 lib/table/rte_lru.h
delete mode 100644 lib/table/rte_lru_arm64.h
delete mode 100644 lib/table/rte_lru_x86.h
delete mode 100644 lib/table/rte_table.h
delete mode 100644 lib/table/rte_table_acl.c
delete mode 100644 lib/table/rte_table_acl.h
delete mode 100644 lib/table/rte_table_array.c
delete mode 100644 lib/table/rte_table_array.h
delete mode 100644 lib/table/rte_table_hash.h
delete mode 100644 lib/table/rte_table_hash_cuckoo.c
delete mode 100644 lib/table/rte_table_hash_cuckoo.h
delete mode 100644 lib/table/rte_table_hash_ext.c
delete mode 100644 lib/table/rte_table_hash_func.h
delete mode 100644 lib/table/rte_table_hash_func_arm64.h
delete mode 100644 lib/table/rte_table_hash_key16.c
delete mode 100644 lib/table/rte_table_hash_key32.c
delete mode 100644 lib/table/rte_table_hash_key8.c
delete mode 100644 lib/table/rte_table_hash_lru.c
delete mode 100644 lib/table/rte_table_lpm.c
delete mode 100644 lib/table/rte_table_lpm.h
delete mode 100644 lib/table/rte_table_lpm_ipv6.c
delete mode 100644 lib/table/rte_table_stub.c
delete mode 100644 lib/table/rte_table_stub.h
delete mode 100644 lib/table/table_log.c
delete mode 100644 lib/table/table_log.h
--
2.53.0
^ permalink raw reply [flat|nested] 29+ messages in thread* [RFC v2 1/6] app/test: remove packet framework tests
2026-07-27 23:11 ` [RFC v2 0/6] remove legacy packet framework Stephen Hemminger
@ 2026-07-27 23:11 ` Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 2/6] app/test-pipeline: remove application Stephen Hemminger
` (3 subsequent siblings)
4 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-27 23:11 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The legacy packet framework libraries (port, table, pipeline) are
being removed, so remove the unit tests exercising them.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 1 -
app/test/meson.build | 6 -
app/test/test_table.c | 209 -------
app/test/test_table.h | 184 ------
app/test/test_table_acl.c | 728 ----------------------
app/test/test_table_acl.h | 6 -
app/test/test_table_combined.c | 846 -------------------------
app/test/test_table_combined.h | 27 -
app/test/test_table_pipeline.c | 575 -----------------
app/test/test_table_pipeline.h | 6 -
app/test/test_table_ports.c | 195 ------
app/test/test_table_ports.h | 13 -
app/test/test_table_tables.c | 1058 --------------------------------
app/test/test_table_tables.h | 22 -
14 files changed, 3876 deletions(-)
delete mode 100644 app/test/test_table.c
delete mode 100644 app/test/test_table.h
delete mode 100644 app/test/test_table_acl.c
delete mode 100644 app/test/test_table_acl.h
delete mode 100644 app/test/test_table_combined.c
delete mode 100644 app/test/test_table_combined.h
delete mode 100644 app/test/test_table_pipeline.c
delete mode 100644 app/test/test_table_pipeline.h
delete mode 100644 app/test/test_table_ports.c
delete mode 100644 app/test/test_table_ports.h
delete mode 100644 app/test/test_table_tables.c
delete mode 100644 app/test/test_table_tables.h
diff --git a/MAINTAINERS b/MAINTAINERS
index e99a65d197..77a41b3fcf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,7 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test/test_table*
F: app/test-pipeline/
F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
diff --git a/app/test/meson.build b/app/test/meson.build
index 51abeeb732..4fcd755940 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -195,12 +195,6 @@ source_file_deps = {
'test_stack.c': ['stack'],
'test_stack_perf.c': ['stack'],
'test_string_fns.c': [],
- 'test_table.c': ['table', 'pipeline', 'port'],
- 'test_table_acl.c': ['net', 'table', 'pipeline', 'port'],
- 'test_table_combined.c': ['table', 'pipeline', 'port'],
- 'test_table_pipeline.c': ['pipeline', 'table', 'port'],
- 'test_table_ports.c': ['table', 'pipeline', 'port'],
- 'test_table_tables.c': ['table', 'pipeline', 'port'],
'test_tailq.c': [],
'test_telemetry_data.c': ['telemetry'],
'test_telemetry_json.c': ['telemetry'],
diff --git a/app/test/test_table.c b/app/test/test_table.c
deleted file mode 100644
index 20623b8735..0000000000
--- a/app/test/test_table.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_byteorder.h>
-#include <rte_hexdump.h>
-#include <rte_string_fns.h>
-#include <string.h>
-#include "test.h"
-
-#ifdef RTE_EXEC_ENV_WINDOWS
-static int
-test_table(void)
-{
- printf("table not supported on Windows, skipping test\n");
- return TEST_SKIPPED;
-}
-#else
-
-#include "test_table.h"
-#include "test_table_pipeline.h"
-#include "test_table_ports.h"
-#include "test_table_tables.h"
-#include "test_table_combined.h"
-#include "test_table_acl.h"
-
-/* Global variables */
-struct rte_pipeline *p;
-struct rte_ring *rings_rx[N_PORTS];
-struct rte_ring *rings_tx[N_PORTS];
-struct rte_mempool *pool = NULL;
-
-uint32_t port_in_id[N_PORTS];
-uint32_t port_out_id[N_PORTS];
-uint32_t port_out_id_type[3];
-uint32_t table_id[N_PORTS*2];
-uint64_t override_hit_mask = 0xFFFFFFFF;
-uint64_t override_miss_mask = 0xFFFFFFFF;
-uint64_t non_reserved_actions_hit = 0;
-uint64_t non_reserved_actions_miss = 0;
-uint8_t connect_miss_action_to_port_out = 0;
-uint8_t connect_miss_action_to_table = 0;
-uint32_t table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
-uint32_t table_entry_hit_action = RTE_PIPELINE_ACTION_PORT;
-uint32_t table_entry_miss_action = RTE_PIPELINE_ACTION_DROP;
-rte_pipeline_port_in_action_handler port_in_action = NULL;
-rte_pipeline_port_out_action_handler port_out_action = NULL;
-rte_pipeline_table_action_handler_hit action_handler_hit = NULL;
-rte_pipeline_table_action_handler_miss action_handler_miss = NULL;
-
-/* Function prototypes */
-static void app_init_rings(void);
-static void app_init_mbuf_pools(void);
-
-uint64_t pipeline_test_hash(void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = ip_dst;
-
- return signature;
-}
-
-uint32_t pipeline_test_hash_cuckoo(const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = ip_dst;
-
- return signature;
-}
-
-static void
-app_free_resources(void) {
- int i;
- for (i = 0; i < N_PORTS; i++)
- rte_ring_free(rings_rx[i]);
- rte_mempool_free(pool);
-}
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- printf("Getting/Creating the mempool ...\n");
- pool = rte_mempool_lookup("mempool");
- if (!pool) {
- pool = rte_pktmbuf_pool_create(
- "mempool",
- POOL_SIZE,
- POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE,
- 0);
- if (pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
- }
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
- rings_rx[i] = rte_ring_lookup(name);
- if (rings_rx[i] == NULL) {
- rings_rx[i] = rte_ring_create(
- name,
- RING_RX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
- rings_tx[i] = rte_ring_lookup(name);
- if (rings_tx[i] == NULL) {
- rings_tx[i] = rte_ring_create(
- name,
- RING_TX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static int
-test_table(void)
-{
- int status, ret;
- unsigned i;
-
- ret = TEST_SUCCESS;
-
- app_init_rings();
- app_init_mbuf_pools();
-
- printf("\n\n\n\n************Pipeline tests************\n");
-
- if (test_table_pipeline() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-
- printf("\n\n\n\n************Port tests************\n");
- for (i = 0; i < n_port_tests; i++) {
- status = port_tests[i]();
- if (status < 0) {
- printf("\nPort test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests; i++) {
- status = table_tests[i]();
- if (status < 0) {
- printf("\nTable test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests_combined; i++) {
- status = table_tests_combined[i]();
- if (status < 0) {
- printf("\nCombined table test number %d failed with "
- "reason number %d.\n", i, status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
-#ifdef RTE_LIB_ACL
- printf("\n\n\n\n************ACL tests************\n");
- if (test_table_acl() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-#endif
-
-end:
- app_free_resources();
-
- return ret;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
-
-REGISTER_FAST_TEST(table_autotest, NOHUGE_OK, ASAN_OK, test_table);
diff --git a/app/test/test_table.h b/app/test/test_table.h
deleted file mode 100644
index 209bdbff2c..0000000000
--- a/app/test/test_table.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_table_stub.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_table_array.h>
-#include <rte_pipeline.h>
-
-#ifdef RTE_LIB_ACL
-#include <rte_table_acl.h>
-#endif
-
-#include <rte_port_ring.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_source_sink.h>
-
-#ifndef TEST_TABLE_H_
-#define TEST_TABLE_H_
-
-#define RING_SIZE 4096
-#define MAX_BULK 32
-#define N 65536
-#define TIME_S 5
-#define TEST_RING_FULL_EMTPY_ITER 8
-#define N_PORTS 2
-#define N_PKTS 2
-#define N_PKTS_EXT 6
-#define RING_RX rings_rx[0]
-#define RING_RX_2 rings_rx[1]
-#define RING_TX rings_tx[0]
-#define RING_TX_2 rings_tx[1]
-#define PORT_RX_RING_SIZE 128
-#define PORT_TX_RING_SIZE 512
-#define RING_RX_SIZE 128
-#define RING_TX_SIZE 128
-#define POOL_BUFFER_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
-#define POOL_SIZE (32 * 1024)
-#define POOL_CACHE_SIZE 256
-#define BURST_SIZE 8
-#define WORKER_TYPE 1
-#define MAX_DUMMY_PORTS 2
-#define MP_NAME "dummy_port_mempool"
-#define MBUF_COUNT (8000 * MAX_DUMMY_PORTS)
-#define MP_CACHE_SZ 256
-#define MP_SOCKET 0
-#define MP_FLAGS 0
-
-/* Macros */
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#define RING_ENQUEUE(ring, value) do { \
- struct rte_mbuf *m; \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- \
- m = rte_pktmbuf_alloc(pool); \
- if (m == NULL) \
- return -1; \
- signature = RTE_MBUF_METADATA_UINT32_PTR(m, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(m, \
- APP_METADATA_OFFSET(32)); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
- rte_ring_enqueue((ring), m); \
-} while (0)
-
-#define RUN_PIPELINE(pipeline) do { \
- rte_pipeline_run((pipeline)); \
- rte_pipeline_flush((pipeline)); \
-} while (0)
-
-#define VERIFY(var, value) do { \
- if ((var) != -(value)) \
- return var; \
-} while (0)
-
-#define VERIFY_TRAFFIC(ring, sent, expected) do { \
- unsigned i, n = 0; \
- void *mbuf = NULL; \
- \
- for (i = 0; i < (sent); i++) { \
- if (!rte_ring_dequeue((ring), &mbuf)) { \
- if (mbuf == NULL) \
- continue; \
- n++; \
- rte_pktmbuf_free((struct rte_mbuf *)mbuf); \
- } \
- else \
- break; \
- } \
- printf("Expected %d, got %d\n", expected, n); \
- if (n != (expected)) { \
- return -21; \
- } \
-} while (0)
-
-/* Function definitions */
-uint64_t pipeline_test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed);
-
-uint32_t pipeline_test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed);
-
-/* Extern variables */
-extern struct rte_pipeline *p;
-extern struct rte_ring *rings_rx[N_PORTS];
-extern struct rte_ring *rings_tx[N_PORTS];
-extern struct rte_mempool *pool;
-extern uint32_t port_in_id[N_PORTS];
-extern uint32_t port_out_id[N_PORTS];
-extern uint32_t port_out_id_type[3];
-extern uint32_t table_id[N_PORTS*2];
-extern uint64_t override_hit_mask;
-extern uint64_t override_miss_mask;
-extern uint64_t non_reserved_actions_hit;
-extern uint64_t non_reserved_actions_miss;
-extern uint8_t connect_miss_action_to_port_out;
-extern uint8_t connect_miss_action_to_table;
-extern uint32_t table_entry_default_action;
-extern uint32_t table_entry_hit_action;
-extern uint32_t table_entry_miss_action;
-extern rte_pipeline_port_in_action_handler port_in_action;
-extern rte_pipeline_port_out_action_handler port_out_action;
-extern rte_pipeline_table_action_handler_hit action_handler_hit;
-extern rte_pipeline_table_action_handler_miss action_handler_miss;
-
-/* Global data types */
-struct manage_ops {
- uint32_t op_id;
- void *op_data;
- int expected_result;
-};
-
-/* Internal pipeline structures */
-struct rte_port_in {
- struct rte_port_in_ops ops;
- uint32_t burst_size;
- uint32_t table_id;
- void *h_port;
-};
-
-struct rte_port_out {
- struct rte_port_out_ops ops;
- void *h_port;
-};
-
-struct rte_table {
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action;
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
- uint8_t actions_lookup_miss[RTE_CACHE_LINE_SIZE];
- uint32_t action_data_size;
- void *h_table;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct rte_pipeline {
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- uint32_t socket_id;
- struct rte_port_in ports_in[16];
- struct rte_port_out ports_out[16];
- struct rte_table tables[64];
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_table_entry *actions[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t mask_action[64];
- uint32_t mask_actions;
-};
-#endif
diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c
deleted file mode 100644
index 4fdf731596..0000000000
--- a/app/test/test_table_acl.c
+++ /dev/null
@@ -1,728 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <rte_ip.h>
-#include <rte_string_fns.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_acl.h"
-
-/*
- * Rule and trace formats definitions.
- **/
-
-struct ipv4_5tuple {
- uint8_t proto;
- uint32_t ip_src;
- uint32_t ip_dst;
- uint16_t port_src;
- uint16_t port_dst;
-};
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, proto),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_dst),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_dst),
- },
-};
-
-struct rte_table_acl_rule_add_params table_acl_IPv4_rule;
-
-typedef int (*parse_5tuple)(char *text,
- struct rte_table_acl_rule_add_params *rule);
-
-/*
-* The order of the fields in the rule string after the initial '@'
-*/
-enum {
- CB_FLD_SRC_ADDR,
- CB_FLD_DST_ADDR,
- CB_FLD_SRC_PORT_RANGE,
- CB_FLD_DST_PORT_RANGE,
- CB_FLD_PROTO,
- CB_FLD_NUM,
-};
-
-
-#define GET_CB_FIELD(in, fd, base, lim, dlm) \
-do { \
- unsigned long val; \
- char *end; \
- \
- errno = 0; \
- val = strtoul((in), &end, (base)); \
- if (errno != 0 || end[0] != (dlm) || val > (lim)) \
- return -EINVAL; \
- (fd) = (typeof(fd)) val; \
- (in) = end + 1; \
-} while (0)
-
-
-
-
-static int
-parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len)
-{
- uint8_t a, b, c, d, m;
-
- GET_CB_FIELD(in, a, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, b, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, c, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, d, 0, UINT8_MAX, '/');
- GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0);
-
- addr[0] = RTE_IPV4(a, b, c, d);
- mask_len[0] = m;
-
- return 0;
-}
-
-static int
-parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high)
-{
- uint16_t a, b;
-
- GET_CB_FIELD(in, a, 0, UINT16_MAX, ':');
- GET_CB_FIELD(in, b, 0, UINT16_MAX, 0);
-
- port_low[0] = a;
- port_high[0] = b;
-
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-setup_acl_pipeline(void)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
- uint32_t n;
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_acl_rule_delete_params *delete_params;
- parse_5tuple parser;
- char acl_name[64];
-
- /*
- * The format for these rules DO NOT need the port ranges to be
- * separated by ' : ', just ':'. It's a lot more readable and
- * cleaner, IMO.
- */
- static const char * const lines[] = {
- "@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */
- "@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP check */
- "@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */
- "@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */
- "@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */
- };
- char line[LINE_MAX];
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = port_in_action;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params;
-
- /* Set up defaults for stub */
- table_params.ops = &rte_table_stub_ops;
- table_params.arg_create = NULL;
- table_params.f_action_hit = action_handler_hit;
- table_params.f_action_miss = NULL;
- table_params.action_data_size = 0;
-
- printf("miss_action=%x\n",
- table_entry_miss_action);
-
- printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs),
- RTE_ACL_RULE_SZ(DIM(ipv4_defs)));
-
- struct rte_table_acl_params acl_params;
-
- acl_params.n_rules = 1 << 5;
- acl_params.n_rule_fields = DIM(ipv4_defs);
- snprintf(acl_name, sizeof(acl_name), "ACL%d", i);
- acl_params.name = acl_name;
- memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
-
- table_params.ops = &rte_table_acl_ops;
- table_params.arg_create = &acl_params;
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table) {
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
- }
-
- for (i = 0; i < N_PORTS; i++) {
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n",
- port_in_id[i], table_id[i]);
- goto fail;
- }
- }
-
- /* Add bulk entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_add_params keys[5];
- struct rte_pipeline_table_entry entries[5];
- struct rte_table_acl_rule_add_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
- struct rte_pipeline_table_entry *table_entries_ptr[5];
- struct rte_pipeline_table_entry entries_ptr[5];
-
- parser = parse_cb_ipv4_rule;
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1;
-
- entries[n].action = RTE_PIPELINE_ACTION_PORT;
- entries[n].port_id = port_out_id[i^1];
- table_entries[n] = &entries[n];
- table_entries_ptr[n] = &entries_ptr[n];
- }
-
- ret = rte_pipeline_table_entry_add_bulk(p, table_id[i],
- (void **)key_array, table_entries, 5, key_found, table_entries_ptr);
- if (ret < 0) {
- rte_panic("Add entry bulk to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* Delete bulk entries from tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_delete_params keys[5];
- struct rte_table_acl_rule_delete_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
-
- memset(table_entries, 0, sizeof(table_entries));
-
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parse_cb_ipv4_rule_del(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
- }
-
- ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i],
- (void **)key_array, 5, key_found, table_entries);
- if (ret < 0) {
- rte_panic("Delete bulk entries from table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Bulk deleted rules.\n");
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- int key_found;
- struct rte_pipeline_table_entry *entry_ptr;
-
- memset(&rule_params, 0, sizeof(rule_params));
- parser = parse_cb_ipv4_rule;
-
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* delete a few rules */
- for (n = 2; n <= 3; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- delete_params = (struct
- rte_pipeline_table_acl_rule_delete_params *)
- &(rule_params.field_value[0]);
- ret = rte_pipeline_table_entry_delete(p, table_id[i],
- delete_params, &key_found, NULL);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Deleted Rule.\n");
- }
-
-
- /* Try to add duplicates */
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- }
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int expected_count)
-{
- int i, j, ret, tx_count;
- struct ipv4_5tuple five_tuple;
-
- /* Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++) {
- for (j = 0; j < 8; j++) {
- struct rte_mbuf *mbuf;
-
- mbuf = rte_pktmbuf_alloc(pool);
- if (mbuf == NULL)
- /* this will cause test failure after cleanup
- * of already enqueued mbufs, as the mbuf
- * counts won't match */
- break;
- memset(rte_pktmbuf_mtod(mbuf, char *), 0x00,
- sizeof(struct ipv4_5tuple));
-
- five_tuple.proto = j;
- five_tuple.ip_src = rte_bswap32(RTE_IPV4(192, 168, j, 1));
- five_tuple.ip_dst = rte_bswap32(RTE_IPV4(10, 4, j, 1));
- five_tuple.port_src = rte_bswap16(100 + j);
- five_tuple.port_dst = rte_bswap16(200 + j);
-
- memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple,
- sizeof(struct ipv4_5tuple));
- printf("%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], mbuf);
- }
- }
-
- /* Run pipeline once */
- for (i = 0; i< N_PORTS; i++)
- rte_pipeline_run(p);
-
- rte_pipeline_flush(p);
-
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0) {
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- } else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "mbuf",
- rte_pktmbuf_mtod(mbuf, char *), 64);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets for ACL test, expected %d, got %d\n",
- __func__, expected_count, tx_count);
- goto fail;
- }
-
- rte_pipeline_free(p);
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_acl(void)
-{
-
-
- override_hit_mask = 0xFF; /* All packets are a hit */
-
- setup_acl_pipeline();
- if (test_pipeline_single_filter(10) < 0)
- return -1;
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_acl.h b/app/test/test_table_acl.h
deleted file mode 100644
index a6ae7d2838..0000000000
--- a/app/test/test_table_acl.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_acl(void);
diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
deleted file mode 100644
index 04503baa51..0000000000
--- a/app/test/test_table_combined.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include "test_table_combined.h"
-#include "test_table.h"
-#include <rte_table_lpm_ipv6.h>
-
-#define MAX_TEST_KEYS 128
-#define N_PACKETS 50
-
-enum check_table_result {
- CHECK_TABLE_OK,
- CHECK_TABLE_PORT_CONFIG,
- CHECK_TABLE_PORT_ENABLE,
- CHECK_TABLE_TABLE_CONFIG,
- CHECK_TABLE_ENTRY_ADD,
- CHECK_TABLE_DEFAULT_ENTRY_ADD,
- CHECK_TABLE_CONNECT,
- CHECK_TABLE_MANAGE_ERROR,
- CHECK_TABLE_CONSISTENCY,
- CHECK_TABLE_NO_TRAFFIC,
- CHECK_TABLE_INVALID_PARAMETER,
-};
-
-struct table_packets {
- uint32_t hit_packet[MAX_TEST_KEYS];
- uint32_t miss_packet[MAX_TEST_KEYS];
- uint32_t n_hit_packets;
- uint32_t n_miss_packets;
-};
-
-combined_table_test table_tests_combined[] = {
- test_table_lpm_combined,
- test_table_lpm_ipv6_combined,
- test_table_hash8lru,
- test_table_hash8ext,
- test_table_hash16lru,
- test_table_hash16ext,
- test_table_hash32lru,
- test_table_hash32ext,
- test_table_hash_cuckoo_combined,
-};
-
-unsigned n_table_tests_combined = RTE_DIM(table_tests_combined);
-
-/* Generic port tester function */
-static int
-test_table_type(struct rte_table_ops *table_ops, void *table_args,
- void *key, struct table_packets *table_packets,
- struct manage_ops *manage_ops, unsigned n_ops)
-{
- uint32_t ring_in_id, table_id, ring_out_id, ring_out_2_id;
- unsigned i;
-
- RTE_SET_USED(manage_ops);
- RTE_SET_USED(n_ops);
- /* Create pipeline */
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = 0,
- };
-
- struct rte_pipeline *pipeline = rte_pipeline_create(&pipeline_params);
-
- /* Create input ring */
- struct rte_port_ring_reader_params ring_params_rx = {
- .ring = RING_RX,
- };
-
- struct rte_port_ring_writer_params ring_params_tx = {
- .ring = RING_RX,
- .tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- struct rte_pipeline_port_in_params ring_in_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *)&ring_params_rx,
- .f_action = NULL,
- .burst_size = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- if (rte_pipeline_port_in_create(pipeline, &ring_in_params,
- &ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Create table */
- struct rte_pipeline_table_params table_params = {
- .ops = table_ops,
- .arg_create = table_args,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(pipeline, &table_params,
- &table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_TABLE_CONFIG;
- }
-
- /* Create output ports */
- ring_params_tx.ring = RING_TX;
-
- struct rte_pipeline_port_out_params ring_out_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *)&ring_params_tx,
- .f_action = NULL,
- };
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- ring_params_tx.ring = RING_TX_2;
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_2_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Add entry to the table */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_DROP,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry *default_entry_ptr, *entry_ptr;
-
- int key_found;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_DEFAULT_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Create connections and check consistency */
- if (rte_pipeline_port_in_connect_to_table(pipeline, ring_in_id,
- table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONNECT;
- }
-
- if (rte_pipeline_port_in_enable(pipeline, ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_ENABLE;
- }
-
- if (rte_pipeline_check(pipeline) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONSISTENCY;
- }
-
-
-
- /* Flow test - All hits */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- /* Flow test - All misses */
- if (table_packets->n_miss_packets) {
- for (i = 0; i < table_packets->n_miss_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
- /* Flow test - Half hits, half misses */
- if (table_packets->n_hit_packets && table_packets->n_miss_packets) {
- for (i = 0; i < (table_packets->n_hit_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- for (i = 0; i < (table_packets->n_miss_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets / 2);
- }
-
- /* Flow test - Single packet */
- if (table_packets->n_hit_packets) {
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 1);
- }
- if (table_packets->n_miss_packets) {
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
-
- /* Change table entry action */
- printf("Change entry action\n");
- table_entry.table_id = ring_out_2_id;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Check that traffic destination has changed */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 0);
- VERIFY_TRAFFIC(RING_TX_2, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- printf("delete entry\n");
- /* Delete table entry */
- rte_pipeline_table_entry_delete(pipeline, table_id,
- key ? key : &table_entry, &key_found, NULL);
-
- rte_pipeline_free(pipeline);
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub_combined(void)
-{
- int status, i;
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = i;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = 0;
-
- status = test_table_type(&rte_table_stub_ops, NULL, NULL,
- &table_packets, NULL, 1);
- VERIFY(status, CHECK_TABLE_OK);
-
- return 0;
-}
-
-int
-test_table_lpm_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(0),
- };
-
- struct rte_table_lpm_key lpm_key = {
- .ip = 0xadadadad,
- .depth = 16,
- };
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_params.n_rules = 1 << 24;
- lpm_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_key.depth = 33;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_ipv6_params lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 13,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_table_lpm_ipv6_key lpm_ipv6_key = {
- .depth = 16,
- };
- memset(&lpm_ipv6_key.ip, 0xad, 16);
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xadadadab;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_ipv6_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_ipv6_params.n_rules = 1 << 24;
- lpm_ipv6_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_ipv6_key.depth = 129;
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_hash8lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8lru_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8lru[8];
- uint32_t *k8lru = (uint32_t *) key8lru;
-
- memset(key8lru, 0, sizeof(key8lru));
- k8lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8lru_params.n_keys = 1<<16;
- key8lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16lru_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16lru[16];
- uint32_t *k16lru = (uint32_t *) key16lru;
-
- memset(key16lru, 0, sizeof(key16lru));
- k16lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16lru_params.n_keys = 1<<16;
- key16lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32lru_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32lru[32];
- uint32_t *k32lru = (uint32_t *) key32lru;
-
- memset(key32lru, 0, sizeof(key32lru));
- k32lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32lru_params.n_keys = 1<<16;
- key32lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash8ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8ext_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8ext[8];
- uint32_t *k8ext = (uint32_t *) key8ext;
-
- memset(key8ext, 0, sizeof(key8ext));
- k8ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8ext_params.n_keys = 1<<16;
- key8ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16ext_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16ext[16];
- uint32_t *k16ext = (uint32_t *) key16ext;
-
- memset(key16ext, 0, sizeof(key16ext));
- k16ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16ext_params.n_keys = 1<<16;
- key16ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32ext_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32ext[32];
- uint32_t *k32ext = (uint32_t *) key32ext;
-
- memset(key32ext, 0, sizeof(key32ext));
- k32ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32ext_params.n_keys = 1<<16;
- key32ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash_cuckoo_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) key_cuckoo;
-
- memset(key_cuckoo, 0, sizeof(key_cuckoo));
- kcuckoo[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- cuckoo_params.key_size = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.n_keys = 1<<16;
- cuckoo_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_combined.h b/app/test/test_table_combined.h
deleted file mode 100644
index fb94dbb94d..0000000000
--- a/app/test/test_table_combined.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_stub_combined(void);
-int test_table_lpm_combined(void);
-int test_table_lpm_ipv6_combined(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash8unoptimized(void);
-int test_table_hash8lru(void);
-int test_table_hash8ext(void);
-int test_table_hash16unoptimized(void);
-int test_table_hash16lru(void);
-int test_table_hash16ext(void);
-int test_table_hash32unoptimized(void);
-int test_table_hash32lru(void);
-int test_table_hash32ext(void);
-int test_table_hash_cuckoo_combined(void);
-
-/* Extern variables */
-typedef int (*combined_table_test)(void);
-
-extern combined_table_test table_tests_combined[];
-extern unsigned n_table_tests_combined;
diff --git a/app/test/test_table_pipeline.c b/app/test/test_table_pipeline.c
deleted file mode 100644
index 960f730cf2..0000000000
--- a/app/test/test_table_pipeline.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_pipeline.h>
-#include <inttypes.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_pipeline.h"
-
-#if 0
-
-static rte_pipeline_port_out_action_handler port_action_0x00
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_0xFF
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_stub
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-
-
-rte_pipeline_port_out_action_handler port_action_0x00(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0x00\n");
- *pkts_mask = 0x00;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_0xFF(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0xFF\n");
- *pkts_mask = 0xFF;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(pkts_mask);
- RTE_SET_USED(arg);
- printf("Port Action stub\n");
- return 0;
-}
-
-#endif
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-static int
-table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry *entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("Table Action, setting pkts_mask to 0x00\n");
- pkts_mask = ~0x00;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Hit - doing nothing\n");
- printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n",
- override_hit_mask);
- pkts_mask = (~override_hit_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-static int
-table_action_stub_miss(struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry *entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n",
- override_miss_mask);
- pkts_mask = (~override_miss_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-enum e_test_type {
- e_TEST_STUB = 0,
- e_TEST_LPM,
- e_TEST_LPM6,
- e_TEST_HASH_LRU_8,
- e_TEST_HASH_LRU_16,
- e_TEST_HASH_LRU_32,
- e_TEST_HASH_EXT_8,
- e_TEST_HASH_EXT_16,
- e_TEST_HASH_EXT_32
-};
-
-char pipeline_test_names[][64] = {
- "Stub",
- "LPM",
- "LPMv6",
- "8-bit LRU Hash",
- "16-bit LRU Hash",
- "32-bit LRU Hash",
- "16-bit Ext Hash",
- "8-bit Ext Hash",
- "32-bit Ext Hash",
- ""
-};
-
-
-static int
-cleanup_pipeline(void)
-{
-
- rte_pipeline_free(p);
-
- return 0;
-}
-
-
-static int check_pipeline_invalid_params(void);
-
-static int
-check_pipeline_invalid_params(void)
-{
- struct rte_pipeline_params pipeline_params_1 = {
- .name = NULL,
- .socket_id = 0,
- };
- struct rte_pipeline_params pipeline_params_2 = {
- .name = "PIPELINE",
- .socket_id = -1,
- };
- struct rte_pipeline_params pipeline_params_3 = {
- .name = "PIPELINE",
- .socket_id = 127,
- };
-
- p = rte_pipeline_create(NULL);
- if (p != NULL) {
- fprintf(stderr,
- "%s: configured pipeline with null params\n",
- __func__);
- goto fail;
- }
- p = rte_pipeline_create(&pipeline_params_1);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with NULL name\n", __func__);
- goto fail;
- }
-
- p = rte_pipeline_create(&pipeline_params_2);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n", __func__);
- goto fail;
- }
-
- if (rte_eal_has_hugepages()) {
- p = rte_pipeline_create(&pipeline_params_3);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n",
- __func__);
- goto fail;
- }
- }
-
- /* Check pipeline consistency */
- if (!rte_pipeline_check(p)) {
- rte_panic("Pipeline consistency reported as OK\n");
- goto fail;
- }
-
-
- return 0;
-fail:
- return -1;
-}
-
-
-static int
-setup_pipeline(int test_type)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
-
- fprintf(stderr, "%s: **** Setting up %s test\n",
- __func__, pipeline_test_names[test_type]);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- ret = rte_pipeline_free(p);
- if (ret != 0) {
- fprintf(stderr, "%s: Failed to free pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = NULL;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (i)
- port_params.f_action = port_out_action;
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = action_handler_hit,
- .f_action_miss = action_handler_miss,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table)
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
-
- for (i = 0; i < N_PORTS; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
- goto fail;
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry default_entry = {
- .action = (enum rte_pipeline_action)
- table_entry_default_action,
- {.port_id = port_out_id[i^1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (connect_miss_action_to_table) {
- printf("Setting first table to output to next table\n");
- default_entry.action = RTE_PIPELINE_ACTION_TABLE;
- default_entry.table_id = table_id[i+2];
- }
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p, table_id[i],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to table %u "
- "code %d\n", table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d with "
- "action %x\n",
- table_id[i], default_entry.action);
-
- if (connect_miss_action_to_table) {
- /* We create a second table so the first can pass
- traffic into it */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- printf("Setting second table to output to port\n");
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p,
- table_id[i+2],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to "
- "table %u code %d\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d "
- "with action %x\n",
- table_id[i], default_entry.action);
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- } else
- printf("Pipeline Consistency OK!\n");
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int test_type, int expected_count)
-{
- int i;
- int j;
- int ret;
- int tx_count;
-
- fprintf(stderr, "%s: **** Running %s test\n",
- __func__, pipeline_test_names[test_type]);
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
-
- ret = rte_pipeline_flush(NULL);
- if (ret != -EINVAL) {
- fprintf(stderr,
- "%s: No pipeline flush error NULL pipeline (%d)\n",
- __func__, ret);
- goto fail;
- }
-
- /*
- * Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++)
- for (j = 0; j < N_PORTS; j++) {
- struct rte_mbuf *m;
- uint8_t *key;
- uint32_t *k32;
-
- m = rte_pktmbuf_alloc(pool);
- if (m == NULL) {
- rte_panic("Failed to alloc mbuf from pool\n");
- return -1;
- }
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- k32 = (uint32_t *) key;
- k32[0] = 0xadadadad >> (j % 2);
-
- fprintf(stderr, "%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], m);
- }
-
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
- /*
- * need to flush the pipeline, as there may be less hits than the burst
- size and they will not have been flushed to the tx rings. */
- rte_pipeline_flush(p);
-
- /*
- * Now we'll see what we got back on the tx rings. We should see whatever
- * packets we had hits on that were destined for the output ports.
- */
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0)
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "Object:",
- rte_pktmbuf_mtod(mbuf, char *),
- mbuf->data_len);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets out for %s test, expected %d, got %d\n",
- __func__, pipeline_test_names[test_type],
- expected_count, tx_count);
- goto fail;
- }
-
- cleanup_pipeline();
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_pipeline(void)
-{
- /* TEST - All packets dropped */
- action_handler_hit = NULL;
- action_handler_miss = NULL;
- table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 0) < 0)
- return -1;
-
- /* TEST - All packets passed through */
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /* TEST - one packet per port */
- action_handler_hit = NULL;
- action_handler_miss = table_action_stub_miss;
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- override_miss_mask = 0x01; /* one packet per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - one packet per port */
- override_miss_mask = 0x02; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - all packets per port */
- override_miss_mask = 0x03; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /*
- * This test will set up two tables in the pipeline. the first table
- * will forward to another table on miss, and the second table will
- * forward to port.
- */
- connect_miss_action_to_table = 1;
- table_entry_default_action = RTE_PIPELINE_ACTION_TABLE;
- action_handler_hit = NULL; /* not for stub, hitmask always zero */
- action_handler_miss = NULL;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- printf("TEST - two tables, hitmask override to 0x01\n");
- connect_miss_action_to_table = 1;
- action_handler_miss = table_action_stub_miss;
- override_miss_mask = 0x01;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- if (check_pipeline_invalid_params()) {
- fprintf(stderr, "%s: Check pipeline invalid params failed.\n",
- __func__);
- return -1;
- }
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_pipeline.h b/app/test/test_table_pipeline.h
deleted file mode 100644
index d66d09d6f1..0000000000
--- a/app/test/test_table_pipeline.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_pipeline(void);
diff --git a/app/test/test_table_ports.c b/app/test/test_table_ports.c
deleted file mode 100644
index 282ec2a3d2..0000000000
--- a/app/test/test_table_ports.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include "test_table_ports.h"
-#include "test_table.h"
-
-port_test port_tests[] = {
- test_port_ring_reader,
- test_port_ring_writer,
-};
-
-unsigned n_port_tests = RTE_DIM(port_tests);
-
-/* Port tests */
-int
-test_port_ring_reader(void)
-{
- int status, i;
- struct rte_port_ring_reader_params port_ring_reader_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_reader_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- /* Create and free */
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
- if (port == NULL)
- return -3;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status != 0)
- return -4;
-
- /* -- Traffic RX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- void *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
-
- /* Single packet */
- mbuf[0] = (void *)rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- mbuf, 1, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, 1);
-
- if (received_pkts < expected_pkts)
- return -5;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- (void * const *) mbuf, RTE_PORT_IN_BURST_SIZE_MAX, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf,
- RTE_PORT_IN_BURST_SIZE_MAX);
-
- if (received_pkts < expected_pkts)
- return -6;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-int
-test_port_ring_writer(void)
-{
- int status, i;
- struct rte_port_ring_writer_params port_ring_writer_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_writer_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- port_ring_writer_params.ring = NULL;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -3;
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX + 1;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -4;
-
- /* Create and free */
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port == NULL)
- return -5;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status != 0)
- return -6;
-
- /* -- Traffic TX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
-
- /* Single packet */
- mbuf[0] = rte_pktmbuf_alloc(pool);
-
- rte_port_ring_writer_ops.f_tx(port, mbuf[0]);
- rte_port_ring_writer_ops.f_flush(port);
- expected_pkts = 1;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -7;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx(port, mbuf[i]);
- }
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- /* TX Bulk */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-1);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-3);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)2);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -9;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_ports.h b/app/test/test_table_ports.h
deleted file mode 100644
index dfa6119319..0000000000
--- a/app/test/test_table_ports.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_port_ring_reader(void);
-int test_port_ring_writer(void);
-
-/* Extern variables */
-typedef int (*port_test)(void);
-
-extern port_test port_tests[];
-extern unsigned n_port_tests;
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
deleted file mode 100644
index 920aa555cb..0000000000
--- a/app/test/test_table_tables.c
+++ /dev/null
@@ -1,1058 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_byteorder.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_lru.h>
-#include <rte_cycles.h>
-#include "test_table_tables.h"
-#include "test_table.h"
-
-table_test table_tests[] = {
- test_table_stub,
- test_table_array,
- test_table_lpm,
- test_table_lpm_ipv6,
- test_table_hash_lru,
- test_table_hash_ext,
- test_table_hash_cuckoo,
-};
-
-#define PREPARE_PACKET(mbuf, value) do { \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- mbuf = rte_pktmbuf_alloc(pool); \
- signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \
- APP_METADATA_OFFSET(32)); \
- if (mbuf->priv_size + mbuf->buf_len >= 64) \
- memset(key, 0, 32); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
-} while (0)
-
-unsigned n_table_tests = RTE_DIM(table_tests);
-
-/* Function prototypes */
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size);
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size);
-
-struct rte_bucket_4_8 {
- /* Cache line 0 */
- uint64_t signature;
- uint64_t lru_list;
- struct rte_bucket_4_8 *next;
- uint64_t next_valid;
- uint64_t key[4];
- /* Cache line 1 */
- uint8_t data[];
-};
-
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
-uint64_t shuffles = 0xfffffffdfffbfff9ULL;
-#else
-uint64_t shuffles = 0x0003000200010000ULL;
-#endif
-
-static int test_lru_update(void)
-{
- struct rte_bucket_4_8 b;
- struct rte_bucket_4_8 *bucket;
- uint32_t i;
- uint64_t pos;
- uint64_t iterations;
- uint64_t j;
- int poss;
-
- printf("---------------------------\n");
- printf("Testing lru_update macro...\n");
- printf("---------------------------\n");
- bucket = &b;
- iterations = 10;
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
- bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL;
-#else
- bucket->lru_list = 0x0000000100020003ULL;
-#endif
- poss = 0;
- for (j = 0; j < iterations; j++)
- for (i = 0; i < 9; i++) {
- uint32_t idx = i >> 1;
- lru_update(bucket, idx);
- pos = lru_pos(bucket);
- poss += pos;
- printf("%s: %d lru_list=%016"PRIx64", upd=%d, "
- "pos=%"PRIx64"\n",
- __func__, i, bucket->lru_list, i>>1, pos);
- }
-
- if (bucket->lru_list != shuffles) {
- printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016"
- PRIx64"\n",
- __func__, i, bucket->lru_list, shuffles);
- return -1;
- }
- printf("%s: output checksum of results =%d\n",
- __func__, poss);
-#if 0
- if (poss != 126) {
- printf("%s: ERROR output checksum of results =%d expected %d\n",
- __func__, poss, 126);
- return -1;
- }
-#endif
-
- fflush(stdout);
-
- uint64_t sc_start = rte_rdtsc();
- iterations = 100000000;
- poss = 0;
- for (j = 0; j < iterations; j++) {
- for (i = 0; i < 4; i++) {
- lru_update(bucket, i);
- pos |= bucket->lru_list;
- }
- }
- uint64_t sc_end = rte_rdtsc();
-
- printf("%s: output checksum of results =%llu\n",
- __func__, (long long unsigned int)pos);
- printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n",
- __func__, sc_start, sc_end);
- printf("\nlru_update: %lu cycles per loop iteration.\n\n",
- (long unsigned int)((sc_end-sc_start)/(iterations*4)));
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub(void)
-{
- int i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
-
- /* Create */
- table = rte_table_stub_ops.f_create(NULL, 0, 1);
- if (table == NULL)
- return -1;
-
- /* Traffic flow */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- expected_mask = 0;
- rte_table_stub_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -2;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- return 0;
-}
-
-int
-test_table_array(void)
-{
- int status, i;
- uint64_t result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry1, entry2;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_array_params array_params = {
- .n_entries = 7,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_array_ops.f_create(NULL, 0, 1);
- if (table != NULL)
- return -1;
-
- array_params.n_entries = 0;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -2;
-
- array_params.n_entries = 7;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -3;
-
- array_params.n_entries = 1 << 24;
- array_params.offset = APP_METADATA_OFFSET(1);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -4;
-
- array_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = rte_table_array_ops.f_free(table);
- if (status < 0)
- return -6;
-
- status = rte_table_array_ops.f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- struct rte_table_array_key array_key_1 = {
- .pos = 10,
- };
- struct rte_table_array_key array_key_2 = {
- .pos = 20,
- };
- entry1 = 'A';
- entry2 = 'B';
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -8;
-
- status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1,
- &key_found, &entry_ptr);
- if (status == 0)
- return -9;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL,
- &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1,
- &entry1, &key_found, &entry_ptr);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- status = rte_table_array_ops.f_add(table, (void *) &array_key_2,
- &entry2, &key_found, &entry_ptr);
- if (status != 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 10);
- else
- PREPARE_PACKET(mbufs[i], 20);
-
- rte_table_array_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0 && *entries[i] != 'A')
- return -13;
- else
- if (i % 2 == 1 && *entries[i] != 'B')
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_array_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_lpm_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.offset = APP_METADATA_OFFSET(32);
- lpm_params.entry_unique_size = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.entry_unique_size = entry_size + 1;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_lpm_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_lpm_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- struct rte_table_lpm_key lpm_key;
- lpm_key.ip = 0xadadadad;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -9;
-
- status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status != 0)
- return -15;
-
- /* Delete */
- status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -17;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -20;
-
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -21;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -22;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -23;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_ipv6_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 18,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(32)
- };
-
- table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.number_tbl8s = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.number_tbl8s = 1 << 18;
- lpm_params.entry_unique_size = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size + 1;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -6;
-
- lpm_params.entry_unique_size = entry_size;
- lpm_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -7;
-
- /* Free */
- status = rte_table_lpm_ipv6_ops.f_free(table);
- if (status < 0)
- return -8;
-
- status = rte_table_lpm_ipv6_ops.f_free(NULL);
- if (status == 0)
- return -9;
-
- /* Add */
- struct rte_table_lpm_ipv6_key lpm_key;
-
- lpm_key.ip.a[0] = 0xad;
- lpm_key.ip.a[1] = 0xad;
- lpm_key.ip.a[2] = 0xad;
- lpm_key.ip.a[3] = 0xad;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -10;
-
- status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -15;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status != 0)
- return -16;
-
- /* Delete */
- status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -17;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -20;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -21;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -22;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- return -23;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -24;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ipv6_ops.f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- int key_found;
- void *entry_ptr;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.key_offset = APP_METADATA_OFFSET(1);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -3;
-
- hash_params.key_offset = APP_METADATA_OFFSET(32);
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-int
-test_table_hash_lru(void)
-{
- int status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key8_lru_ops,
- 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key16_lru_ops,
- 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key32_lru_ops,
- 32);
- if (status < 0)
- return status;
-
- status = test_lru_update();
- if (status < 0)
- return status;
-
- return 0;
-}
-
-int
-test_table_hash_ext(void)
-{
- int status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops, 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32);
- if (status < 0)
- return status;
-
- return 0;
-}
-
-
-int
-test_table_hash_cuckoo(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = 1;
-
- /* Initialize params and create tables */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- cuckoo_params.key_size = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -2;
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -3;
-
- cuckoo_params.n_keys = 1 << 24;
- cuckoo_params.f_hash = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -4;
-
- cuckoo_params.f_hash = pipeline_test_hash_cuckoo;
- cuckoo_params.name = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -5;
-
- cuckoo_params.name = "CUCKOO";
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_hash_cuckoo_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_hash_cuckoo_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) &key_cuckoo;
-
- memset(key_cuckoo, 0, 32);
- kcuckoo[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 0, 1);
- if (table == NULL)
- return -9;
-
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- NULL, &key_found, &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -13;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -14;
-
- /* Delete */
- status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo,
- &key_found, NULL);
- if (status == 0)
- return -15;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, NULL,
- &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != 0)
- return -17;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != -ENOENT)
- return -18;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -19;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_hash_cuckoo_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -20;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_hash_cuckoo_ops.f_free(table);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_tables.h b/app/test/test_table_tables.h
deleted file mode 100644
index 530633a013..0000000000
--- a/app/test/test_table_tables.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_hash_cuckoo(void);
-int test_table_lpm(void);
-int test_table_lpm_ipv6(void);
-int test_table_array(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash_unoptimized(void);
-int test_table_hash_lru(void);
-int test_table_hash_ext(void);
-int test_table_stub(void);
-
-/* Extern variables */
-typedef int (*table_test)(void);
-
-extern table_test table_tests[];
-extern unsigned n_table_tests;
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC v2 2/6] app/test-pipeline: remove application
2026-07-27 23:11 ` [RFC v2 0/6] remove legacy packet framework Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 1/6] app/test: remove packet framework tests Stephen Hemminger
@ 2026-07-27 23:11 ` Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 3/6] examples/ip_pipeline: remove example Stephen Hemminger
` (2 subsequent siblings)
4 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-27 23:11 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The test-pipeline application is built on the legacy pipeline
library API (rte_pipeline_*), which was announced for removal
in the 24.11 release. Remove it before removing the library.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
app/meson.build | 1 -
app/test-pipeline/config.c | 230 ---------
app/test-pipeline/init.c | 273 ----------
app/test-pipeline/main.c | 188 -------
app/test-pipeline/main.h | 132 -----
app/test-pipeline/meson.build | 21 -
app/test-pipeline/pipeline_acl.c | 251 ----------
app/test-pipeline/pipeline_hash.c | 471 ------------------
app/test-pipeline/pipeline_lpm.c | 175 -------
app/test-pipeline/pipeline_lpm_ipv6.c | 168 -------
app/test-pipeline/pipeline_stub.c | 137 -----
app/test-pipeline/runtime.c | 160 ------
doc/guides/rel_notes/release_26_11.rst | 3 +
.../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/test_pipeline.rst | 237 ---------
17 files changed, 3 insertions(+), 2447 deletions(-)
delete mode 100644 app/test-pipeline/config.c
delete mode 100644 app/test-pipeline/init.c
delete mode 100644 app/test-pipeline/main.c
delete mode 100644 app/test-pipeline/main.h
delete mode 100644 app/test-pipeline/meson.build
delete mode 100644 app/test-pipeline/pipeline_acl.c
delete mode 100644 app/test-pipeline/pipeline_hash.c
delete mode 100644 app/test-pipeline/pipeline_lpm.c
delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
delete mode 100644 app/test-pipeline/pipeline_stub.c
delete mode 100644 app/test-pipeline/runtime.c
delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 77a41b3fcf..4c06f85706 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,8 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test-pipeline/
-F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
F: examples/pipeline/
F: doc/guides/sample_app_ug/ip_pipeline.rst
diff --git a/app/meson.build b/app/meson.build
index 1798db3ae4..4515688471 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -28,7 +28,6 @@ apps = [
'test-flow-perf',
'test-gpudev',
'test-mldev',
- 'test-pipeline',
'test-pmd',
'test-regex',
'test-sad',
diff --git a/app/test-pipeline/config.c b/app/test-pipeline/config.c
deleted file mode 100644
index daf838948b..0000000000
--- a/app/test-pipeline/config.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_string_fns.h>
-
-#include "main.h"
-
-static const char usage[] = "\n";
-
-void
-app_print_usage(void)
-{
- printf(usage);
-}
-
-static int
-app_parse_port_mask(const char *arg)
-{
- char *end = NULL;
- uint64_t port_mask;
- uint32_t i;
-
- if (arg[0] == '\0')
- return -1;
-
- port_mask = strtoul(arg, &end, 16);
- if ((end == NULL) || (*end != '\0'))
- return -2;
-
- if (port_mask == 0)
- return -3;
-
- app.n_ports = 0;
- for (i = 0; i < 64; i++) {
- if ((port_mask & (1LLU << i)) == 0)
- continue;
-
- if (app.n_ports >= APP_MAX_PORTS)
- return -4;
-
- app.ports[app.n_ports] = i;
- app.n_ports++;
- }
-
- if (!rte_is_power_of_2(app.n_ports))
- return -5;
-
- return 0;
-}
-
-struct {
- const char *name;
- uint32_t value;
-} app_args_table[] = {
- {"none", e_APP_PIPELINE_NONE},
- {"stub", e_APP_PIPELINE_STUB},
- {"hash-8-ext", e_APP_PIPELINE_HASH_KEY8_EXT},
- {"hash-8-lru", e_APP_PIPELINE_HASH_KEY8_LRU},
- {"hash-16-ext", e_APP_PIPELINE_HASH_KEY16_EXT},
- {"hash-16-lru", e_APP_PIPELINE_HASH_KEY16_LRU},
- {"hash-32-ext", e_APP_PIPELINE_HASH_KEY32_EXT},
- {"hash-32-lru", e_APP_PIPELINE_HASH_KEY32_LRU},
- {"hash-spec-8-ext", e_APP_PIPELINE_HASH_SPEC_KEY8_EXT},
- {"hash-spec-8-lru", e_APP_PIPELINE_HASH_SPEC_KEY8_LRU},
- {"hash-spec-16-ext", e_APP_PIPELINE_HASH_SPEC_KEY16_EXT},
- {"hash-spec-16-lru", e_APP_PIPELINE_HASH_SPEC_KEY16_LRU},
- {"hash-spec-32-ext", e_APP_PIPELINE_HASH_SPEC_KEY32_EXT},
- {"hash-spec-32-lru", e_APP_PIPELINE_HASH_SPEC_KEY32_LRU},
- {"acl", e_APP_PIPELINE_ACL},
- {"lpm", e_APP_PIPELINE_LPM},
- {"lpm-ipv6", e_APP_PIPELINE_LPM_IPV6},
- {"hash-cuckoo-8", e_APP_PIPELINE_HASH_CUCKOO_KEY8},
- {"hash-cuckoo-16", e_APP_PIPELINE_HASH_CUCKOO_KEY16},
- {"hash-cuckoo-32", e_APP_PIPELINE_HASH_CUCKOO_KEY32},
- {"hash-cuckoo-48", e_APP_PIPELINE_HASH_CUCKOO_KEY48},
- {"hash-cuckoo-64", e_APP_PIPELINE_HASH_CUCKOO_KEY64},
- {"hash-cuckoo-80", e_APP_PIPELINE_HASH_CUCKOO_KEY80},
- {"hash-cuckoo-96", e_APP_PIPELINE_HASH_CUCKOO_KEY96},
- {"hash-cuckoo-112", e_APP_PIPELINE_HASH_CUCKOO_KEY112},
- {"hash-cuckoo-128", e_APP_PIPELINE_HASH_CUCKOO_KEY128},
-};
-
-int
-app_parse_args(int argc, char **argv)
-{
- int opt, ret;
- char **argvopt;
- int option_index;
- char *prgname = argv[0];
- static struct option lgopts[] = {
- {"none", 0, 0, 0},
- {"stub", 0, 0, 0},
- {"hash-8-ext", 0, 0, 0},
- {"hash-8-lru", 0, 0, 0},
- {"hash-16-ext", 0, 0, 0},
- {"hash-16-lru", 0, 0, 0},
- {"hash-32-ext", 0, 0, 0},
- {"hash-32-lru", 0, 0, 0},
- {"hash-spec-8-ext", 0, 0, 0},
- {"hash-spec-8-lru", 0, 0, 0},
- {"hash-spec-16-ext", 0, 0, 0},
- {"hash-spec-16-lru", 0, 0, 0},
- {"hash-spec-32-ext", 0, 0, 0},
- {"hash-spec-32-lru", 0, 0, 0},
- {"acl", 0, 0, 0},
- {"lpm", 0, 0, 0},
- {"lpm-ipv6", 0, 0, 0},
- {"hash-cuckoo-8", 0, 0, 0},
- {"hash-cuckoo-16", 0, 0, 0},
- {"hash-cuckoo-32", 0, 0, 0},
- {"hash-cuckoo-48", 0, 0, 0},
- {"hash-cuckoo-64", 0, 0, 0},
- {"hash-cuckoo-80", 0, 0, 0},
- {"hash-cuckoo-96", 0, 0, 0},
- {"hash-cuckoo-112", 0, 0, 0},
- {"hash-cuckoo-128", 0, 0, 0},
- {NULL, 0, 0, 0}
- };
- uint32_t lcores[3], n_lcores, lcore_id, pipeline_type_provided;
-
- /* EAL args */
- n_lcores = 0;
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
- if (rte_lcore_is_enabled(lcore_id) == 0)
- continue;
-
- if (n_lcores >= 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- lcores[n_lcores] = lcore_id;
- n_lcores++;
- }
-
- if (n_lcores != 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- app.core_rx = lcores[0];
- app.core_worker = lcores[1];
- app.core_tx = lcores[2];
-
- /* Non-EAL args */
- argvopt = argv;
-
- app.pipeline_type = e_APP_PIPELINE_HASH_KEY16_LRU;
- pipeline_type_provided = 0;
-
- while ((opt = getopt_long(argc, argvopt, "p:",
- lgopts, &option_index)) != EOF) {
- switch (opt) {
- case 'p':
- if (app_parse_port_mask(optarg) < 0) {
- app_print_usage();
- return -1;
- }
- break;
-
- case 0: /* long options */
- if (!pipeline_type_provided) {
- uint32_t i;
-
- for (i = 0; i < e_APP_PIPELINES; i++) {
- if (!strcmp(lgopts[option_index].name,
- app_args_table[i].name)) {
- app.pipeline_type =
- app_args_table[i].value;
- pipeline_type_provided = 1;
- break;
- }
- }
-
- break;
- }
-
- app_print_usage();
- return -1;
-
- default:
- return -1;
- }
- }
-
- if (optind >= 0)
- argv[optind - 1] = prgname;
-
- ret = optind - 1;
- optind = 1; /* reset getopt lib */
- return ret;
-}
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
deleted file mode 100644
index 558f0e428d..0000000000
--- a/app/test-pipeline/init.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-struct app_params app = {
- /* Ports*/
- .n_ports = APP_MAX_PORTS,
- .port_rx_ring_size = 128,
- .port_tx_ring_size = 512,
-
- /* Rings */
- .ring_rx_size = 128,
- .ring_tx_size = 128,
-
- /* Buffer pool */
- .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
- .pool_size = 32 * 1024,
- .pool_cache_size = 256,
-
- /* Burst sizes */
- .burst_size_rx_read = 64,
- .burst_size_rx_write = 64,
- .burst_size_worker_read = 64,
- .burst_size_worker_write = 64,
- .burst_size_tx_read = 64,
- .burst_size_tx_write = 64,
-};
-
-static struct rte_eth_conf port_conf = {
- .rxmode = {
- .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM,
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_hf = RTE_ETH_RSS_IP,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
-};
-
-static struct rte_eth_rxconf rx_conf = {
- .rx_thresh = {
- .pthresh = 8,
- .hthresh = 8,
- .wthresh = 4,
- },
- .rx_free_thresh = 64,
- .rx_drop_en = 0,
-};
-
-static struct rte_eth_txconf tx_conf = {
- .tx_thresh = {
- .pthresh = 36,
- .hthresh = 0,
- .wthresh = 0,
- },
- .tx_free_thresh = 0,
- .tx_rs_thresh = 0,
-};
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
- app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
- app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
- if (app.pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
-
- app.rings_rx[i] = rte_ring_create(
- name,
- app.ring_rx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
-
- app.rings_tx[i] = rte_ring_create(
- name,
- app.ring_tx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static void
-app_ports_check_link(void)
-{
- uint32_t all_ports_up, i;
- char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
- all_ports_up = 1;
-
- for (i = 0; i < app.n_ports; i++) {
- struct rte_eth_link link;
- uint16_t port;
- int ret;
-
- port = app.ports[i];
- memset(&link, 0, sizeof(link));
- ret = rte_eth_link_get_nowait(port, &link);
- if (ret < 0) {
- RTE_LOG(INFO, USER1,
- "Failed to get port %u link status: %s\n",
- port, rte_strerror(-ret));
- all_ports_up = 0;
- continue;
- }
- rte_eth_link_to_str(link_status_text, sizeof(link_status_text),
- &link);
- RTE_LOG(INFO, USER1, "Port %u %s\n",
- port,
- link_status_text);
- if (link.link_status == RTE_ETH_LINK_DOWN)
- all_ports_up = 0;
- }
-
- if (all_ports_up == 0)
- rte_panic("Some NIC ports are DOWN\n");
-}
-
-static void
-app_init_ports(void)
-{
- uint32_t i;
- struct rte_eth_dev_info dev_info;
-
- /* Init NIC ports, then start the ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
- int ret;
- struct rte_eth_conf local_port_conf = port_conf;
-
- port = app.ports[i];
- RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port);
-
- ret = rte_eth_dev_info_get(port, &dev_info);
- if (ret != 0)
- rte_panic("Error during getting device (port %u) info: %s\n",
- port, rte_strerror(-ret));
-
- /* Init port */
- local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
- dev_info.flow_type_rss_offloads;
- if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
- port_conf.rx_adv_conf.rss_conf.rss_hf) {
- printf("Warning:"
- "Port %u modified RSS hash function based on hardware support,"
- "requested:%#"PRIx64" configured:%#"PRIx64"\n",
- port,
- port_conf.rx_adv_conf.rss_conf.rss_hf,
- local_port_conf.rx_adv_conf.rss_conf.rss_hf);
- }
-
- ret = rte_eth_dev_configure(
- port,
- 1,
- 1,
- &local_port_conf);
- if (ret < 0)
- rte_panic("Cannot init NIC port %u (%d)\n", port, ret);
-
- ret = rte_eth_promiscuous_enable(port);
- if (ret != 0)
- rte_panic("Cannot enable promiscuous mode for port %u: %s\n",
- port, rte_strerror(-ret));
-
- /* Init RX queues */
- ret = rte_eth_rx_queue_setup(
- port,
- 0,
- app.port_rx_ring_size,
- rte_eth_dev_socket_id(port),
- &rx_conf,
- app.pool);
- if (ret < 0)
- rte_panic("Cannot init RX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Init TX queues */
- ret = rte_eth_tx_queue_setup(
- port,
- 0,
- app.port_tx_ring_size,
- rte_eth_dev_socket_id(port),
- &tx_conf);
- if (ret < 0)
- rte_panic("Cannot init TX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Start port */
- ret = rte_eth_dev_start(port);
- if (ret < 0)
- rte_panic("Cannot start port %u (%d)\n", port, ret);
- }
-
- app_ports_check_link();
-}
-
-void
-app_init(void)
-{
- app_init_mbuf_pools();
- app_init_rings();
- app_init_ports();
-
- RTE_LOG(INFO, USER1, "Initialization completed\n");
-}
diff --git a/app/test-pipeline/main.c b/app/test-pipeline/main.c
deleted file mode 100644
index e5efafdf28..0000000000
--- a/app/test-pipeline/main.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <errno.h>
-#include <getopt.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-bool force_quit;
-
-static void
-signal_handler(int signum)
-{
- if (signum == SIGINT || signum == SIGTERM)
- force_quit = true;
-}
-
-int
-main(int argc, char **argv)
-{
- uint32_t lcore;
- uint32_t i;
- int ret;
-
- /* Init EAL */
- ret = rte_eal_init(argc, argv);
- if (ret < 0)
- return -1;
- argc -= ret;
- argv += ret;
-
- force_quit = false;
- signal(SIGINT, signal_handler);
- signal(SIGTERM, signal_handler);
-
- /* Parse application arguments (after the EAL ones) */
- ret = app_parse_args(argc, argv);
- if (ret < 0) {
- app_print_usage();
- return -1;
- }
-
- /* Init */
- app_init();
-
- /* Launch per-lcore init on every lcore */
- rte_eal_mp_remote_launch(app_lcore_main_loop, NULL, CALL_MAIN);
- RTE_LCORE_FOREACH_WORKER(lcore) {
- if (rte_eal_wait_lcore(lcore) < 0)
- return -1;
- }
-
- /* Close ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
-
- port = app.ports[i];
- printf("Closing port %d...", port);
- ret = rte_eth_dev_stop(port);
- if (ret != 0)
- printf("rte_eth_dev_stop: err=%d, port=%u\n",
- ret, port);
- rte_eth_dev_close(port);
- printf("Done\n");
- }
-
- /* Clean up the EAL */
- rte_eal_cleanup();
-
- return 0;
-}
-
-int
-app_lcore_main_loop(__rte_unused void *arg)
-{
- unsigned lcore;
-
- lcore = rte_lcore_id();
-
- if (lcore == app.core_rx) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_ACL:
- app_main_loop_rx();
- return 0;
-
- default:
- app_main_loop_rx_metadata();
- return 0;
- }
- }
-
- if (lcore == app.core_worker) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_STUB:
- app_main_loop_worker_pipeline_stub();
- return 0;
-
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- /* cases for cuckoo hash table types */
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- app_main_loop_worker_pipeline_hash();
- return 0;
-
- case e_APP_PIPELINE_ACL:
-#ifndef RTE_LIB_ACL
- rte_exit(EXIT_FAILURE, "ACL not present in build\n");
-#else
- app_main_loop_worker_pipeline_acl();
- return 0;
-#endif
-
- case e_APP_PIPELINE_LPM:
- app_main_loop_worker_pipeline_lpm();
- return 0;
-
- case e_APP_PIPELINE_LPM_IPV6:
- app_main_loop_worker_pipeline_lpm_ipv6();
- return 0;
-
- case e_APP_PIPELINE_NONE:
- default:
- app_main_loop_worker();
- return 0;
- }
- }
-
- if (lcore == app.core_tx) {
- app_main_loop_tx();
- return 0;
- }
-
- return 0;
-}
diff --git a/app/test-pipeline/main.h b/app/test-pipeline/main.h
deleted file mode 100644
index ee9c58ac4c..0000000000
--- a/app/test-pipeline/main.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-#ifndef APP_MBUF_ARRAY_SIZE
-#define APP_MBUF_ARRAY_SIZE 256
-#endif
-
-struct app_mbuf_array {
- struct rte_mbuf *array[APP_MBUF_ARRAY_SIZE];
- uint16_t n_mbufs;
-};
-
-#ifndef APP_MAX_PORTS
-#define APP_MAX_PORTS 4
-#endif
-
-struct __rte_cache_aligned app_params {
- /* CPU cores */
- uint32_t core_rx;
- uint32_t core_worker;
- uint32_t core_tx;
-
- /* Ports*/
- uint32_t ports[APP_MAX_PORTS];
- uint32_t n_ports;
- uint32_t port_rx_ring_size;
- uint32_t port_tx_ring_size;
-
- /* Rings */
- struct rte_ring *rings_rx[APP_MAX_PORTS];
- struct rte_ring *rings_tx[APP_MAX_PORTS];
- uint32_t ring_rx_size;
- uint32_t ring_tx_size;
-
- /* Internal buffers */
- struct app_mbuf_array mbuf_rx;
- struct app_mbuf_array mbuf_tx[APP_MAX_PORTS];
-
- /* Buffer pool */
- struct rte_mempool *pool;
- uint32_t pool_buffer_size;
- uint32_t pool_size;
- uint32_t pool_cache_size;
-
- /* Burst sizes */
- uint32_t burst_size_rx_read;
- uint32_t burst_size_rx_write;
- uint32_t burst_size_worker_read;
- uint32_t burst_size_worker_write;
- uint32_t burst_size_tx_read;
- uint32_t burst_size_tx_write;
-
- /* App behavior */
- uint32_t pipeline_type;
-};
-
-extern struct app_params app;
-
-extern bool force_quit;
-
-int app_parse_args(int argc, char **argv);
-void app_print_usage(void);
-void app_init(void);
-int app_lcore_main_loop(void *arg);
-
-/* Pipeline */
-enum {
- e_APP_PIPELINE_NONE = 0,
- e_APP_PIPELINE_STUB,
-
- e_APP_PIPELINE_HASH_KEY8_EXT,
- e_APP_PIPELINE_HASH_KEY8_LRU,
- e_APP_PIPELINE_HASH_KEY16_EXT,
- e_APP_PIPELINE_HASH_KEY16_LRU,
- e_APP_PIPELINE_HASH_KEY32_EXT,
- e_APP_PIPELINE_HASH_KEY32_LRU,
-
- e_APP_PIPELINE_HASH_SPEC_KEY8_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY8_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY16_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY16_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY32_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY32_LRU,
-
- e_APP_PIPELINE_ACL,
- e_APP_PIPELINE_LPM,
- e_APP_PIPELINE_LPM_IPV6,
-
- e_APP_PIPELINE_HASH_CUCKOO_KEY8,
- e_APP_PIPELINE_HASH_CUCKOO_KEY16,
- e_APP_PIPELINE_HASH_CUCKOO_KEY32,
- e_APP_PIPELINE_HASH_CUCKOO_KEY48,
- e_APP_PIPELINE_HASH_CUCKOO_KEY64,
- e_APP_PIPELINE_HASH_CUCKOO_KEY80,
- e_APP_PIPELINE_HASH_CUCKOO_KEY96,
- e_APP_PIPELINE_HASH_CUCKOO_KEY112,
- e_APP_PIPELINE_HASH_CUCKOO_KEY128,
- e_APP_PIPELINES
-};
-
-void app_main_loop_rx(void);
-void app_main_loop_rx_metadata(void);
-uint64_t test_hash(void *key,
- void *key_mask,
- uint32_t key_size,
- uint64_t seed);
-
-uint32_t test_hash_cuckoo(const void *key,
- uint32_t key_size,
- uint32_t seed);
-
-void app_main_loop_worker(void);
-void app_main_loop_worker_pipeline_stub(void);
-void app_main_loop_worker_pipeline_hash(void);
-void app_main_loop_worker_pipeline_acl(void);
-void app_main_loop_worker_pipeline_lpm(void);
-void app_main_loop_worker_pipeline_lpm_ipv6(void);
-
-void app_main_loop_tx(void);
-
-#define APP_FLUSH 0
-#ifndef APP_FLUSH
-#define APP_FLUSH 0x3FF
-#endif
-
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#endif /* _MAIN_H_ */
diff --git a/app/test-pipeline/meson.build b/app/test-pipeline/meson.build
deleted file mode 100644
index 3add6b637b..0000000000
--- a/app/test-pipeline/meson.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2019 Intel Corporation
-
-if is_windows
- build = false
- reason = 'not supported on Windows'
- subdir_done()
-endif
-
-sources = files(
- 'config.c',
- 'init.c',
- 'main.c',
- 'pipeline_acl.c',
- 'pipeline_hash.c',
- 'pipeline_lpm.c',
- 'pipeline_lpm_ipv6.c',
- 'pipeline_stub.c',
- 'runtime.c',
-)
-deps += ['pipeline', 'pci']
diff --git a/app/test-pipeline/pipeline_acl.c b/app/test-pipeline/pipeline_acl.c
deleted file mode 100644
index 9eb4053e23..0000000000
--- a/app/test-pipeline/pipeline_acl.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_acl.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-/*
- * Here we define the 'shape' of the data we're searching for,
- * by defining the meta-data of the ACL rules.
- * in this case, we're defining 5 tuples. IP addresses, ports,
- * and protocol.
- */
-struct rte_acl_field_def ipv4_field_formats[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, src_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, dst_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr) + sizeof(uint16_t),
- },
-};
-
-
-
-void
-app_main_loop_worker_pipeline_acl(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with ACL table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_acl_params table_acl_params = {
- .name = "test", /* unique identifier for acl contexts */
- .n_rules = 1 << 5,
- .n_rule_fields = DIM(ipv4_field_formats),
- };
-
- /* Copy in the rule meta-data defined above into the params */
- memcpy(table_acl_params.field_format, ipv4_field_formats,
- sizeof(ipv4_field_formats));
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_acl_ops,
- .arg_create = &table_acl_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the ACL table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_entry *entry_ptr;
- int key_found, ret;
-
- memset(&rule_params, 0, sizeof(rule_params));
-
- /* Set the rule values */
- rule_params.field_value[SRC_FIELD_IPV4].value.u32 = 0;
- rule_params.field_value[SRC_FIELD_IPV4].mask_range.u32 = 0;
- rule_params.field_value[DST_FIELD_IPV4].value.u32 =
- i << (24 - rte_popcount32(app.n_ports - 1));
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32 =
- 8 + rte_popcount32(app.n_ports - 1);
- rule_params.field_value[SRCP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[SRCP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[DSTP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[DSTP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[PROTO_FIELD_IPV4].value.u8 = 0;
- rule_params.field_value[PROTO_FIELD_IPV4].mask_range.u8 = 0;
-
- rule_params.priority = 0;
-
- uint32_t dst_addr = rule_params.field_value[DST_FIELD_IPV4].
- value.u32;
- uint32_t dst_mask =
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32;
-
- printf("Adding rule to ACL table (IPv4 destination = "
- "%u.%u.%u.%u/%u => port out = %u)\n",
- (dst_addr & 0xFF000000) >> 24,
- (dst_addr & 0x00FF0000) >> 16,
- (dst_addr & 0x0000FF00) >> 8,
- dst_addr & 0x000000FF,
- dst_mask,
- table_entry.port_id);
-
- /* For ACL, add needs an rte_table_acl_rule_add_params struct */
- ret = rte_pipeline_table_entry_add(p, table_id, &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, ret);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
deleted file mode 100644
index 194e5c5dcc..0000000000
--- a/app/test-pipeline/pipeline_hash.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_hash.h>
-#include <rte_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-static void
-translate_options(uint32_t *special, uint32_t *ext, uint32_t *key_size)
-{
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- *special = 0; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- *special = 0; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- *special = 0; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- *special = 0; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- *special = 1; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- *special = 1; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- *special = 1; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- *special = 1; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- *special = 1; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- *special = 1; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- *special = 0; *ext = 0; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- *special = 0; *ext = 0; *key_size = 48; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- *special = 0; *ext = 0; *key_size = 64; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- *special = 0; *ext = 0; *key_size = 80; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- *special = 0; *ext = 0; *key_size = 96; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- *special = 0; *ext = 0; *key_size = 112; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- *special = 0; *ext = 0; *key_size = 128; return;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-}
-void
-app_main_loop_worker_pipeline_hash(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
- uint32_t special, ext, key_size;
-
- translate_options(&special, &ext, &key_size);
-
- RTE_LOG(INFO, USER1, "Core %u is doing work "
- "(pipeline with hash table, %s, %s, %d-byte key)\n",
- rte_lcore_id(),
- special ? "specialized" : "non-specialized",
- ext ? "extendible bucket" : "LRU",
- key_size);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- struct rte_table_hash_params table_hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash,
- .seed = 0,
- };
-
- struct rte_table_hash_cuckoo_params table_hash_cuckoo_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash_cuckoo,
- .seed = 0,
- };
-
- /* Table configuration */
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table)\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_cuckoo_ops,
- .arg_create = &table_hash_cuckoo_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < (1 << 24); i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_pipeline_table_entry *entry_ptr;
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) key;
- int key_found, status;
-
- memset(key, 0, sizeof(key));
- k32[0] = rte_be_to_cpu_32(i);
-
- status = rte_pipeline_table_entry_add(p, table_id, key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
-
-uint64_t test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-uint32_t test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-void
-app_main_loop_rx_metadata(void) {
- uint32_t i, j;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX (with meta-data)\n",
- rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- for (j = 0; j < n_mbufs; j++) {
- struct rte_mbuf *m;
- uint8_t *m_data, *key;
- struct rte_ipv4_hdr *ip_hdr;
- struct rte_ipv6_hdr *ipv6_hdr;
- uint32_t ip_dst;
- uint32_t *signature, *k32;
-
- m = app.mbuf_rx.array[j];
- m_data = rte_pktmbuf_mtod(m, uint8_t *);
- signature = RTE_MBUF_METADATA_UINT32_PTR(m,
- APP_METADATA_OFFSET(0));
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
- ip_hdr = (struct rte_ipv4_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
- ip_dst = ip_hdr->dst_addr;
-
- k32 = (uint32_t *) key;
- k32[0] = ip_dst & 0xFFFFFF00;
- } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
- ipv6_hdr = (struct rte_ipv6_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
-
- memcpy(key, &ipv6_hdr->dst_addr, 16);
- } else
- continue;
-
- *signature = test_hash(key, NULL, 0, 0);
- }
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
diff --git a/app/test-pipeline/pipeline_lpm.c b/app/test-pipeline/pipeline_lpm.c
deleted file mode 100644
index 8a59bd0042..0000000000
--- a/app/test-pipeline/pipeline_lpm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-#ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s
-#define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256
-#endif
-
-void
-app_main_loop_worker_pipeline_lpm(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with "
- "LPM table)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_params table_lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s,
- .flags = 0,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ops,
- .arg_create = &table_lpm_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_key key = {
- .ip = i << (24 - rte_popcount32(app.n_ports - 1)),
- .depth = 8 + rte_popcount32(app.n_ports - 1),
- };
-
- struct rte_pipeline_table_entry *entry_ptr;
-
- int key_found, status;
-
- printf("Adding rule to LPM table (IPv4 destination = %"
- PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8
- " => port out = %" PRIu32 ")\n",
- (key.ip & 0xFF000000) >> 24,
- (key.ip & 0x00FF0000) >> 16,
- (key.ip & 0x0000FF00) >> 8,
- key.ip & 0x000000FF,
- key.depth,
- i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_lpm_ipv6.c b/app/test-pipeline/pipeline_lpm_ipv6.c
deleted file mode 100644
index 6558e887c8..0000000000
--- a/app/test-pipeline/pipeline_lpm_ipv6.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_lpm_ipv6(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with IPv6 LPM table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_ipv6_params table_lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 21,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ipv6_ops,
- .arg_create = &table_lpm_ipv6_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the IPv6 LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_ipv6_key key;
- struct rte_pipeline_table_entry *entry_ptr;
- uint32_t ip;
- int key_found, status;
-
- key.depth = 8 + rte_popcount32(app.n_ports - 1);
-
- ip = rte_bswap32(i << (24 -
- rte_popcount32(app.n_ports - 1)));
- memcpy(&key.ip, &ip, sizeof(uint32_t));
-
- printf("Adding rule to IPv6 LPM table (IPv6 destination = "
- RTE_IPV6_ADDR_FMT "/%u => port out = %u)\n",
- RTE_IPV6_ADDR_SPLIT(&key.ip),
- key.depth, i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_stub.c b/app/test-pipeline/pipeline_stub.c
deleted file mode 100644
index 48a638aad7..0000000000
--- a/app/test-pipeline/pipeline_stub.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_port_ring.h>
-#include <rte_table_stub.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_stub(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id[APP_MAX_PORTS];
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with stub "
- "tables)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i]))
- rte_panic("Unable to configure table %u\n", i);
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i]))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i ^ 1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (rte_pipeline_table_default_entry_add(p, table_id[i], &entry,
- &default_entry_ptr))
- rte_panic("Unable to add default entry to table %u\n",
- table_id[i]);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/runtime.c b/app/test-pipeline/runtime.c
deleted file mode 100644
index 752f783370..0000000000
--- a/app/test-pipeline/runtime.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_malloc.h>
-
-#include "main.h"
-
-void
-app_main_loop_rx(void) {
- uint32_t i;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs, NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_worker(void) {
- struct app_mbuf_array *worker_mbuf;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (no pipeline)\n",
- rte_lcore_id());
-
- worker_mbuf = rte_malloc_socket(NULL, sizeof(struct app_mbuf_array),
- RTE_CACHE_LINE_SIZE, rte_socket_id());
- if (worker_mbuf == NULL)
- rte_panic("Worker thread: cannot allocate buffer space\n");
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- int ret;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_rx[i],
- (void **) worker_mbuf->array,
- app.burst_size_worker_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_tx[i ^ 1],
- (void **) worker_mbuf->array,
- app.burst_size_worker_write,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_tx(void) {
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing TX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs, n_pkts;
- int ret;
-
- n_mbufs = app.mbuf_tx[i].n_mbufs;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_tx[i],
- (void **) &app.mbuf_tx[i].array[n_mbufs],
- app.burst_size_tx_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- n_mbufs += app.burst_size_tx_read;
-
- if (n_mbufs < app.burst_size_tx_write) {
- app.mbuf_tx[i].n_mbufs = n_mbufs;
- continue;
- }
-
- n_pkts = rte_eth_tx_burst(
- app.ports[i],
- 0,
- app.mbuf_tx[i].array,
- n_mbufs);
-
- if (n_pkts < n_mbufs) {
- uint16_t k;
-
- for (k = n_pkts; k < n_mbufs; k++) {
- struct rte_mbuf *pkt_to_free;
-
- pkt_to_free = app.mbuf_tx[i].array[k];
- rte_pktmbuf_free(pkt_to_free);
- }
- }
-
- app.mbuf_tx[i].n_mbufs = 0;
- }
- }
-}
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index c8cc86295d..6ad0cf6eec 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -77,6 +77,9 @@ Removed Items
``rte_rib6_is_equal``
* table: ``RTE_LPM_IPV6_ADDR_SIZE``
+* Removed the ``dpdk-test-pipeline`` application, which was based on
+ the legacy pipeline library API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/img/test_pipeline_app.png b/doc/guides/sample_app_ug/img/test_pipeline_app.png
deleted file mode 100644
index d322a9e46e5e714126988a76456c9eae41635879..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 67410
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%0D%V3H
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"Exg8HvZ0ke@W&Fw<
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
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index f12623bb66..c8b50b801c 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -45,7 +45,6 @@ Sample Applications User Guides
vhost_crypto
vdpa
ip_pipeline
- test_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/test_pipeline.rst b/doc/guides/sample_app_ug/test_pipeline.rst
deleted file mode 100644
index e53d77a170..0000000000
--- a/doc/guides/sample_app_ug/test_pipeline.rst
+++ /dev/null
@@ -1,237 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2010-2014 Intel Corporation.
-
-Test Pipeline Application
-=========================
-
-The Test Pipeline application illustrates the use of the DPDK Packet Framework tool suite.
-Its purpose is to demonstrate the performance of single-table DPDK pipelines.
-
-Overview
---------
-
-The application uses three CPU cores:
-
-* Core A ("RX core") receives traffic from the NIC ports and feeds core B with traffic through SW queues.
-
-* Core B ("Pipeline core") implements a single-table DPDK pipeline
- whose type is selectable through specific command line parameter.
- Core B receives traffic from core A through software queues,
- processes it according to the actions configured in the table entries that
- are hit by the input packets and feeds it to core C through another set of software queues.
-
-* Core C ("TX core") receives traffic from core B through software queues and sends it to the NIC ports for transmission.
-
-.. figure:: img/test_pipeline_app.*
-
- Test Pipeline Application
-
-Compiling the Application
--------------------------
-To compile the sample application see :doc:`compiling`
-
-The application is located in the ``dpdk/<build_dir>/app`` directory.
-
-
-Running the Application
------------------------
-
-Application Command Line
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The application execution command line is:
-
-.. code-block:: console
-
- ./dpdk-test-pipeline [EAL options] -- -p PORTMASK --TABLE_TYPE
-
-The ``-l/--lcores`` EAL CPU corelist option has to contain exactly 3 CPU cores.
-The first CPU core in the core mask is assigned for core A, the second for core B and the third for core C.
-
-The PORTMASK parameter must contain 2 or 4 ports.
-
-Table Types and Behavior
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-:numref:`test_pipeline_table_1` describes the table types used and how they are populated.
-
-The hash tables are pre-populated with 16 million keys.
-For hash tables, the following parameters can be selected:
-
-* **Configurable key size implementation or fixed (specialized) key size implementation (e.g. hash-8-ext or hash-spec-8-ext).**
- The key size specialized implementations are expected to provide better performance for 8-byte and 16-byte key sizes,
- while the key-size-non-specialized implementation is expected to provide better performance for larger key sizes;
-
-* **Key size (e.g. hash-spec-8-ext or hash-spec-16-ext).**
- The available options are 8, 16 and 32 bytes;
-
-* **Table type (e.g. hash-spec-16-ext or hash-spec-16-lru).**
- The available options are ext (extendable bucket) or lru (least recently used).
-
-.. _test_pipeline_table_1:
-
-.. table:: Table Types
-
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | **#** | **TABLE_TYPE** | **Description of Core B Table** | **Pre-added Table Entries** |
- | | | | |
- +=======+========================+==========================================================+=======================================================+
- | 1 | none | Core B is not implementing a DPDK pipeline. | N/A |
- | | | Core B is implementing a pass-through from its input set | |
- | | | of software queues to its output set of software queues. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 2 | stub | Stub table. Core B is implementing the same pass-through | N/A |
- | | | functionality as described for the "none" option by | |
- | | | using the DPDK Packet Framework by using one | |
- | | | stub table for each input NIC port. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 3 | hash-[spec]-8-lru | LRU hash table with 8-byte key size and 16 million | 16 million entries are successfully added to the |
- | | | entries. | hash table with the following key format: |
- | | | | |
- | | | | [4-byte index, 4 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Sendto output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | core B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 4 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 4 | hash-[spec]-8-ext | Extendable bucket hash table with 8-byte key size | Same as hash-[spec]-8-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 5 | hash-[spec]-16-lru | LRU hash table with 16-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 12 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for core |
- | | | | B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 12 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 6 | hash-[spec]-16-ext | Extendable bucket hash table with 16-byte key size | Same as hash-[spec]-16-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 7 | hash-[spec]-32-lru | LRU hash table with 32-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 28 bytes of 0]. |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | Lpmcore B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 28 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 8 | hash-[spec]-32-ext | Extendable bucket hash table with 32-byte key size | Same as hash-[spec]-32-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 9 | lpm | Longest Prefix Match (LPM) IPv4 table. | In the case of two ports, two routes |
- | | | | are added to the table: |
- | | | | |
- | | | | [0.0.0.0/9 => send to output port 0] |
- | | | | |
- | | | | [0.128.0.0/9 => send to output port 1] |
- | | | | |
- | | | | In case of four ports, four entries are added to the |
- | | | | table: |
- | | | | |
- | | | | [0.0.0.0/10 => send to output port 0] |
- | | | | |
- | | | | [0.64.0.0/10 => send to output port 1] |
- | | | | |
- | | | | [0.128.0.0/10 => send to output port 2] |
- | | | | |
- | | | | [0.192.0.0/10 => send to output port 3] |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is storing the IPv4 destination |
- | | | | within the packet meta data to be later used by core |
- | | | | B as the lookup key. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 10 | acl | Access Control List (ACL) table | In the case of two ports, two ACL rules are added to |
- | | | | the table: |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.0.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0] |
- | | | | |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.128.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0]. |
- | | | | |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
-
-Input Traffic
-~~~~~~~~~~~~~
-
-Regardless of the table type used for the core B pipeline,
-the same input traffic can be used to hit all table entries with uniform distribution,
-which results in uniform distribution of packets sent out on the set of output NIC ports.
-The profile for input traffic is TCP/IPv4 packets with:
-
-* destination IP address as A.B.C.D with A fixed to 0 and B, C,D random
-
-* source IP address fixed to 0.0.0.0
-
-* destination TCP port fixed to 0
-
-* source TCP port fixed to 0
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC v2 3/6] examples/ip_pipeline: remove example
2026-07-27 23:11 ` [RFC v2 0/6] remove legacy packet framework Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 1/6] app/test: remove packet framework tests Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 2/6] app/test-pipeline: remove application Stephen Hemminger
@ 2026-07-27 23:11 ` Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 4/6] pipeline: remove legacy API Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 6/6] port: " Stephen Hemminger
4 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-27 23:11 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon, Cristian Dumitrescu
The ip_pipeline example is built on the legacy pipeline library
API (rte_pipeline_*) and the associated port and table action
APIs, which were announced for removal in the 24.11 release.
The pipeline example covers the SWX pipeline API.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
doc/guides/nics/softnic.rst | 3 +-
doc/guides/rel_notes/release_26_11.rst | 4 +
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
examples/ip_pipeline/Makefile | 60 -
examples/ip_pipeline/action.c | 391 -
examples/ip_pipeline/action.h | 78 -
examples/ip_pipeline/cli.c | 6791 -----------------
examples/ip_pipeline/cli.h | 18 -
examples/ip_pipeline/common.h | 12 -
examples/ip_pipeline/conn.c | 330 -
examples/ip_pipeline/conn.h | 47 -
examples/ip_pipeline/cryptodev.c | 160 -
examples/ip_pipeline/cryptodev.h | 46 -
examples/ip_pipeline/examples/firewall.cli | 59 -
examples/ip_pipeline/examples/flow.cli | 60 -
examples/ip_pipeline/examples/flow_crypto.cli | 57 -
examples/ip_pipeline/examples/l2fwd.cli | 51 -
examples/ip_pipeline/examples/route.cli | 60 -
examples/ip_pipeline/examples/route_ecmp.cli | 57 -
| 112 -
examples/ip_pipeline/examples/tap.cli | 66 -
examples/ip_pipeline/link.c | 270 -
examples/ip_pipeline/link.h | 66 -
examples/ip_pipeline/main.c | 260 -
examples/ip_pipeline/mempool.c | 82 -
examples/ip_pipeline/mempool.h | 40 -
examples/ip_pipeline/meson.build | 30 -
examples/ip_pipeline/parser.c | 506 --
examples/ip_pipeline/parser.h | 56 -
examples/ip_pipeline/pipeline.c | 1078 ---
examples/ip_pipeline/pipeline.h | 425 --
examples/ip_pipeline/swq.c | 76 -
examples/ip_pipeline/swq.h | 37 -
examples/ip_pipeline/tap.c | 102 -
examples/ip_pipeline/tap.h | 29 -
examples/ip_pipeline/thread.c | 3137 --------
examples/ip_pipeline/thread.h | 24 -
examples/ip_pipeline/tmgr.c | 248 -
examples/ip_pipeline/tmgr.h | 74 -
examples/meson.build | 1 -
42 files changed, 5 insertions(+), 15532 deletions(-)
delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
delete mode 100644 examples/ip_pipeline/Makefile
delete mode 100644 examples/ip_pipeline/action.c
delete mode 100644 examples/ip_pipeline/action.h
delete mode 100644 examples/ip_pipeline/cli.c
delete mode 100644 examples/ip_pipeline/cli.h
delete mode 100644 examples/ip_pipeline/common.h
delete mode 100644 examples/ip_pipeline/conn.c
delete mode 100644 examples/ip_pipeline/conn.h
delete mode 100644 examples/ip_pipeline/cryptodev.c
delete mode 100644 examples/ip_pipeline/cryptodev.h
delete mode 100644 examples/ip_pipeline/examples/firewall.cli
delete mode 100644 examples/ip_pipeline/examples/flow.cli
delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
delete mode 100644 examples/ip_pipeline/examples/route.cli
delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
delete mode 100644 examples/ip_pipeline/examples/rss.cli
delete mode 100644 examples/ip_pipeline/examples/tap.cli
delete mode 100644 examples/ip_pipeline/link.c
delete mode 100644 examples/ip_pipeline/link.h
delete mode 100644 examples/ip_pipeline/main.c
delete mode 100644 examples/ip_pipeline/mempool.c
delete mode 100644 examples/ip_pipeline/mempool.h
delete mode 100644 examples/ip_pipeline/meson.build
delete mode 100644 examples/ip_pipeline/parser.c
delete mode 100644 examples/ip_pipeline/parser.h
delete mode 100644 examples/ip_pipeline/pipeline.c
delete mode 100644 examples/ip_pipeline/pipeline.h
delete mode 100644 examples/ip_pipeline/swq.c
delete mode 100644 examples/ip_pipeline/swq.h
delete mode 100644 examples/ip_pipeline/tap.c
delete mode 100644 examples/ip_pipeline/tap.h
delete mode 100644 examples/ip_pipeline/thread.c
delete mode 100644 examples/ip_pipeline/thread.h
delete mode 100644 examples/ip_pipeline/tmgr.c
delete mode 100644 examples/ip_pipeline/tmgr.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 4c06f85706..ae84e7f289 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,9 +1739,7 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: examples/ip_pipeline/
F: examples/pipeline/
-F: doc/guides/sample_app_ug/ip_pipeline.rst
Algorithms
diff --git a/doc/guides/nics/softnic.rst b/doc/guides/nics/softnic.rst
index 603fdb49c4..87f3e5adc0 100644
--- a/doc/guides/nics/softnic.rst
+++ b/doc/guides/nics/softnic.rst
@@ -10,8 +10,7 @@ is DIY and reconfigurable through ``firmware`` (DPDK Packet Framework script).
The Soft NIC leverages the DPDK Packet Framework libraries (librte_port,
librte_table and librte_pipeline) to make it modular, flexible and extensible
with new functionality.
-Please refer to :doc:`/prog_guide/packet_framework` and
-:doc:`/sample_app_ug/ip_pipeline` for more details.
+Please refer to :doc:`/prog_guide/packet_framework` for more details.
The Soft NIC is configured through the standard DPDK ethdev API (ethdev, flow,
QoS, security). The internal framework is not externally visible.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 6ad0cf6eec..fc84ba367e 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -80,6 +80,10 @@ Removed Items
* Removed the ``dpdk-test-pipeline`` application, which was based on
the legacy pipeline library API.
+* Removed the ``ip_pipeline`` example application, which was based on
+ the legacy pipeline library API.
+ The ``pipeline`` example application covers the SWX pipeline API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index c8b50b801c..28c4c9a5b2 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -44,7 +44,6 @@ Sample Applications User Guides
vhost_blk
vhost_crypto
vdpa
- ip_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/ip_pipeline.rst b/doc/guides/sample_app_ug/ip_pipeline.rst
deleted file mode 100644
index 9a5cb517a2..0000000000
--- a/doc/guides/sample_app_ug/ip_pipeline.rst
+++ /dev/null
@@ -1,531 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2015-2018 Intel Corporation.
-
-Internet Protocol (IP) Pipeline Application
-===========================================
-
-Application overview
---------------------
-
-The *Internet Protocol (IP) Pipeline* application is intended to be a vehicle for rapid development of packet processing
-applications on multi-core CPUs.
-
-Following OpenFlow and P4 design principles, the application can be used to create functional blocks called pipelines out
-of input/output ports, tables and actions in a modular way. Multiple pipelines can be inter-connected through packet queues
-to create complete applications (super-pipelines).
-
-The pipelines are mapped to application threads, with each pipeline executed by a single thread and each thread able to run
-one or several pipelines. The possibilities of creating pipelines out of ports, tables and actions, connecting multiple
-pipelines together and mapping the pipelines to execution threads are endless, therefore this application can be seen as
-a true application generator.
-
-Pipelines are created and managed through Command Line Interface (CLI):
-
- * Any standard TCP client (e.g. telnet, netcat, custom script, etc) is typically able to connect to the application, send
- commands through the network and wait for the response before pushing the next command.
-
- * All the application objects are created and managed through CLI commands:
- * 'Primitive' objects used to create pipeline ports: memory pools, links (i.e. network interfaces), SW queues, traffic managers, etc.
- * Action profiles: used to define the actions to be executed by pipeline input/output ports and tables.
- * Pipeline components: input/output ports, tables, pipelines, mapping of pipelines to execution threads.
-
-Running the application
------------------------
-
-The application startup command line is::
-
- dpdk-ip_pipeline [EAL_ARGS] -- [-s SCRIPT_FILE] [-h HOST] [-p PORT]
-
-The application startup arguments are:
-
-``-s SCRIPT_FILE``
-
- * Optional: Yes
-
- * Default: Not present
-
- * Argument: Path to the CLI script file to be run at application startup.
- No CLI script file will run at startup if this argument is not present.
-
-``-h HOST``
-
- * Optional: Yes
-
- * Default: ``0.0.0.0``
-
- * Argument: IP Address of the host running ip pipeline application to be used by
- remote TCP based client (telnet, netcat, etc.) for connection.
-
-``-p PORT``
-
- * Optional: Yes
-
- * Default: ``8086``
-
- * Argument: TCP port number at which the ip pipeline is running.
- This port number should be used by remote TCP client (such as telnet, netcat, etc.) to connect to host application.
-
-Refer to *DPDK Getting Started Guide* for general information on running applications and the Environment Abstraction Layer (EAL) options.
-
-The following is an example command to run ip pipeline application configured for layer 2 forwarding:
-
-.. code-block:: console
-
- $ ./<build_dir>/examples/dpdk-ip_pipeline -l 0,1 -- -s examples/route_ecmp.cli
-
-The application should start successfully and display as follows:
-
-.. code-block:: console
-
- EAL: Detected 40 lcore(s)
- EAL: Detected 2 NUMA nodes
- EAL: Multi-process socket /var/run/.rte_unix
- EAL: Probing VFIO support...
- EAL: PCI device 0000:02:00.0 on NUMA socket 0
- EAL: probe driver: 8086:10fb net_ixgbe
- ...
-
-To run remote client (e.g. telnet) to communicate with the ip pipeline application:
-
-.. code-block:: console
-
- $ telnet 127.0.0.1 8086
-
-When running a telnet client as above, command prompt is displayed:
-
-.. code-block:: console
-
- Trying 127.0.0.1...
- Connected to 127.0.0.1.
- Escape character is '^]'.
-
- Welcome to IP Pipeline!
-
- pipeline>
-
-Once application and telnet client start running, messages can be sent from client to application.
-At any stage, telnet client can be terminated using the quit command.
-
-
-Application stages
-------------------
-
-Initialization
-~~~~~~~~~~~~~~
-
-During this stage, EAL layer is initialised and application specific arguments are parsed. Furthermore, the data structures
-(i.e. linked lists) for application objects are initialized. In case of any initialization error, an error message
-is displayed and the application is terminated.
-
-Run-time
-~~~~~~~~
-
-The main thread is creating and managing all the application objects based on CLI input.
-
-Each data plane thread runs one or several pipelines previously assigned to it in round-robin order. Each data plane thread
-executes two tasks in time-sharing mode:
-
-#. *Packet processing task*: Process bursts of input packets read from the pipeline input ports.
-
-#. *Message handling task*: Periodically, the data plane thread pauses the packet processing task and polls for request
- messages send by the main thread. Examples: add/remove pipeline to/from current data plane thread, add/delete rules
- to/from given table of a specific pipeline owned by the current data plane thread, read statistics, etc.
-
-Examples
---------
-
-.. tabularcolumns:: |p{3cm}|p{5cm}|p{4cm}|p{4cm}|
-
-.. table:: Pipeline examples provided with the application
-
- +-----------------------+----------------------+----------------+------------------------------------+
- | Name | Table(s) | Actions | Messages |
- +=======================+======================+================+====================================+
- | L2fwd | Stub | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | Note: Implemented | | | 3. Pipeline create |
- | using pipeline with | | | 4. Pipeline port in/out |
- | a simple pass-through | | | 5. Pipeline table |
- | connection between | | | 6. Pipeline port in table |
- | input and output | | | 7. Pipeline enable |
- | ports. | | | 8. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Flow classification | Exact match | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = byte array | | 3. Pipeline create |
- | | (16 bytes) | | 4. Pipeline port in/out |
- | | * Offset = 278 | | 5. Pipeline table |
- | | * Table size = 64K | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Firewall | ACL | Allow/Drop | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = n-tuple | | 3. Pipeline create |
- | | * Offset = 270 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | IP routing | LPM (IPv4) | Forward | 1. Mempool Create |
- | | | | 2. Link create |
- | | * Key = IP dest addr | | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Equal-cost multi-path | LPM (IPv4) | Forward, | 1. Mempool Create |
- | routing (ECMP) | | load balance, | 2. Link create |
- | | * Key = IP dest addr | encap ether | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table (LPM) |
- | | | | 6. Pipeline table (Array) |
- | | | | 7. Pipeline port in table (LPM) |
- | | Array | | 8. Pipeline enable |
- | | | | 9. Pipeline table rule add default |
- | | * Key = Array index | | 10. Pipeline table rule add(LPM) |
- | | * Offset = 256 | | 11. Pipeline table rule add(Array) |
- | | * Size = 64K | | |
- | | | | |
- +-----------------------+----------------------+----------------+------------------------------------+
-
-Command Line Interface (CLI)
-----------------------------
-
-Link
-~~~~
-
- Link configuration ::
-
- link <link_name>
- dev <device_name>|port <port_id>
- rxq <n_queues> <queue_size> <mempool_name>
- txq <n_queues> <queue_size> promiscuous on | off
- [rss <qid_0> ... <qid_n>]
-
- Note: The PCI device name must be specified in the Domain:Bus:Device.Function format.
-
-
-Mempool
-~~~~~~~
-
- Mempool create ::
-
- mempool <mempool_name> buffer <buffer_size>
- pool <pool_size> cache <cache_size> cpu <cpu_id>
-
-
-Software queue
-~~~~~~~~~~~~~~
-
- Create software queue ::
-
- swq <swq_name> size <size> cpu <cpu_id>
-
-
-Traffic manager
-~~~~~~~~~~~~~~~
-
- Add traffic manager subport profile ::
-
- tmgr subport profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
-
- Add traffic manager pipe profile ::
-
- tmgr pipe profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
- <tc_ov_weight>
- <wrr_weight0..3>
-
- Create traffic manager port ::
-
- tmgr <tmgr_name>
- rate <rate>
- spp <n_subports_per_port>
- pps <n_pipes_per_subport>
- fo <frame_overhead>
- mtu <mtu>
- cpu <cpu_id>
-
- Configure traffic manager subport ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- profile <subport_profile_id>
-
- Configure traffic manager pipe ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- pipe from <pipe_id_first> to <pipe_id_last>
- profile <pipe_profile_id>
-
-
-Tap
-~~~
-
- Create tap port ::
-
- tap <name>
-
-
-Cryptodev
-~~~~~~~~~
-
- Create cryptodev port ::
-
- cryptodev <cryptodev_name>
- dev <DPDK Cryptodev PMD name>
- queue <n_queues> <queue_size>
-
-Action profile
-~~~~~~~~~~~~~~
-
- Create action profile for pipeline input port ::
-
- port in action profile <profile_name>
- [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
- [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
-
- Create action profile for the pipeline table ::
-
- table action profile <profile_name>
- ipv4 | ipv6
- offset <ip_offset>
- fwd
- [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
- [meter srtcm | trtcm
- tc <n_tc>
- stats none | pkts | bytes | both]
- [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
- [encap ether | vlan | qinq | mpls | pppoe]
- [nat src | dst
- proto udp | tcp]
- [ttl drop | fwd
- stats none | pkts]
- [stats pkts | bytes | both]
- [sym_crypto cryptodev <cryptodev_name>
- mempool_create <mempool_name> mempool_init <mempool_name>]
- [time]
-
-
-Pipeline
-~~~~~~~~
-
-Create pipeline ::
-
- pipeline <pipeline_name>
- period <timer_period_ms>
- offset_port_id <offset_port_id>
- cpu <cpu_id>
-
-Create pipeline input port ::
-
- pipeline <pipeline_name> port in
- bsz <burst_size>
- link <link_name> rxq <queue_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name> mempool <mempool_name> mtu <mtu>
- | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
- [action <port_in_action_profile_name>]
- [disabled]
-
-Create pipeline output port ::
-
- pipeline <pipeline_name> port out
- bsz <burst_size>
- link <link_name> txq <txq_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name>
- | sink [file <file_name> pkts <max_n_pkts>]
-
-Create pipeline table ::
-
- pipeline <pipeline_name> table
- match
- acl
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | array
- offset <key_offset>
- size <n_keys>
- | hash
- ext | lru
- key <key_size>
- mask <key_mask>
- offset <key_offset>
- buckets <n_buckets>
- size <n_keys>
- | lpm
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | stub
- [action <table_action_profile_name>]
-
-Connect pipeline input port to table ::
-
- pipeline <pipeline_name> port in <port_id> table <table_id>
-
-Display statistics for specific pipeline input port, output port
-or table ::
-
- pipeline <pipeline_name> port in <port_id> stats read [clear]
- pipeline <pipeline_name> port out <port_id> stats read [clear]
- pipeline <pipeline_name> table <table_id> stats read [clear]
-
-Enable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Disable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Add default rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
- match
- default
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
-
-Add rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
-
- match
- acl
- priority <priority>
- ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- <sp0> <sp1> <dp0> <dp1> <proto>
- | array <pos>
- | hash
- raw <key>
- | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv4_addr <addr>
- | ipv6_addr <addr>
- | qinq <svlan> <cvlan>
- | lpm
- ipv4 | ipv6 <addr> <depth>
-
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
- [balance <out0> ... <out7>]
- [meter
- tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- [tm subport <subport_id> pipe <pipe_id>]
- [encap
- ether <da> <sa>
- | vlan <da> <sa> <pcp> <dei> <vid>
- | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- | mpls unicast | multicast
- <da> <sa>
- label0 <label> <tc> <ttl>
- [label1 <label> <tc> <ttl>
- [label2 <label> <tc> <ttl>
- [label3 <label> <tc> <ttl>]]]
- | pppoe <da> <sa> <session_id>]
- [nat ipv4 | ipv6 <addr> <port>]
- [ttl dec | keep]
- [stats]
- [time]
- [sym_crypto
- encrypt | decrypt
- type
- | cipher
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- | cipher_auth
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- auth_algo <algo> auth_key <key> digest_size <size>
- | aead
- aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- digest_size <size>
- data_offset <data_offset>]
-
- where:
- <pa> ::= g | y | r | drop
-
-Add bulk rules to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
-
- Where:
- - file_name = path to file
- - File line format = match <match> action <action>
-
-Delete table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match <match>
-
-Delete default table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match
- default
-
-Add meter profile to the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
- add srtcm cir <cir> cbs <cbs> ebs <ebs>
- | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
-
-Delete meter profile from the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id>
- meter profile <meter_profile_id> delete
-
-
-Update the dscp table for meter or traffic manager action for specific
-pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> dscp <file_name>
-
- Where:
- - file_name = path to file
- - exactly 64 lines
- - File line format = <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
-
-
-Pipeline enable/disable
-~~~~~~~~~~~~~~~~~~~~~~~
-
- Enable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> enable
-
-
- Disable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> disable
diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
deleted file mode 100644
index 438aa6b37f..0000000000
--- a/examples/ip_pipeline/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2010-2018 Intel Corporation
-
-# binary name
-APP = ip_pipeline
-
-# all source are stored in SRCS-y
-SRCS-y := action.c
-SRCS-y += cli.c
-SRCS-y += conn.c
-SRCS-y += link.c
-SRCS-y += main.c
-SRCS-y += mempool.c
-SRCS-y += parser.c
-SRCS-y += pipeline.c
-SRCS-y += swq.c
-SRCS-y += tap.c
-SRCS-y += thread.c
-SRCS-y += tmgr.c
-SRCS-y += cryptodev.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)
-
-CFLAGS += -I. -DALLOW_EXPERIMENTAL_API -D_GNU_SOURCE
-
-OBJS := $(patsubst %.c,build/%.o,$(SRCS-y))
-
-build/%.o: %.c Makefile $(PC_FILE) | build
- $(CC) $(CFLAGS) -c $< -o $@
-
-build/$(APP)-shared: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
-
-build/$(APP)-static: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
-
-build:
- @mkdir -p $@
-
-.PHONY: clean
-clean:
- rm -f build/$(APP)* build/*.o
- test -d build && rmdir -p build || true
diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
deleted file mode 100644
index d2104aad6e..0000000000
--- a/examples/ip_pipeline/action.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-#include <rte_table_hash_func.h>
-
-#include "action.h"
-
-/**
- * Input port
- */
-static struct port_in_action_profile_list port_in_action_profile_list;
-
-int
-port_in_action_profile_init(void)
-{
- TAILQ_INIT(&port_in_action_profile_list);
-
- return 0;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name)
-{
- struct port_in_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &port_in_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params)
-{
- struct port_in_action_profile *profile;
- struct rte_port_in_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- port_in_action_profile_find(name) ||
- (params == NULL))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
- /* Resource */
- ap = rte_port_in_action_profile_create(0);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_FLTR,
- ¶ms->fltr);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_port_in_action_profile_freeze(ap);
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct port_in_action_profile));
- if (profile == NULL) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&port_in_action_profile_list, profile, node);
-
- return profile;
-}
-
-/**
- * Table
- */
-static struct table_action_profile_list table_action_profile_list;
-
-int
-table_action_profile_init(void)
-{
- TAILQ_INIT(&table_action_profile_list);
-
- return 0;
-}
-
-struct table_action_profile *
-table_action_profile_find(const char *name)
-{
- struct table_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &table_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params)
-{
- struct table_action_profile *profile;
- struct rte_table_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- table_action_profile_find(name) ||
- (params == NULL) ||
- ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
-
- /* Resource */
- ap = rte_table_action_profile_create(¶ms->common);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_FWD,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_MTR,
- ¶ms->mtr);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TM,
- ¶ms->tm);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_ENCAP,
- ¶ms->encap);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_NAT,
- ¶ms->nat);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TTL,
- ¶ms->ttl);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_STATS,
- ¶ms->stats);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TIME,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- ¶ms->sym_crypto);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TAG,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_DECAP,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_table_action_profile_freeze(ap);
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct table_action_profile));
- if (profile == NULL) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node);
-
- return profile;
-}
diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
deleted file mode 100644
index cde17e69a3..0000000000
--- a/examples/ip_pipeline/action.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_ACTION_H_
-#define _INCLUDE_ACTION_H_
-
-#include <sys/queue.h>
-
-#include <rte_port_in_action.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-
-/**
- * Input port action
- */
-struct port_in_action_profile_params {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-struct port_in_action_profile {
- TAILQ_ENTRY(port_in_action_profile) node;
- char name[NAME_SIZE];
- struct port_in_action_profile_params params;
- struct rte_port_in_action_profile *ap;
-};
-
-TAILQ_HEAD(port_in_action_profile_list, port_in_action_profile);
-
-int
-port_in_action_profile_init(void);
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name);
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params);
-
-/**
- * Table action
- */
-struct table_action_profile_params {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-struct table_action_profile {
- TAILQ_ENTRY(table_action_profile) node;
- char name[NAME_SIZE];
- struct table_action_profile_params params;
- struct rte_table_action_profile *ap;
-};
-
-TAILQ_HEAD(table_action_profile_list, table_action_profile);
-
-int
-table_action_profile_init(void);
-
-struct table_action_profile *
-table_action_profile_find(const char *name);
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params);
-
-#endif /* _INCLUDE_ACTION_H_ */
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
deleted file mode 100644
index 935c9b39d5..0000000000
--- a/examples/ip_pipeline/cli.c
+++ /dev/null
@@ -1,6791 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-
-#include "cli.h"
-
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "parser.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-#ifndef CMD_MAX_TOKENS
-#define CMD_MAX_TOKENS 256
-#endif
-
-#define MSG_OUT_OF_MEMORY "Not enough memory.\n"
-#define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
-#define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
-#define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
-#define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
-#define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
-#define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
-#define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
-#define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
-#define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
-#define MSG_CMD_FAIL "Command \"%s\" failed.\n"
-
-static int
-is_comment(char *in)
-{
- if ((strlen(in) && index("!#%;", in[0])) ||
- (strncmp(in, "//", 2) == 0) ||
- (strncmp(in, "--", 2) == 0))
- return 1;
-
- return 0;
-}
-
-static const char cmd_mempool_help[] =
-"mempool <mempool_name>\n"
-" buffer <buffer_size>\n"
-" pool <pool_size>\n"
-" cache <cache_size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_mempool(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct mempool_params p;
- char *name;
- struct mempool *mempool;
-
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "buffer") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
- return;
- }
-
- if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
- return;
- }
-
- if (strcmp(tokens[4], "pool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
- return;
- }
-
- if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
- return;
- }
-
- if (strcmp(tokens[6], "cache") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
- return;
- }
-
- if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
- return;
- }
-
- if (strcmp(tokens[8], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- mempool = mempool_create(name, &p);
- if (mempool == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_link_help[] =
-"link <link_name>\n"
-" dev <device_name> | port <port_id>\n"
-" rxq <n_queues> <queue_size> <mempool_name>\n"
-" txq <n_queues> <queue_size>\n"
-" promiscuous on | off\n"
-" [rss <qid_0> ... <qid_n>]\n";
-
-static void
-cmd_link(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct link_params p;
- struct link_params_rss rss;
- struct link *link;
- char *name;
-
- memset(&p, 0, sizeof(p));
-
- if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- p.dev_name = tokens[3];
- else if (strcmp(tokens[2], "port") == 0) {
- p.dev_name = NULL;
-
- if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
- return;
- }
-
- if (strcmp(tokens[4], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
- if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- p.rx.mempool_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
-
- if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- if (strcmp(tokens[11], "promiscuous") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
- return;
- }
-
- if (strcmp(tokens[12], "on") == 0)
- p.promiscuous = 1;
- else if (strcmp(tokens[12], "off") == 0)
- p.promiscuous = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
- return;
- }
-
- /* RSS */
- p.rx.rss = NULL;
- if (n_tokens > 13) {
- uint32_t queue_id, i;
-
- if (strcmp(tokens[13], "rss") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
- return;
- }
-
- p.rx.rss = &rss;
-
- rss.n_queues = 0;
- for (i = 14; i < n_tokens; i++) {
- if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
-
- rss.queue_id[rss.n_queues] = queue_id;
- rss.n_queues++;
- }
- }
-
- link = link_create(name, &p);
- if (link == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-/* Print the link stats and info */
-static void
-print_link_info(struct link *link, char *out, size_t out_size)
-{
- struct rte_eth_stats stats;
- struct rte_ether_addr mac_addr;
- struct rte_eth_link eth_link;
- uint16_t mtu;
- int ret;
-
- memset(&stats, 0, sizeof(stats));
- rte_eth_stats_get(link->port_id, &stats);
-
- ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
- if (ret != 0) {
- snprintf(out, out_size, "\n%s: MAC address get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- ret = rte_eth_link_get(link->port_id, ð_link);
- if (ret < 0) {
- snprintf(out, out_size, "\n%s: link get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- rte_eth_dev_get_mtu(link->port_id, &mtu);
-
- snprintf(out, out_size,
- "\n"
- "%s: flags=<%s> mtu %u\n"
- "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
- "\tport# %u speed %s\n"
- "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
- "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tTX errors %" PRIu64"\n",
- link->name,
- eth_link.link_status == 0 ? "DOWN" : "UP",
- mtu,
- RTE_ETHER_ADDR_BYTES(&mac_addr),
- link->n_rxq,
- link->n_txq,
- link->port_id,
- rte_eth_link_speed_to_str(eth_link.link_speed),
- stats.ipackets,
- stats.ibytes,
- stats.ierrors,
- stats.imissed,
- stats.rx_nombuf,
- stats.opackets,
- stats.obytes,
- stats.oerrors);
-}
-
-/*
- * link show [<link_name>]
- */
-static void
-cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- struct link *link;
- char *link_name;
-
- if (n_tokens != 2 && n_tokens != 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (n_tokens == 2) {
- link = link_next(NULL);
-
- while (link != NULL) {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- print_link_info(link, out, out_size);
- link = link_next(link);
- }
- } else {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- link_name = tokens[2];
- link = link_find(link_name);
-
- if (link == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "Link does not exist");
- return;
- }
- print_link_info(link, out, out_size);
- }
-}
-
-static const char cmd_swq_help[] =
-"swq <swq_name>\n"
-" size <size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_swq(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct swq_params p;
- char *name;
- struct swq *swq;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "size");
- return;
- }
-
- if (strcmp(tokens[4], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- swq = swq_create(name, &p);
- if (swq == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_profile_help[] =
-"tmgr subport profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n";
-
-static void
-cmd_tmgr_subport_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_subport_profile_params subport_profile;
- int status, i;
-
- if (n_tokens != 19) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&subport_profile.tc_rate[i],
- tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- status = tmgr_subport_profile_add(&subport_profile);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_pipe_profile_help[] =
-"tmgr pipe profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n"
-" <tc_ov_weight>\n"
-" <wrr_weight0..3>\n";
-
-static void
-cmd_tmgr_pipe_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_pipe_params p;
- int status, i;
-
- if (n_tokens != 24) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&p.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&p.tc_rate[i], tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++)
- if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
- return;
- }
-
- status = tmgr_pipe_profile_add(&p);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_help[] =
-"tmgr <tmgr_name>\n"
-" rate <rate>\n"
-" spp <n_subports_per_port>\n"
-" pps <n_pipes_per_subport>\n"
-" fo <frame_overhead>\n"
-" mtu <mtu>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_tmgr(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct tmgr_port_params p;
- char *name;
- struct tmgr_port *tmgr_port;
-
- if (n_tokens != 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "rate") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
- return;
- }
-
- if (parser_read_uint64(&p.rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "rate");
- return;
- }
-
- if (strcmp(tokens[4], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[6], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
- return;
- }
-
- if (strcmp(tokens[8], "fo") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
- return;
- }
-
- if (parser_read_uint32(&p.frame_overhead, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
- return;
- }
-
- if (strcmp(tokens[10], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.mtu, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- if (strcmp(tokens[12], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- tmgr_port = tmgr_port_create(name, &p);
- if (tmgr_port == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_help[] =
-"tmgr <tmgr_name> subport <subport_id>\n"
-" profile <subport_profile_id>\n";
-
-static void
-cmd_tmgr_subport(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, subport_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
- return;
- }
-
- status = tmgr_subport_config(name, subport_id, subport_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tmgr_subport_pipe_help[] =
-"tmgr <tmgr_name> subport <subport_id> pipe\n"
-" from <pipe_id_first> to <pipe_id_last>\n"
-" profile <pipe_profile_id>\n";
-
-static void
-cmd_tmgr_subport_pipe(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (strcmp(tokens[4], "pipe") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
- return;
- }
-
- if (strcmp(tokens[5], "from") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
- return;
- }
-
- if (strcmp(tokens[7], "to") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
- return;
- }
-
- if (strcmp(tokens[9], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
- return;
- }
-
- status = tmgr_pipe_config(name, subport_id, pipe_id_first,
- pipe_id_last, pipe_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tap_help[] =
-"tap <tap_name>\n";
-
-static void
-cmd_tap(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *name;
- struct tap *tap;
-
- if (n_tokens != 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- tap = tap_create(name);
- if (tap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_cryptodev_help[] =
-"cryptodev <cryptodev_name>\n"
-" dev <device_name> | dev_id <device_id>\n"
-" queue <n_queues> <queue_size>\n"
-" max_sessions <n_sessions>";
-
-static void
-cmd_cryptodev(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct cryptodev_params params;
- char *name;
-
- memset(¶ms, 0, sizeof(params));
- if (n_tokens != 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- params.dev_name = tokens[3];
- else if (strcmp(tokens[2], "dev_id") == 0) {
- if (parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "dev_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cryptodev");
- return;
- }
-
- if (strcmp(tokens[4], "queue")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "queue");
- return;
- }
-
- if (parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "q");
- return;
- }
-
- if (parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (strcmp(tokens[7], "max_sessions")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "max_sessions");
- return;
- }
-
- if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (cryptodev_create(name, ¶ms) == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_port_in_action_profile_help[] =
-"port in action profile <profile_name>\n"
-" [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
-" [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
-
-static void
-cmd_port_in_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_action_profile_params p;
- struct port_in_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[2], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[3], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[4];
-
- t0 = 5;
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
- uint32_t size;
-
- if (n_tokens < t0 + 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "match") == 0)
- p.fltr.filter_on_match = 1;
- else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
- p.fltr.filter_on_match = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 6], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
- t0 += 10;
- } /* filter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- uint32_t i;
-
- if (n_tokens < t0 + 22) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "port in action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- for (i = 0; i < 16; i++)
- if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
- t0 += 22;
- } /* balance */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = port_in_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_table_action_profile_help[] =
-"table action profile <profile_name>\n"
-" ipv4 | ipv6\n"
-" offset <ip_offset>\n"
-" fwd\n"
-" [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
-" [meter srtcm | trtcm\n"
-" tc <n_tc>\n"
-" stats none | pkts | bytes | both]\n"
-" [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
-" [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
-" vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
-" [nat src | dst\n"
-" proto udp | tcp]\n"
-" [ttl drop | fwd\n"
-" stats none | pkts]\n"
-" [stats pkts | bytes | both]\n"
-" [time]\n"
-" [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
-" [tag]\n"
-" [decap]\n";
-
-static void
-cmd_table_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_action_profile_params p;
- struct table_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[2], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[3];
-
- if (strcmp(tokens[4], "ipv4") == 0)
- p.common.ip_version = 1;
- else if (strcmp(tokens[4], "ipv6") == 0)
- p.common.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[5], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
- return;
- }
-
- if (strcmp(tokens[7], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
-
- t0 = 8;
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- if (n_tokens < t0 + 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
- t0 += 7;
- } /* balance */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile meter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "srtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
- else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "srtcm or trtcm");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "tc") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
- return;
- }
-
- if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "none") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 5], "both") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
- t0 += 6;
- } /* meter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile tm");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_subports_per_port,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_pipes_per_subport,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_pipes_per_subport");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
- t0 += 5;
- } /* tm */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
- uint32_t n_extra_tokens = 0;
-
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "ether") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
- else if (strcmp(tokens[t0 + 1], "vlan") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
- else if (strcmp(tokens[t0 + 1], "qinq") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
- else if (strcmp(tokens[t0 + 1], "mpls") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
- else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
- else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
- if (n_tokens < t0 + 2 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap vxlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: offset");
- return;
- }
-
- if (parser_read_uint32(&p.encap.vxlan.data_offset,
- tokens[t0 + 2 + 1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ether_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
- p.encap.vxlan.ip_version = 1;
- else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
- p.encap.vxlan.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: vlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
- p.encap.vxlan.vlan = 1;
- else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
- p.encap.vxlan.vlan = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: on or off");
- return;
- }
-
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
- n_extra_tokens = 5;
- } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
- p.encap.encap_mask =
- 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
- t0 += 2 + n_extra_tokens;
- } /* encap */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile nat");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "src") == 0)
- p.nat.source_nat = 1;
- else if (strcmp(tokens[t0 + 1], "dst") == 0)
- p.nat.source_nat = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "src or dst");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "proto") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "tcp") == 0)
- p.nat.proto = 0x06;
- else if (strcmp(tokens[t0 + 3], "udp") == 0)
- p.nat.proto = 0x11;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "tcp or udp");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
- t0 += 4;
- } /* nat */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile ttl");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "drop") == 0)
- p.ttl.drop = 1;
- else if (strcmp(tokens[t0 + 1], "fwd") == 0)
- p.ttl.drop = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "drop or fwd");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "none") == 0)
- p.ttl.n_packets_enabled = 0;
- else if (strcmp(tokens[t0 + 3], "pkts") == 0)
- p.ttl.n_packets_enabled = 1;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
- t0 += 4;
- } /* ttl */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "pkts") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
- p.stats.n_packets_enabled = 0;
- p.stats.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 1], "both") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
- t0 += 2;
- } /* stats */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
- t0 += 1;
- } /* time */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
- struct cryptodev *cryptodev;
-
- if (n_tokens < t0 + 5 ||
- strcmp(tokens[t0 + 1], "dev") ||
- strcmp(tokens[t0 + 3], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile sym_crypto");
- return;
- }
-
- cryptodev = cryptodev_find(tokens[t0 + 2]);
- if (cryptodev == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.cryptodev_id = cryptodev->dev_id;
-
- if (parser_read_uint32(&p.sym_crypto.op_offset,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.mp_create = cryptodev->mp_create;
- p.sym_crypto.mp_init = cryptodev->mp_init;
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- t0 += 5;
- } /* sym_crypto */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
- t0 += 1;
- } /* tag */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "decap") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
- t0 += 1;
- } /* decap */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = table_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_help[] =
-"pipeline <pipeline_name>\n"
-" period <timer_period_ms>\n"
-" offset_port_id <offset_port_id>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_pipeline(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct pipeline_params p;
- char *name;
- struct pipeline *pipeline;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "period") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
- return;
- }
-
- if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
- return;
- }
-
- if (strcmp(tokens[4], "offset_port_id") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
- return;
- }
-
- if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
- return;
- }
-
- if (strcmp(tokens[6], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- pipeline = pipeline_create(name, &p);
- if (pipeline == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_help[] =
-"pipeline <pipeline_name> port in\n"
-" bsz <burst_size>\n"
-" link <link_name> rxq <queue_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
-" | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
-" | cryptodev <cryptodev_name> rxq <queue_id>\n"
-" [action <port_in_action_profile_name>]\n"
-" [disabled]\n";
-
-static void
-cmd_pipeline_port_in(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_params p;
- char *pipeline_name;
- uint32_t t0;
- int enabled, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- t0 = 6;
-
- if (strcmp(tokens[t0], "link") == 0) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in link");
- return;
- }
-
- p.type = PORT_IN_RXQ;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
- t0 += 4;
- } else if (strcmp(tokens[t0], "swq") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in swq");
- return;
- }
-
- p.type = PORT_IN_SWQ;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tmgr") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tmgr");
- return;
- }
-
- p.type = PORT_IN_TMGR;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tap") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tap");
- return;
- }
-
- p.type = PORT_IN_TAP;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.tap.mempool_name = tokens[t0 + 3];
-
- if (strcmp(tokens[t0 + 4], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "source") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in source");
- return;
- }
-
- p.type = PORT_IN_SOURCE;
-
- p.dev_name = NULL;
-
- if (strcmp(tokens[t0 + 1], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.source.mempool_name = tokens[t0 + 2];
-
- if (strcmp(tokens[t0 + 3], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.source.file_name = tokens[t0 + 4];
-
- if (strcmp(tokens[t0 + 5], "bpp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "bpp");
- return;
- }
-
- if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_bytes_per_pkt");
- return;
- }
-
- t0 += 7;
- } else if (strcmp(tokens[t0], "cryptodev") == 0) {
- if (n_tokens < t0 + 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in cryptodev");
- return;
- }
-
- p.type = PORT_IN_CRYPTODEV;
-
- p.dev_name = tokens[t0 + 1];
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "rxq");
- return;
- }
-
- p.cryptodev.arg_callback = NULL;
- p.cryptodev.f_callback = NULL;
-
- t0 += 4;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- enabled = 1;
- if ((n_tokens > t0) &&
- (strcmp(tokens[t0], "disabled") == 0)) {
- enabled = 0;
-
- t0 += 1;
- }
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_port_in_create(pipeline_name,
- &p, enabled);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_out_help[] =
-"pipeline <pipeline_name> port out\n"
-" bsz <burst_size>\n"
-" link <link_name> txq <txq_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name>\n"
-" | sink [file <file_name> pkts <max_n_pkts>]\n"
-" | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
-
-static void
-cmd_pipeline_port_out(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_out_params p;
- char *pipeline_name;
- int status;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- if (strcmp(tokens[6], "link") == 0) {
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out link");
- return;
- }
-
- p.type = PORT_OUT_TXQ;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else if (strcmp(tokens[6], "swq") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out swq");
- return;
- }
-
- p.type = PORT_OUT_SWQ;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tmgr") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tmgr");
- return;
- }
-
- p.type = PORT_OUT_TMGR;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tap") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tap");
- return;
- }
-
- p.type = PORT_OUT_TAP;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "sink") == 0) {
- if ((n_tokens != 7) && (n_tokens != 11)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out sink");
- return;
- }
-
- p.type = PORT_OUT_SINK;
-
- p.dev_name = NULL;
-
- if (n_tokens == 7) {
- p.sink.file_name = NULL;
- p.sink.max_n_pkts = 0;
- } else {
- if (strcmp(tokens[7], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.sink.file_name = tokens[8];
-
- if (strcmp(tokens[9], "pkts") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
- return;
- }
-
- if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
- return;
- }
- }
-
- } else if (strcmp(tokens[6], "cryptodev") == 0) {
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- p.type = PORT_OUT_CRYPTODEV;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
-
- if (strcmp(tokens[10], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_port_out_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_help[] =
-"pipeline <pipeline_name> table\n"
-" match\n"
-" acl\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | array\n"
-" offset <key_offset>\n"
-" size <n_keys>\n"
-" | hash\n"
-" ext | lru\n"
-" key <key_size>\n"
-" mask <key_mask>\n"
-" offset <key_offset>\n"
-" buckets <n_buckets>\n"
-" size <n_keys>\n"
-" | lpm\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | stub\n"
-" [action <table_action_profile_name>]\n";
-
-static void
-cmd_pipeline_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
- struct table_params p;
- char *pipeline_name;
- uint32_t t0;
- int status;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (strcmp(tokens[3], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- t0 = 4;
- if (strcmp(tokens[t0], "acl") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table acl");
- return;
- }
-
- p.match_type = TABLE_ACL;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.acl.ip_version = 1;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.acl.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.ip_header_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "ip_header_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "array") == 0) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table array");
- return;
- }
-
- p.match_type = TABLE_ARRAY;
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.key_offset,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.n_keys,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 5;
- } else if (strcmp(tokens[t0], "hash") == 0) {
- uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < t0 + 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table hash");
- return;
- }
-
- p.match_type = TABLE_HASH;
-
- if (strcmp(tokens[t0 + 1], "ext") == 0)
- p.match.hash.extendable_bucket = 1;
- else if (strcmp(tokens[t0 + 1], "lru") == 0)
- p.match.hash.extendable_bucket = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ext or lru");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- if ((parser_read_uint32(&p.match.hash.key_size,
- tokens[t0 + 3]) != 0) ||
- (p.match.hash.key_size == 0) ||
- (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- if ((parse_hex_string(tokens[t0 + 5],
- key_mask, &key_mask_size) != 0) ||
- (key_mask_size != p.match.hash.key_size)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
- p.match.hash.key_mask = key_mask;
-
- if (strcmp(tokens[t0 + 6], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.key_offset,
- tokens[t0 + 7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "buckets") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_buckets,
- tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
- return;
- }
-
- if (strcmp(tokens[t0 + 10], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_keys,
- tokens[t0 + 11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 12;
- } else if (strcmp(tokens[t0], "lpm") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table lpm");
- return;
- }
-
- p.match_type = TABLE_LPM;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.lpm.key_size = 4;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.lpm.key_size = 16;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.key_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "stub") == 0) {
- p.match_type = TABLE_STUB;
-
- t0 += 1;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- if (n_tokens > t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_table_help[] =
-"pipeline <pipeline_name> port in <port_id> table <table_id>\n";
-
-static void
-cmd_pipeline_port_in_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id, table_id;
- int status;
-
- if (n_tokens != 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- status = pipeline_port_in_connect_to_table(pipeline_name,
- port_id,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_stats_help[] =
-"pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_IN_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_in_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_in_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_in_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_port_in_enable_help[] =
-"pipeline <pipeline_name> port in <port_id> enable\n";
-
-static void
-cmd_pipeline_port_in_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = pipeline_port_in_enable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_disable_help[] =
-"pipeline <pipeline_name> port in <port_id> disable\n";
-
-static void
-cmd_pipeline_port_in_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = pipeline_port_in_disable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_out_stats_help[] =
-"pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_OUT_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_out_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_out_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_out_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_table_stats_help[] =
-"pipeline <pipeline_name> table <table_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_TABLE_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts in with lookup miss: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_table_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_table_stats stats;
- char *pipeline_name;
- uint32_t table_id;
- int clear, status;
-
- if ((n_tokens != 6) && (n_tokens != 7)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 7) {
- if (strcmp(tokens[6], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_table_stats_read(pipeline_name,
- table_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
- stats.stats.n_pkts_in,
- stats.stats.n_pkts_lookup_miss,
- stats.n_pkts_dropped_by_lkp_hit_ah,
- stats.n_pkts_dropped_lkp_hit,
- stats.n_pkts_dropped_by_lkp_miss_ah,
- stats.n_pkts_dropped_lkp_miss);
-}
-
-/**
- * <match> ::=
- *
- * match
- * acl
- * priority <priority>
- * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- * <sp0> <sp1> <dp0> <dp1> <proto>
- * | array <pos>
- * | hash
- * raw <key>
- * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv4_addr <addr>
- * | ipv6_addr <addr>
- * | qinq <svlan> <cvlan>
- * | lpm
- * ipv4 | ipv6 <addr> <depth>
- */
-struct pkt_key_qinq {
- uint16_t ethertype_svlan;
- uint16_t svlan;
- uint16_t ethertype_cvlan;
- uint16_t cvlan;
-};
-
-struct pkt_key_ipv4_5tuple {
- uint8_t time_to_live;
- uint8_t proto;
- uint16_t hdr_checksum;
- uint32_t sa;
- uint32_t da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv6_5tuple {
- uint16_t payload_length;
- uint8_t proto;
- uint8_t hop_limit;
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv4_addr {
- uint32_t addr;
-};
-
-struct pkt_key_ipv6_addr {
- struct rte_ipv6_addr addr;
-};
-
-static uint32_t
-parse_match(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_match *m)
-{
- memset(m, 0, sizeof(*m));
-
- if (n_tokens < 2)
- return 0;
-
- if (strcmp(tokens[0], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return 0;
- }
-
- if (strcmp(tokens[1], "acl") == 0) {
- if (n_tokens < 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ACL;
-
- if (strcmp(tokens[2], "priority") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.priority,
- tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "priority");
- return 0;
- }
-
- if (strcmp(tokens[4], "ipv4") == 0) {
- struct in_addr saddr, daddr;
-
- m->match.acl.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
-
- if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
- } else if (strcmp(tokens[4], "ipv6") == 0) {
- struct rte_ipv6_addr saddr, daddr;
-
- m->match.acl.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv6.sa = saddr;
-
- if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv6.da = daddr;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.sa_depth,
- tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.da_depth,
- tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "proto");
- return 0;
- }
-
- m->match.acl.proto_mask = 0xff;
-
- return 14;
- } /* acl */
-
- if (strcmp(tokens[1], "array") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ARRAY;
-
- if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pos");
- return 0;
- }
-
- return 3;
- } /* array */
-
- if (strcmp(tokens[1], "hash") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_HASH;
-
- if (strcmp(tokens[2], "raw") == 0) {
- uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_hex_string(tokens[3],
- m->match.hash.key, &key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key");
- return 0;
- }
-
- return 4;
- } /* hash raw */
-
- if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
- struct pkt_key_ipv4_5tuple *ipv4 =
- (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
- struct in_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv4->sa = saddr.s_addr;
- ipv4->da = daddr.s_addr;
- ipv4->sp = rte_cpu_to_be_16(sp);
- ipv4->dp = rte_cpu_to_be_16(dp);
- ipv4->proto = proto;
-
- return 8;
- } /* hash ipv4_5tuple */
-
- if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
- struct pkt_key_ipv6_5tuple *ipv6 =
- (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
- struct rte_ipv6_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv6->sa = saddr;
- ipv6->da = daddr;
- ipv6->sp = rte_cpu_to_be_16(sp);
- ipv6->dp = rte_cpu_to_be_16(dp);
- ipv6->proto = proto;
-
- return 8;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "ipv4_addr") == 0) {
- struct pkt_key_ipv4_addr *ipv4_addr =
- (struct pkt_key_ipv4_addr *) m->match.hash.key;
- struct in_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv4_addr->addr = addr.s_addr;
-
- return 4;
- } /* hash ipv4_addr */
-
- if (strcmp(tokens[2], "ipv6_addr") == 0) {
- struct pkt_key_ipv6_addr *ipv6_addr =
- (struct pkt_key_ipv6_addr *) m->match.hash.key;
- struct rte_ipv6_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv6_addr->addr = addr;
-
- return 4;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "qinq") == 0) {
- struct pkt_key_qinq *qinq =
- (struct pkt_key_qinq *) m->match.hash.key;
- uint16_t svlan, cvlan;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
- (svlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "svlan");
- return 0;
- }
-
- if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
- (cvlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cvlan");
- return 0;
- }
-
- qinq->svlan = rte_cpu_to_be_16(svlan);
- qinq->cvlan = rte_cpu_to_be_16(cvlan);
-
- return 5;
- } /* hash qinq */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- } /* hash */
-
- if (strcmp(tokens[1], "lpm") == 0) {
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_LPM;
-
- if (strcmp(tokens[2], "ipv4") == 0) {
- struct in_addr addr;
-
- m->match.lpm.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- } else if (strcmp(tokens[2], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
-
- m->match.lpm.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv6 = addr;
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "depth");
- return 0;
- }
-
- return 5;
- } /* lpm */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "acl or array or hash or lpm");
- return 0;
-}
-
-/**
- * table_action ::=
- *
- * action
- * fwd
- * drop
- * | port <port_id>
- * | meta
- * | table <table_id>
- * [balance <out0> ... <out7>]
- * [meter
- * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- * [tm subport <subport_id> pipe <pipe_id>]
- * [encap
- * ether <da> <sa>
- * | vlan <da> <sa> <pcp> <dei> <vid>
- * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
- * | mpls unicast | multicast
- * <da> <sa>
- * label0 <label> <tc> <ttl>
- * [label1 <label> <tc> <ttl>
- * [label2 <label> <tc> <ttl>
- * [label3 <label> <tc> <ttl>]]]
- * | pppoe <da> <sa> <session_id>
- * | vxlan ether <da> <sa>
- * [vlan <pcp> <dei> <vid>]
- * ipv4 <sa> <da> <dscp> <ttl>
- * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
- * udp <sp> <dp>
- * vxlan <vni>]
- * [nat ipv4 | ipv6 <addr> <port>]
- * [ttl dec | keep]
- * [stats]
- * [time]
- * [sym_crypto
- * encrypt | decrypt
- * type
- * | cipher
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * | cipher_auth
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * auth_algo <algo> auth_key <key> digest_size <size>
- * | aead
- * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- * digest_size <size>
- * data_offset <data_offset>]
- * [tag <tag>]
- * [decap <n>]
- *
- * where:
- * <pa> ::= g | y | r | drop
- */
-static uint32_t
-parse_table_action_fwd(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_DROP;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_PORT;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_balance(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t i;
-
- if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
- return 0;
-
- for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
- if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
- return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
-
-}
-
-static int
-parse_policer_action(char *token, enum rte_table_action_policer *a)
-{
- if (strcmp(token, "g") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
- return 0;
- }
-
- if (strcmp(token, "y") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
- return 0;
- }
-
- if (strcmp(token, "r") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
- return 0;
- }
-
- if (strcmp(token, "drop") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_DROP;
- return 0;
- }
-
- return -1;
-}
-
-static uint32_t
-parse_table_action_meter_tc(char **tokens,
- uint32_t n_tokens,
- struct rte_table_action_mtr_tc_params *mtr)
-{
- if ((n_tokens < 9) ||
- strcmp(tokens[0], "meter") ||
- parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
- strcmp(tokens[2], "policer") ||
- strcmp(tokens[3], "g") ||
- parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
- strcmp(tokens[5], "y") ||
- parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
- strcmp(tokens[7], "r") ||
- parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
- return 0;
-
- return 9;
-}
-
-static uint32_t
-parse_table_action_meter(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if ((n_tokens < 10) ||
- strcmp(tokens[0], "tc0") ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1,
- &a->mtr.mtr[0]) == 0))
- return 0;
-
- tokens += 10;
- n_tokens -= 10;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
- a->mtr.tc_mask = 1;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10;
- }
-
- if ((n_tokens < 30) ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
- strcmp(tokens[10], "tc2") ||
- (parse_table_action_meter_tc(tokens + 11,
- n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
- strcmp(tokens[20], "tc3") ||
- (parse_table_action_meter_tc(tokens + 21,
- n_tokens - 21, &a->mtr.mtr[3]) == 0))
- return 0;
-
- a->mtr.tc_mask = 0xF;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10 + 3 * 10;
-}
-
-static uint32_t
-parse_table_action_tm(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t subport_id, pipe_id;
-
- if ((n_tokens < 5) ||
- strcmp(tokens[0], "tm") ||
- strcmp(tokens[1], "subport") ||
- parser_read_uint32(&subport_id, tokens[2]) ||
- strcmp(tokens[3], "pipe") ||
- parser_read_uint32(&pipe_id, tokens[4]))
- return 0;
-
- a->tm.subport_id = subport_id;
- a->tm.pipe_id = pipe_id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
- return 5;
-}
-
-static uint32_t
-parse_table_action_encap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- /* ether */
- if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
- if ((n_tokens < 3) ||
- parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 3;
- }
-
- /* vlan */
- if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 6) ||
- parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
- parser_read_uint32(&pcp, tokens[3]) ||
- (pcp > 0x7) ||
- parser_read_uint32(&dei, tokens[4]) ||
- (dei > 0x1) ||
- parser_read_uint32(&vid, tokens[5]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vlan.vlan.pcp = pcp & 0x7;
- a->encap.vlan.vlan.dei = dei & 0x1;
- a->encap.vlan.vlan.vid = vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 6;
- }
-
- /* qinq */
- if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 9) ||
- parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF))
- return 0;
-
- a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 9;
- }
-
- /* qinq_pppoe */
- if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 10) ||
- parse_mac_addr(tokens[1],
- &a->encap.qinq_pppoe.ether.da) ||
- parse_mac_addr(tokens[2],
- &a->encap.qinq_pppoe.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF) ||
- parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
- tokens[9]))
- return 0;
-
- a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 10;
-
- }
-
- /* mpls */
- if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
- uint32_t label, tc, ttl;
-
- if (n_tokens < 8)
- return 0;
-
- if (strcmp(tokens[1], "unicast") == 0)
- a->encap.mpls.unicast = 1;
- else if (strcmp(tokens[1], "multicast") == 0)
- a->encap.mpls.unicast = 0;
- else
- return 0;
-
- if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
- parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
- strcmp(tokens[4], "label0") ||
- parser_read_uint32(&label, tokens[5]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[6]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[7]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[0].label = label;
- a->encap.mpls.mpls[0].tc = tc;
- a->encap.mpls.mpls[0].ttl = ttl;
-
- tokens += 8;
- n_tokens -= 8;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
- a->encap.mpls.mpls_count = 1;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[1].label = label;
- a->encap.mpls.mpls[1].tc = tc;
- a->encap.mpls.mpls[1].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
- a->encap.mpls.mpls_count = 2;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[2].label = label;
- a->encap.mpls.mpls[2].tc = tc;
- a->encap.mpls.mpls[2].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
- a->encap.mpls.mpls_count = 3;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[3].label = label;
- a->encap.mpls.mpls[3].tc = tc;
- a->encap.mpls.mpls[3].ttl = ttl;
-
- a->encap.mpls.mpls_count = 4;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4 + 4;
- }
-
- /* pppoe */
- if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
- if ((n_tokens < 4) ||
- parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
- parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
- tokens[3]))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 4;
- }
-
- /* vxlan */
- if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
- uint32_t n = 0;
-
- n_tokens--;
- tokens++;
- n++;
-
- /* ether <da> <sa> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "ether") ||
- parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* [vlan <pcp> <dei> <vid>] */
- if (strcmp(tokens[0], "vlan") == 0) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&pcp, tokens[1]) ||
- (pcp > 7) ||
- parser_read_uint32(&dei, tokens[2]) ||
- (dei > 1) ||
- parser_read_uint32(&vid, tokens[3]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vxlan.vlan.pcp = pcp;
- a->encap.vxlan.vlan.dei = dei;
- a->encap.vxlan.vlan.vid = vid;
-
- n_tokens -= 4;
- tokens += 4;
- n += 4;
- }
-
- /* ipv4 <sa> <da> <dscp> <ttl>
- | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
- if (strcmp(tokens[0], "ipv4") == 0) {
- struct in_addr sa, da;
- uint8_t dscp, ttl;
-
- if ((n_tokens < 5) ||
- parse_ipv4_addr(tokens[1], &sa) ||
- parse_ipv4_addr(tokens[2], &da) ||
- parser_read_uint8(&dscp, tokens[3]) ||
- (dscp > 64) ||
- parser_read_uint8(&ttl, tokens[4]))
- return 0;
-
- a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
- a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
- a->encap.vxlan.ipv4.dscp = dscp;
- a->encap.vxlan.ipv4.ttl = ttl;
-
- n_tokens -= 5;
- tokens += 5;
- n += 5;
- } else if (strcmp(tokens[0], "ipv6") == 0) {
- struct rte_ipv6_addr sa, da;
- uint32_t flow_label;
- uint8_t dscp, hop_limit;
-
- if ((n_tokens < 6) ||
- parse_ipv6_addr(tokens[1], &sa) ||
- parse_ipv6_addr(tokens[2], &da) ||
- parser_read_uint32(&flow_label, tokens[3]) ||
- parser_read_uint8(&dscp, tokens[4]) ||
- (dscp > 64) ||
- parser_read_uint8(&hop_limit, tokens[5]))
- return 0;
-
- a->encap.vxlan.ipv6.sa = sa;
- a->encap.vxlan.ipv6.da = da;
- a->encap.vxlan.ipv6.flow_label = flow_label;
- a->encap.vxlan.ipv6.dscp = dscp;
- a->encap.vxlan.ipv6.hop_limit = hop_limit;
-
- n_tokens -= 6;
- tokens += 6;
- n += 6;
- } else
- return 0;
-
- /* udp <sp> <dp> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "udp") ||
- parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
- parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* vxlan <vni> */
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "vxlan") ||
- parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
- (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
- return 0;
-
- n_tokens -= 2;
- tokens += 2;
- n += 2;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + n;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_nat(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 4) ||
- strcmp(tokens[0], "nat"))
- return 0;
-
- if (strcmp(tokens[1], "ipv4") == 0) {
- struct in_addr addr;
- uint16_t port;
-
- if (parse_ipv4_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 1;
- a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- if (strcmp(tokens[1], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
- uint16_t port;
-
- if (parse_ipv6_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 0;
- a->nat.addr.ipv6 = addr;
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_ttl(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "ttl"))
- return 0;
-
- if (strcmp(tokens[1], "dec") == 0)
- a->ttl.decrement = 1;
- else if (strcmp(tokens[1], "keep") == 0)
- a->ttl.decrement = 0;
- else
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
- return 2;
-}
-
-static uint32_t
-parse_table_action_stats(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "stats"))
- return 0;
-
- a->stats.n_packets = 0;
- a->stats.n_bytes = 0;
- a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
- return 1;
-}
-
-static uint32_t
-parse_table_action_time(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "time"))
- return 0;
-
- a->time.time = rte_rdtsc();
- a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
- return 1;
-}
-
-static void
-parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
-{
- struct rte_crypto_sym_xform *xform[2] = {NULL};
- uint32_t i;
-
- xform[0] = p->xform;
- if (xform[0])
- xform[1] = xform[0]->next;
-
- for (i = 0; i < 2; i++) {
- if (xform[i] == NULL)
- continue;
-
- switch (xform[i]->type) {
- case RTE_CRYPTO_SYM_XFORM_CIPHER:
- free(p->cipher_auth.cipher_iv.val);
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AUTH:
- if (p->cipher_auth.auth_iv.val)
- free(p->cipher_auth.cipher_iv.val);
- if (p->cipher_auth.auth_iv_update.val)
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AEAD:
- free(p->aead.iv.val);
- free(p->aead.aad.val);
- break;
- default:
- continue;
- }
- }
-
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- int status;
- size_t len;
-
- if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
- strcmp(tokens[3], "cipher_key") ||
- strcmp(tokens[5], "cipher_iv"))
- return NULL;
-
- xform_cipher = calloc(1, sizeof(*xform_cipher));
- if (xform_cipher == NULL)
- return NULL;
-
- xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
- xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- /* cipher_algo */
- status = rte_cryptodev_get_cipher_algo_enum(
- &xform_cipher->cipher.algo, tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* cipher_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.key.data = key;
- xform_cipher->cipher.key.length = (uint16_t)len;
-
- /* cipher_iv */
- len = strlen(tokens[6]);
-
- p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
- if (p->cipher_auth.cipher_iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6],
- p->cipher_auth.cipher_iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.iv.length = (uint16_t)len;
- xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->cipher_auth.cipher_iv.length = (uint32_t)len;
- *used_n_tokens = 7;
-
- return xform_cipher;
-
-error_exit:
- if (p->cipher_auth.cipher_iv.val) {
- free(p->cipher_auth.cipher_iv.val);
- p->cipher_auth.cipher_iv.val = NULL;
- }
-
- free(xform_cipher);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- struct rte_crypto_sym_xform *xform_auth;
- int status;
- size_t len;
-
- if (n_tokens < 13 ||
- strcmp(tokens[7], "auth_algo") ||
- strcmp(tokens[9], "auth_key") ||
- strcmp(tokens[11], "digest_size"))
- return NULL;
-
- xform_auth = calloc(1, sizeof(*xform_auth));
- if (xform_auth == NULL)
- return NULL;
-
- xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
- xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
- RTE_CRYPTO_AUTH_OP_VERIFY;
-
- /* auth_algo */
- status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
- tokens[8]);
- if (status < 0)
- goto error_exit;
-
- /* auth_key */
- len = strlen(tokens[10]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_auth->auth.key.data = key;
- xform_auth->auth.key.length = (uint16_t)len;
-
- key += xform_auth->auth.key.length;
- max_key_len -= xform_auth->auth.key.length;
-
- if (strcmp(tokens[11], "digest_size"))
- goto error_exit;
-
- status = parser_read_uint16(&xform_auth->auth.digest_length,
- tokens[12]);
- if (status < 0)
- goto error_exit;
-
- xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
- 7, encrypt, used_n_tokens);
- if (xform_cipher == NULL)
- goto error_exit;
-
- *used_n_tokens += 6;
-
- if (encrypt) {
- xform_cipher->next = xform_auth;
- return xform_cipher;
- } else {
- xform_auth->next = xform_cipher;
- return xform_auth;
- }
-
-error_exit:
- if (p->cipher_auth.auth_iv.val) {
- free(p->cipher_auth.auth_iv.val);
- p->cipher_auth.auth_iv.val = 0;
- }
-
- free(xform_auth);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_aead;
- int status;
- size_t len;
-
- if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
- strcmp(tokens[3], "aead_key") ||
- strcmp(tokens[5], "aead_iv") ||
- strcmp(tokens[7], "aead_aad") ||
- strcmp(tokens[9], "digest_size"))
- return NULL;
-
- xform_aead = calloc(1, sizeof(*xform_aead));
- if (xform_aead == NULL)
- return NULL;
-
- xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
- xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
- RTE_CRYPTO_AEAD_OP_DECRYPT;
-
- /* aead_algo */
- status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
- tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* aead_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.key.data = key;
- xform_aead->aead.key.length = (uint16_t)len;
-
- /* aead_iv */
- len = strlen(tokens[6]);
- p->aead.iv.val = calloc(1, len / 2 + 1);
- if (p->aead.iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6], p->aead.iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.iv.length = (uint16_t)len;
- xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->aead.iv.length = (uint32_t)len;
-
- /* aead_aad */
- len = strlen(tokens[8]);
- p->aead.aad.val = calloc(1, len / 2 + 1);
- if (p->aead.aad.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.aad_length = (uint16_t)len;
- p->aead.aad.length = (uint32_t)len;
-
- /* digest_size */
- status = parser_read_uint16(&xform_aead->aead.digest_length,
- tokens[10]);
- if (status < 0)
- goto error_exit;
-
- *used_n_tokens = 11;
-
- return xform_aead;
-
-error_exit:
- if (p->aead.iv.val) {
- free(p->aead.iv.val);
- p->aead.iv.val = NULL;
- }
- if (p->aead.aad.val) {
- free(p->aead.aad.val);
- p->aead.aad.val = NULL;
- }
-
- free(xform_aead);
-
- return NULL;
-}
-
-
-static uint32_t
-parse_table_action_sym_crypto(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
- struct rte_crypto_sym_xform *xform = NULL;
- uint8_t *key = a->sym_crypto_key;
- uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
- uint32_t used_n_tokens;
- uint32_t encrypt;
- int status;
-
- if ((n_tokens < 12) ||
- strcmp(tokens[0], "sym_crypto") ||
- strcmp(tokens[2], "type"))
- return 0;
-
- memset(p, 0, sizeof(*p));
-
- if (strcmp(tokens[1], "encrypt") == 0)
- encrypt = 1;
- else
- encrypt = 0;
-
- status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
- if (status < 0)
- return 0;
-
- if (strcmp(tokens[3], "cipher") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "cipher_auth") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher_auth(p, key, max_key_len,
- tokens, n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "aead") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_aead(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- }
-
- if (xform == NULL)
- return 0;
-
- p->xform = xform;
-
- if (strcmp(tokens[used_n_tokens], "data_offset")) {
- parse_free_sym_crypto_param_data(p);
- return 0;
- }
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- return used_n_tokens + 5;
-}
-
-static uint32_t
-parse_table_action_tag(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "tag"))
- return 0;
-
- if (parser_read_uint32(&a->tag.tag, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
- return 2;
-}
-
-static uint32_t
-parse_table_action_decap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "decap"))
- return 0;
-
- if (parser_read_uint16(&a->decap.n, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
- return 2;
-}
-
-static uint32_t
-parse_table_action(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_action *a)
-{
- uint32_t n_tokens0 = n_tokens;
-
- memset(a, 0, sizeof(*a));
-
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "action"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
- uint32_t n;
-
- n = parse_table_action_fwd(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action fwd");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
- uint32_t n;
-
- n = parse_table_action_balance(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action balance");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
- uint32_t n;
-
- n = parse_table_action_meter(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action meter");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tm(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tm");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_encap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action encap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
- uint32_t n;
-
- n = parse_table_action_nat(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action nat");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
- uint32_t n;
-
- n = parse_table_action_ttl(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action ttl");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
- uint32_t n;
-
- n = parse_table_action_stats(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action stats");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
- uint32_t n;
-
- n = parse_table_action_time(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action time");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
- uint32_t n;
-
- n = parse_table_action_sym_crypto(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action sym_crypto");
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tag(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tag");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_decap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action decap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens0 - n_tokens == 1) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return 0;
- }
-
- return n_tokens0 - n_tokens;
-}
-
-
-static const char cmd_pipeline_table_rule_add_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match <match>\n"
-" action <table_action>\n";
-
-static void
-cmd_pipeline_table_rule_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct table_rule_action a;
- char *pipeline_name;
- uint32_t table_id, t0, n_tokens_parsed;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- /* action */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &a);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (t0 != n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
- parse_free_sym_crypto_param_data(&a.sym_crypto);
-}
-
-
-static const char cmd_pipeline_table_rule_add_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match\n"
-" default\n"
-" action\n"
-" fwd\n"
-" drop\n"
-" | port <port_id>\n"
-" | meta\n"
-" | table <table_id>\n";
-
-static void
-cmd_pipeline_table_rule_add_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_action action;
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if ((n_tokens != 11) && (n_tokens != 12)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- if (strcmp(tokens[8], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return;
- }
-
- if (strcmp(tokens[9], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
- return;
- }
-
- action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
-
- if (strcmp(tokens[10], "drop") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_DROP;
- } else if (strcmp(tokens[10], "port") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT;
- action.fwd.id = id;
- } else if (strcmp(tokens[10], "meta") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- } else if (strcmp(tokens[10], "table") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
- action.fwd.id = id;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "drop or port or meta or table");
- return;
- }
-
- status = pipeline_table_rule_add_default(pipeline_name,
- table_id,
- &action);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_add_bulk_help[] =
-"pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - line format: match <match> action <action>\n";
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size);
-
-static void
-cmd_pipeline_table_rule_add_bulk(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *pipeline_name, *file_name;
- uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "bulk") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
- return;
- }
-
- file_name = tokens[7];
-
- /* Load rules from file. */
- status = cli_rule_file_process(file_name,
- 1024,
- &list,
- &n_rules,
- &line_number,
- out,
- out_size);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- /* Rule bulk add */
- status = pipeline_table_rule_add_bulk(pipeline_name,
- table_id,
- list,
- &n_rules_added,
- &n_rules_not_added);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, "Added %u rules out of %u.\n",
- n_rules_added,
- n_rules);
-}
-
-
-static const char cmd_pipeline_table_rule_delete_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed, t0;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_delete(pipeline_name,
- table_id,
- &m);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_delete_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match\n"
-" default\n";
-
-static void
-cmd_pipeline_table_rule_delete_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- status = pipeline_table_rule_delete_default(pipeline_name,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static void
-ether_addr_show(FILE *f, struct rte_ether_addr *addr)
-{
- fprintf(f, RTE_ETHER_ADDR_PRT_FMT, RTE_ETHER_ADDR_BYTES(addr));
-}
-
-static void
-ipv4_addr_show(FILE *f, uint32_t addr)
-{
- fprintf(f, "%u.%u.%u.%u",
- addr >> 24,
- (addr >> 16) & 0xFF,
- (addr >> 8) & 0xFF,
- addr & 0xFF);
-}
-
-static void
-ipv6_addr_show(FILE *f, const struct rte_ipv6_addr *ip)
-{
- fprintf(f, RTE_IPV6_ADDR_FMT ":", RTE_IPV6_ADDR_SPLIT(ip));
-}
-
-static const char *
-policer_action_string(enum rte_table_action_policer action) {
- switch (action) {
- case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
- case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
- case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
- case RTE_TABLE_ACTION_POLICER_DROP: return "D";
- default: return "?";
- }
-}
-
-static int
-table_rule_show(const char *pipeline_name,
- uint32_t table_id,
- const char *file_name)
-{
- struct pipeline *pipeline;
- struct table *table;
- struct table_rule *rule;
- FILE *f = NULL;
- uint32_t i;
-
- /* Check input params. */
- if ((pipeline_name == NULL) ||
- (file_name == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL || table_id >= pipeline->n_tables)
- return -1;
-
- table = &pipeline->table[table_id];
-
- /* Open file. */
- f = fopen(file_name, "w");
- if (f == NULL)
- return -1;
-
- /* Write table rules to file. */
- TAILQ_FOREACH(rule, &table->rules, node) {
- struct table_rule_match *m = &rule->match;
- struct table_rule_action *a = &rule->action;
-
- fprintf(f, "match ");
- switch (m->match_type) {
- case TABLE_ACL:
- fprintf(f, "acl priority %u ",
- m->match.acl.priority);
-
- fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.sa);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.sa);
-
- fprintf(f, "%u", m->match.acl.sa_depth);
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.da);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.da);
-
- fprintf(f, "%u", m->match.acl.da_depth);
-
- fprintf(f, "%u %u %u %u %u ",
- (uint32_t)m->match.acl.sp0,
- (uint32_t)m->match.acl.sp1,
- (uint32_t)m->match.acl.dp0,
- (uint32_t)m->match.acl.dp1,
- (uint32_t)m->match.acl.proto);
- break;
-
- case TABLE_ARRAY:
- fprintf(f, "array %u ",
- m->match.array.pos);
- break;
-
- case TABLE_HASH:
- fprintf(f, "hash raw ");
- for (i = 0; i < table->params.match.hash.key_size; i++)
- fprintf(f, "%02x", m->match.hash.key[i]);
- fprintf(f, " ");
- break;
-
- case TABLE_LPM:
- fprintf(f, "lpm ");
-
- fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.lpm.ipv4);
- else
- ipv6_addr_show(f, &m->match.lpm.ipv6);
-
- fprintf(f, "%u ",
- (uint32_t)m->match.lpm.depth);
- break;
-
- default:
- fprintf(f, "unknown ");
- }
-
- fprintf(f, "action ");
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- fprintf(f, "fwd ");
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- fprintf(f, "balance ");
- for (i = 0; i < RTE_DIM(a->lb.out); i++)
- fprintf(f, "%u ", a->lb.out[i]);
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- fprintf(f, "mtr ");
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
- if (a->mtr.tc_mask & (1 << i)) {
- struct rte_table_action_mtr_tc_params *p =
- &a->mtr.mtr[i];
- enum rte_table_action_policer ga =
- p->policer[RTE_COLOR_GREEN];
- enum rte_table_action_policer ya =
- p->policer[RTE_COLOR_YELLOW];
- enum rte_table_action_policer ra =
- p->policer[RTE_COLOR_RED];
-
- fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
- i,
- a->mtr.mtr[i].meter_profile_id,
- policer_action_string(ga),
- policer_action_string(ya),
- policer_action_string(ra));
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
- fprintf(f, "tm subport %u pipe %u ",
- a->tm.subport_id,
- a->tm.pipe_id);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- fprintf(f, "encap ");
- switch (a->encap.type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- fprintf(f, "ether ");
- ether_addr_show(f, &a->encap.ether.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.ether.ether.sa);
- fprintf(f, " ");
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- fprintf(f, "vlan ");
- ether_addr_show(f, &a->encap.vlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vlan.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u ",
- a->encap.vlan.vlan.pcp,
- a->encap.vlan.vlan.dei,
- a->encap.vlan.vlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- fprintf(f, "qinq ");
- ether_addr_show(f, &a->encap.qinq.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.qinq.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
- a->encap.qinq.svlan.pcp,
- a->encap.qinq.svlan.dei,
- a->encap.qinq.svlan.vid,
- a->encap.qinq.cvlan.pcp,
- a->encap.qinq.cvlan.dei,
- a->encap.qinq.cvlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
- "unicast " : "multicast ");
- ether_addr_show(f, &a->encap.mpls.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.mpls.ether.sa);
- fprintf(f, " ");
- for (i = 0; i < a->encap.mpls.mpls_count; i++) {
- struct rte_table_action_mpls_hdr *l =
- &a->encap.mpls.mpls[i];
-
- fprintf(f, "label%u %u %u %u ",
- i,
- l->label,
- l->tc,
- l->ttl);
- }
- break;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- fprintf(f, "pppoe ");
- ether_addr_show(f, &a->encap.pppoe.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.pppoe.ether.sa);
- fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- fprintf(f, "vxlan ether ");
- ether_addr_show(f, &a->encap.vxlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vxlan.ether.sa);
- if (table->ap->params.encap.vxlan.vlan)
- fprintf(f, " vlan pcp %u dei %u vid %u ",
- a->encap.vxlan.vlan.pcp,
- a->encap.vxlan.vlan.dei,
- a->encap.vxlan.vlan.vid);
- if (table->ap->params.encap.vxlan.ip_version) {
- fprintf(f, " ipv4 ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
- fprintf(f, " ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
- fprintf(f, " %u %u ",
- (uint32_t)a->encap.vxlan.ipv4.dscp,
- (uint32_t)a->encap.vxlan.ipv4.ttl);
- } else {
- fprintf(f, " ipv6 ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.sa);
- fprintf(f, " ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.da);
- fprintf(f, " %u %u %u ",
- a->encap.vxlan.ipv6.flow_label,
- (uint32_t)a->encap.vxlan.ipv6.dscp,
- (uint32_t)a->encap.vxlan.ipv6.hop_limit);
- fprintf(f, " udp %u %u vxlan %u ",
- a->encap.vxlan.udp.sp,
- a->encap.vxlan.udp.dp,
- a->encap.vxlan.vxlan.vni);
- }
- break;
-
- default:
- fprintf(f, "unknown ");
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
- if (a->nat.ip_version)
- ipv4_addr_show(f, a->nat.addr.ipv4);
- else
- ipv6_addr_show(f, &a->nat.addr.ipv6);
- fprintf(f, " %u ", (uint32_t)(a->nat.port));
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
- fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
- fprintf(f, "stats ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
- fprintf(f, "time ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
- fprintf(f, "sym_crypto ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
- fprintf(f, "tag %u ", a->tag.tag);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
- fprintf(f, "decap %u ", a->decap.n);
-
- /* end */
- fprintf(f, "\n");
- }
-
- /* Write table default rule to file. */
- if (table->rule_default) {
- struct table_rule_action *a = &table->rule_default->action;
-
- fprintf(f, "# match default action fwd ");
-
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- } else
- fprintf(f, "# match default action fwd drop ");
-
- fprintf(f, "\n");
-
- /* Close file. */
- fclose(f);
-
- return 0;
-}
-
-static const char cmd_pipeline_table_rule_show_help[] =
-"pipeline <pipeline_name> table <table_id> rule show\n"
-" file <file_name>\n";
-
-static void
-cmd_pipeline_table_rule_show(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *file_name = NULL, *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "show") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
- return;
- }
-
- if (strcmp(tokens[6], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
- return;
- }
-
- file_name = tokens[7];
-
- status = table_rule_show(pipeline_name, table_id, file_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_rule_stats_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_stats_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_stats_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule stats. */
- status = pipeline_table_rule_stats_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- if (stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
- stats.n_packets,
- stats.n_bytes);
-
- if (stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
- stats.n_packets);
-
- if (!stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
- stats.n_bytes);
-
- if (!stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
-}
-
-static const char cmd_pipeline_table_meter_profile_add_help[] =
-"pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
-" add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
-" | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
-
-static void
-cmd_pipeline_table_meter_profile_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_meter_profile p;
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens < 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[8], "srtcm") == 0) {
- if (n_tokens != 15) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_SRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[13], "ebs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
- return;
- }
- } else if (strcmp(tokens[8], "trtcm") == 0) {
- if (n_tokens != 17) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_TRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "pir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pir");
- return;
- }
- if (strcmp(tokens[13], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[15], "pbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_mtr_profile_add(pipeline_name,
- table_id,
- meter_profile_id,
- &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_meter_profile_delete_help[] =
-"pipeline <pipeline_name> table <table_id>\n"
-" meter profile <meter_profile_id> delete\n";
-
-static void
-cmd_pipeline_table_meter_profile_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- status = pipeline_table_mtr_profile_delete(pipeline_name,
- table_id,
- meter_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_meter_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_meter_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_mtr_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule meter stats. */
- status = pipeline_table_rule_mtr_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
-}
-
-
-static const char cmd_pipeline_table_dscp_help[] =
-"pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - exactly 64 lines\n"
-" - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
-
-static int
-load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
- const char *file_name,
- uint32_t *line_number)
-{
- FILE *f = NULL;
- uint32_t dscp, l;
-
- /* Check input arguments */
- if ((dscp_table == NULL) ||
- (file_name == NULL) ||
- (line_number == NULL)) {
- if (line_number)
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Read file */
- for (dscp = 0, l = 1; ; l++) {
- char line[64];
- char *tokens[3];
- enum rte_color color;
- uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
-
- if (fgets(line, sizeof(line), f) == NULL)
- break;
-
- if (is_comment(line))
- continue;
-
- if (parse_tokenize_string(line, tokens, &n_tokens)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- if (n_tokens == 0)
- continue;
-
- if ((dscp >= RTE_DIM(dscp_table->entry)) ||
- (n_tokens != RTE_DIM(tokens)) ||
- parser_read_uint32(&tc_id, tokens[0]) ||
- (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
- parser_read_uint32(&tc_queue_id, tokens[1]) ||
- (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
- (strlen(tokens[2]) != 1)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- switch (tokens[2][0]) {
- case 'g':
- case 'G':
- color = RTE_COLOR_GREEN;
- break;
-
- case 'y':
- case 'Y':
- color = RTE_COLOR_YELLOW;
- break;
-
- case 'r':
- case 'R':
- color = RTE_COLOR_RED;
- break;
-
- default:
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- dscp_table->entry[dscp].tc_id = tc_id;
- dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
- dscp_table->entry[dscp].color = color;
- dscp++;
- }
-
- /* Close file */
- fclose(f);
- return 0;
-}
-
-static void
-cmd_pipeline_table_dscp(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_dscp_table dscp_table;
- char *pipeline_name, *file_name;
- uint32_t table_id, line_number;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "dscp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
- return;
- }
-
- file_name = tokens[5];
-
- status = load_dscp_table(&dscp_table, file_name, &line_number);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- status = pipeline_table_dscp_table_update(pipeline_name,
- table_id,
- UINT64_MAX,
- &dscp_table);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_ttl_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_ttl_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_ttl_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "ttl") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule TTL stats. */
- status = pipeline_table_rule_ttl_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n",
- stats.n_packets);
-}
-
-static const char cmd_pipeline_table_rule_time_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read time\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_time_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint64_t timestamp;
- uint32_t table_id, n_tokens_parsed;
- int status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "time") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule timestamp. */
- status = pipeline_table_rule_time_read(pipeline_name,
- table_id,
- &m,
- ×tamp);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
-}
-
-static const char cmd_thread_pipeline_enable_help[] =
-"thread <thread_id> pipeline <pipeline_name> enable\n";
-
-static void
-cmd_thread_pipeline_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = thread_pipeline_enable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
- return;
- }
-}
-
-
-static const char cmd_thread_pipeline_disable_help[] =
-"thread <thread_id> pipeline <pipeline_name> disable\n";
-
-static void
-cmd_thread_pipeline_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = thread_pipeline_disable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL,
- "thread pipeline disable");
- return;
- }
-}
-
-static void
-cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- tokens++;
- n_tokens--;
-
- if (n_tokens == 0) {
- snprintf(out, out_size,
- "Type 'help <command>' for details on each command.\n\n"
- "List of commands:\n"
- "\tmempool\n"
- "\tlink\n"
- "\tswq\n"
- "\ttmgr subport profile\n"
- "\ttmgr pipe profile\n"
- "\ttmgr\n"
- "\ttmgr subport\n"
- "\ttmgr subport pipe\n"
- "\ttap\n"
- "\tport in action profile\n"
- "\ttable action profile\n"
- "\tpipeline\n"
- "\tpipeline port in\n"
- "\tpipeline port out\n"
- "\tpipeline table\n"
- "\tpipeline port in table\n"
- "\tpipeline port in stats\n"
- "\tpipeline port in enable\n"
- "\tpipeline port in disable\n"
- "\tpipeline port out stats\n"
- "\tpipeline table stats\n"
- "\tpipeline table rule add\n"
- "\tpipeline table rule add default\n"
- "\tpipeline table rule add bulk\n"
- "\tpipeline table rule delete\n"
- "\tpipeline table rule delete default\n"
- "\tpipeline table rule show\n"
- "\tpipeline table rule stats read\n"
- "\tpipeline table meter profile add\n"
- "\tpipeline table meter profile delete\n"
- "\tpipeline table rule meter read\n"
- "\tpipeline table dscp\n"
- "\tpipeline table rule ttl read\n"
- "\tpipeline table rule time read\n"
- "\tthread pipeline enable\n"
- "\tthread pipeline disable\n\n");
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_link_help);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_swq_help);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if (n_tokens == 1) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
- return;
- }
-
- if ((n_tokens == 2) &&
- (strcmp(tokens[1], "subport")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_tmgr_subport_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "pipe") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
- return;
- }
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tap_help);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[0], "port") == 0) &&
- (strcmp(tokens[1], "in") == 0) &&
- (strcmp(tokens[2], "action") == 0) &&
- (strcmp(tokens[3], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "table") == 0) &&
- (strcmp(tokens[1], "action") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "port") == 0)) {
- if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
- return;
- }
-
- if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "table") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_table_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_stats_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "enable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_enable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "disable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_disable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "out") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_out_stats_help);
- return;
- }
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "table") == 0)) {
- if (n_tokens == 2) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_stats_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_dscp_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_default_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "bulk") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_bulk_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_default_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "show") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_show_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "stats") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_stats_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "meter") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_meter_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "ttl") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_ttl_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "time") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_time_read_help);
- return;
- }
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "thread") == 0) &&
- (strcmp(tokens[1], "pipeline") == 0)) {
- if (strcmp(tokens[2], "enable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_enable_help);
- return;
- }
-
- if (strcmp(tokens[2], "disable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_disable_help);
- return;
- }
- }
-
- snprintf(out, out_size, "Invalid command\n");
-}
-
-void
-cli_process(char *in, char *out, size_t out_size)
-{
- char *tokens[CMD_MAX_TOKENS];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- if (is_comment(in))
- return;
-
- status = parse_tokenize_string(in, tokens, &n_tokens);
- if (status) {
- snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
- return;
- }
-
- if (n_tokens == 0)
- return;
-
- if (strcmp(tokens[0], "help") == 0) {
- cmd_help(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- cmd_mempool(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- if (strcmp(tokens[1], "show") == 0) {
- cmd_link_show(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_link(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- cmd_swq(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_subport_profile(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "profile") == 0)) {
- cmd_tmgr_subport(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "pipe") == 0)) {
- cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_tmgr(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- cmd_tap(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- cmd_cryptodev(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "port") == 0) {
- cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "table") == 0) {
- cmd_table_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "pipeline") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[2], "period") == 0)) {
- cmd_pipeline(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 4) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[3], "match") == 0)) {
- cmd_pipeline_table(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "table") == 0)) {
- cmd_pipeline_port_in_table(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_in_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "enable") == 0)) {
- cmd_pipeline_port_in_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "disable") == 0)) {
- cmd_pipeline_port_in_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_out_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "stats") == 0)) {
- cmd_pipeline_table_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_add_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "bulk") == 0)) {
- cmd_pipeline_table_rule_add_bulk(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "delete") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_delete_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_delete(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "show") == 0)) {
- cmd_pipeline_table_rule_show(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "stats") == 0)) {
- cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "add") == 0)) {
- cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "delete") == 0)) {
- cmd_pipeline_table_meter_profile_delete(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "meter") == 0)) {
- cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "dscp") == 0)) {
- cmd_pipeline_table_dscp(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "ttl") == 0)) {
- cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "time") == 0)) {
- cmd_pipeline_table_rule_time_read(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- if (strcmp(tokens[0], "thread") == 0) {
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "enable") == 0)) {
- cmd_thread_pipeline_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "disable") == 0)) {
- cmd_thread_pipeline_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
-}
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max)
-{
- char *msg_in = NULL, *msg_out = NULL;
- FILE *f = NULL;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (msg_in_len_max == 0) ||
- (msg_out_len_max == 0))
- return -EINVAL;
-
- msg_in = malloc(msg_in_len_max + 1);
- msg_out = malloc(msg_out_len_max + 1);
- if ((msg_in == NULL) ||
- (msg_out == NULL)) {
- free(msg_out);
- free(msg_in);
- return -ENOMEM;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- free(msg_out);
- free(msg_in);
- return -EIO;
- }
-
- /* Read file */
- for ( ; ; ) {
- if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
- break;
-
- printf("%s", msg_in);
- msg_out[0] = 0;
-
- cli_process(msg_in,
- msg_out,
- msg_out_len_max);
-
- if (strlen(msg_out))
- printf("%s", msg_out);
- }
-
- /* Close file */
- fclose(f);
- free(msg_out);
- free(msg_in);
- return 0;
-}
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *line = NULL;
- FILE *f = NULL;
- uint32_t rule_id = 0, line_id = 0;
- int status = 0;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (line_len_max == 0) ||
- (rule_list == NULL) ||
- (n_rules == NULL) ||
- (line_number == NULL) ||
- (out == NULL)) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Memory allocation */
- list = malloc(sizeof(struct table_rule_list));
- if (list == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INIT(list);
-
- line = malloc(line_len_max + 1);
- if (line == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- /* Open file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- status = -EIO;
- goto cli_rule_file_process_free;
- }
-
- /* Read file */
- for (line_id = 1, rule_id = 0; ; line_id++) {
- char *tokens[CMD_MAX_TOKENS];
- struct table_rule *rule = NULL;
- uint32_t n_tokens, n_tokens_parsed, t0;
-
- /* Read next line from file. */
- if (fgets(line, line_len_max + 1, f) == NULL)
- break;
-
- /* Comment. */
- if (is_comment(line))
- continue;
-
- /* Parse line. */
- n_tokens = RTE_DIM(tokens);
- status = parse_tokenize_string(line, tokens, &n_tokens);
- if (status) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Empty line. */
- if (n_tokens == 0)
- continue;
- t0 = 0;
-
- /* Rule alloc and insert. */
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INSERT_TAIL(list, rule, node);
-
- /* Rule match. */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->match);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Rule action. */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->action);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Line completed. */
- if (t0 < n_tokens) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Increment rule count */
- rule_id++;
- }
-
- /* Close file */
- fclose(f);
-
- /* Memory free */
- free(line);
-
- *rule_list = list;
- *n_rules = rule_id;
- *line_number = line_id;
- return 0;
-
-cli_rule_file_process_free:
- if (rule_list != NULL)
- *rule_list = NULL;
-
- if (n_rules != NULL)
- *n_rules = rule_id;
-
- if (line_number != NULL)
- *line_number = line_id;
-
- if (list != NULL)
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- }
-
- if (f)
- fclose(f);
- free(line);
- free(list);
-
- return status;
-}
diff --git a/examples/ip_pipeline/cli.h b/examples/ip_pipeline/cli.h
deleted file mode 100644
index 992e4c3a4a..0000000000
--- a/examples/ip_pipeline/cli.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CLI_H__
-#define __INCLUDE_CLI_H__
-
-#include <stddef.h>
-
-void
-cli_process(char *in, char *out, size_t out_size);
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max);
-
-#endif
diff --git a/examples/ip_pipeline/common.h b/examples/ip_pipeline/common.h
deleted file mode 100644
index 0886dfbe95..0000000000
--- a/examples/ip_pipeline/common.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_COMMON_H_
-#define _INCLUDE_COMMON_H_
-
-#ifndef NAME_SIZE
-#define NAME_SIZE 64
-#endif
-
-#endif /* _INCLUDE_COMMON_H_ */
diff --git a/examples/ip_pipeline/conn.c b/examples/ip_pipeline/conn.c
deleted file mode 100644
index b2406b7af1..0000000000
--- a/examples/ip_pipeline/conn.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <sys/socket.h>
-
-#include <sys/epoll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#include <rte_string_fns.h>
-
-#include "conn.h"
-
-#define MSG_CMD_TOO_LONG "Command too long."
-
-struct conn {
- char *welcome;
- char *prompt;
- char *buf;
- char *msg_in;
- char *msg_out;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- size_t msg_in_len;
- int fd_server;
- int fd_client_group;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p)
-{
- struct sockaddr_in server_address;
- struct conn *conn;
- int fd_server, fd_client_group, status;
-
- memset(&server_address, 0, sizeof(server_address));
-
- /* Check input arguments */
- if ((p == NULL) ||
- (p->welcome == NULL) ||
- (p->prompt == NULL) ||
- (p->addr == NULL) ||
- (p->buf_size == 0) ||
- (p->msg_in_len_max == 0) ||
- (p->msg_out_len_max == 0) ||
- (p->msg_handle == NULL))
- return NULL;
-
- status = inet_aton(p->addr, &server_address.sin_addr);
- if (status == 0)
- return NULL;
-
- /* Memory allocation */
- conn = calloc(1, sizeof(struct conn));
- if (conn == NULL)
- return NULL;
-
- conn->welcome = calloc(1, CONN_WELCOME_LEN_MAX + 1);
- conn->prompt = calloc(1, CONN_PROMPT_LEN_MAX + 1);
- conn->buf = calloc(1, p->buf_size);
- conn->msg_in = calloc(1, p->msg_in_len_max + 1);
- conn->msg_out = calloc(1, p->msg_out_len_max + 1);
-
- if ((conn->welcome == NULL) ||
- (conn->prompt == NULL) ||
- (conn->buf == NULL) ||
- (conn->msg_in == NULL) ||
- (conn->msg_out == NULL)) {
- conn_free(conn);
- return NULL;
- }
-
- /* Server socket */
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(p->port);
-
- fd_server = socket(AF_INET,
- SOCK_STREAM | SOCK_NONBLOCK,
- 0);
- if (fd_server == -1) {
- conn_free(conn);
- return NULL;
- }
-
- status = bind(fd_server,
- (struct sockaddr *) &server_address,
- sizeof(server_address));
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- status = listen(fd_server, 16);
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Client group */
- fd_client_group = epoll_create(1);
- if (fd_client_group == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Fill in */
- strlcpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX + 1);
- strlcpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX + 1);
- conn->buf_size = p->buf_size;
- conn->msg_in_len_max = p->msg_in_len_max;
- conn->msg_out_len_max = p->msg_out_len_max;
- conn->msg_in_len = 0;
- conn->fd_server = fd_server;
- conn->fd_client_group = fd_client_group;
- conn->msg_handle = p->msg_handle;
-
- return conn;
-}
-
-void
-conn_free(struct conn *conn)
-{
- if (conn == NULL)
- return;
-
- if (conn->fd_client_group)
- close(conn->fd_client_group);
-
- if (conn->fd_server)
- close(conn->fd_server);
-
- free(conn->msg_out);
- free(conn->msg_in);
- free(conn->prompt);
- free(conn->welcome);
- free(conn);
-}
-
-int
-conn_poll_for_conn(struct conn *conn)
-{
- struct sockaddr_in client_address;
- struct epoll_event event;
- socklen_t client_address_length;
- int fd_client, status;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Server socket */
- client_address_length = sizeof(client_address);
- fd_client = accept4(conn->fd_server,
- (struct sockaddr *) &client_address,
- &client_address_length,
- SOCK_NONBLOCK);
- if (fd_client == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
-
- /* Client group */
- event.events = EPOLLIN | EPOLLRDHUP | EPOLLHUP;
- event.data.fd = fd_client;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_ADD,
- fd_client,
- &event);
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- /* Client */
- status = write(fd_client,
- conn->welcome,
- strlen(conn->welcome));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- return 0;
-}
-
-static int
-data_event_handle(struct conn *conn,
- int fd_client)
-{
- ssize_t len, i, status;
-
- /* Read input message */
-
- len = read(fd_client,
- conn->buf,
- conn->buf_size);
- if (len == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
- if (len == 0)
- return 0;
-
- /* Handle input messages */
- for (i = 0; i < len; i++) {
- if (conn->buf[i] == '\n') {
- size_t n;
-
- conn->msg_in[conn->msg_in_len] = 0;
- conn->msg_out[0] = 0;
-
- conn->msg_handle(conn->msg_in,
- conn->msg_out,
- conn->msg_out_len_max);
-
- n = strlen(conn->msg_out);
- if (n) {
- status = write(fd_client,
- conn->msg_out,
- n);
- if (status == -1)
- return status;
- }
-
- conn->msg_in_len = 0;
- } else if (conn->msg_in_len < conn->msg_in_len_max) {
- conn->msg_in[conn->msg_in_len] = conn->buf[i];
- conn->msg_in_len++;
- } else {
- status = write(fd_client,
- MSG_CMD_TOO_LONG,
- strlen(MSG_CMD_TOO_LONG));
- if (status == -1)
- return status;
-
- conn->msg_in_len = 0;
- }
- }
-
- /* Write prompt */
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1)
- return status;
-
- return 0;
-}
-
-static int
-control_event_handle(struct conn *conn,
- int fd_client)
-{
- int status;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_DEL,
- fd_client,
- NULL);
- if (status == -1)
- return -1;
-
- status = close(fd_client);
- if (status == -1)
- return -1;
-
- return 0;
-}
-
-int
-conn_poll_for_msg(struct conn *conn)
-{
- struct epoll_event event;
- int fd_client, status, status_data = 0, status_control = 0;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Client group */
- status = epoll_wait(conn->fd_client_group,
- &event,
- 1,
- 0);
- if (status == -1)
- return -1;
- if (status == 0)
- return 0;
-
- fd_client = event.data.fd;
-
- /* Data available */
- if (event.events & EPOLLIN)
- status_data = data_event_handle(conn, fd_client);
-
- /* Control events */
- if (event.events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP))
- status_control = control_event_handle(conn, fd_client);
-
- if (status_data || status_control)
- return -1;
-
- return 0;
-}
diff --git a/examples/ip_pipeline/conn.h b/examples/ip_pipeline/conn.h
deleted file mode 100644
index 46f9f95e9c..0000000000
--- a/examples/ip_pipeline/conn.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CONN_H__
-#define __INCLUDE_CONN_H__
-
-#include <stdint.h>
-
-struct conn;
-
-#ifndef CONN_WELCOME_LEN_MAX
-#define CONN_WELCOME_LEN_MAX 1024
-#endif
-
-#ifndef CONN_PROMPT_LEN_MAX
-#define CONN_PROMPT_LEN_MAX 16
-#endif
-
-typedef void (*conn_msg_handle_t)(char *msg_in,
- char *msg_out,
- size_t msg_out_len_max);
-
-struct conn_params {
- const char *welcome;
- const char *prompt;
- const char *addr;
- uint16_t port;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p);
-
-void
-conn_free(struct conn *conn);
-
-int
-conn_poll_for_conn(struct conn *conn);
-
-int
-conn_poll_for_msg(struct conn *conn);
-
-#endif
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
deleted file mode 100644
index cd0f9c3d4e..0000000000
--- a/examples/ip_pipeline/cryptodev.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <rte_cryptodev.h>
-#include <rte_string_fns.h>
-
-#include "cryptodev.h"
-
-#define PIPELINE_CRYPTO_SESSION_CACHE_SIZE 128
-
-static struct cryptodev_list cryptodev_list;
-
-int
-cryptodev_init(void)
-{
- TAILQ_INIT(&cryptodev_list);
-
- return 0;
-}
-
-struct cryptodev *
-cryptodev_find(const char *name)
-{
- struct cryptodev *cryptodev;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(cryptodev, &cryptodev_list, node)
- if (strcmp(cryptodev->name, name) == 0)
- return cryptodev;
-
- return NULL;
-}
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev)
-{
- return (cryptodev == NULL) ?
- TAILQ_FIRST(&cryptodev_list) :
- TAILQ_NEXT(cryptodev, node);
-}
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params)
-{
- struct rte_cryptodev_info dev_info;
- struct rte_cryptodev_config dev_conf;
- struct rte_cryptodev_qp_conf queue_conf;
- struct cryptodev *cryptodev;
- uint32_t dev_id, i;
- uint32_t socket_id;
- uint32_t cache_size;
- char mp_name[NAME_SIZE];
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- cryptodev_find(name) ||
- (params->n_queues == 0) ||
- (params->queue_size == 0) ||
- (params->session_pool_size == 0))
- return NULL;
-
- if (params->dev_name) {
- status = rte_cryptodev_get_dev_id(params->dev_name);
- if (status == -1)
- return NULL;
-
- dev_id = (uint32_t)status;
- } else {
- if (rte_cryptodev_is_valid_dev(params->dev_id) == 0)
- return NULL;
-
- dev_id = params->dev_id;
- }
-
- cache_size = (params->session_pool_size / 2 <
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE) ?
- (params->session_pool_size / 2) :
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE;
-
- socket_id = rte_cryptodev_socket_id(dev_id);
- rte_cryptodev_info_get(dev_id, &dev_info);
-
- if (dev_info.max_nb_queue_pairs < params->n_queues)
- return NULL;
-
- dev_conf.socket_id = socket_id;
- dev_conf.nb_queue_pairs = params->n_queues;
- dev_conf.ff_disable = 0;
-
- status = rte_cryptodev_configure(dev_id, &dev_conf);
- if (status < 0)
- return NULL;
-
- queue_conf.nb_descriptors = params->queue_size;
- for (i = 0; i < params->n_queues; i++) {
- status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id);
- if (status < 0)
- return NULL;
- }
-
- if (rte_cryptodev_start(dev_id) < 0)
- return NULL;
-
- cryptodev = calloc(1, sizeof(struct cryptodev));
- if (cryptodev == NULL) {
- rte_cryptodev_stop(dev_id);
- return NULL;
- }
-
- strlcpy(cryptodev->name, name, sizeof(cryptodev->name));
- cryptodev->dev_id = dev_id;
- cryptodev->n_queues = params->n_queues;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id);
- cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(
- mp_name,
- params->session_pool_size,
- 0,
- cache_size,
- 0,
- socket_id);
- if (!cryptodev->mp_create)
- goto error_exit;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp_priv%u", name, dev_id);
- cryptodev->mp_init = rte_mempool_create(
- NULL,
- params->session_pool_size,
- rte_cryptodev_sym_get_private_session_size(dev_id),
- cache_size,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- socket_id,
- 0);
- if (!cryptodev->mp_init)
- goto error_exit;
-
- TAILQ_INSERT_TAIL(&cryptodev_list, cryptodev, node);
-
- return cryptodev;
-
-error_exit:
- rte_mempool_free(cryptodev->mp_create);
- rte_mempool_free(cryptodev->mp_init);
-
- free(cryptodev);
-
- return NULL;
-}
diff --git a/examples/ip_pipeline/cryptodev.h b/examples/ip_pipeline/cryptodev.h
deleted file mode 100644
index d00434379e..0000000000
--- a/examples/ip_pipeline/cryptodev.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SYM_C_H_
-#define _INCLUDE_SYM_C_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_cryptodev.h>
-
-#include "common.h"
-
-struct cryptodev {
- TAILQ_ENTRY(cryptodev) node;
- char name[NAME_SIZE];
- uint16_t dev_id;
- uint32_t n_queues;
- struct rte_mempool *mp_create;
- struct rte_mempool *mp_init;
-};
-
-TAILQ_HEAD(cryptodev_list, cryptodev);
-
-int
-cryptodev_init(void);
-
-struct cryptodev *
-cryptodev_find(const char *name);
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev);
-
-struct cryptodev_params {
- const char *dev_name;
- uint32_t dev_id; /**< Valid only when *dev_name* is NULL. */
- uint32_t n_queues;
- uint32_t queue_size;
- uint32_t session_pool_size;
-};
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params);
-
-#endif
diff --git a/examples/ip_pipeline/examples/firewall.cli b/examples/ip_pipeline/examples/firewall.cli
deleted file mode 100644
index 269256c161..0000000000
--- a/examples/ip_pipeline/examples/firewall.cli
+++ /dev/null
@@ -1,59 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Firewall |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; -+-
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match acl ipv4 offset 270 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd drop
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow.cli b/examples/ip_pipeline/examples/flow.cli
deleted file mode 100644
index 426ff90255..0000000000
--- a/examples/ip_pipeline/examples/flow.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Flow |
-; LINK2 RXQ0 --->| Classification |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 16 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF offset 278 buckets 16K size 65K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.10 200.0.0.10 100 200 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.11 200.0.0.11 101 201 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.12 200.0.0.12 102 202 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.13 200.0.0.13 103 203 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow_crypto.cli b/examples/ip_pipeline/examples/flow_crypto.cli
deleted file mode 100644
index 849f9d5fec..0000000000
--- a/examples/ip_pipeline/examples/flow_crypto.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> CRYPTO0 TXQ0
-; | Flow |
-; CRYPTO0 RXQ0-->| Classification |---> LINK0 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 280 20
-; 4 Packet 256 1536
-; 5 Crypto Operation 1792 160
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 1
-
-link LINK0 dev 81:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-#Cryptodev
-cryptodev CRYPTO0 dev crypto_aesni_gcm0 queue 1 1024 max_sessions 512
-
-table action profile AP0 ipv4 offset 270 fwd sym_crypto dev CRYPTO0 offset 1792
-table action profile AP1 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 1
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 cryptodev CRYPTO0 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 cryptodev CRYPTO0 txq 0 offset 1792
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 8 mask FFFFFFFF00000000 offset 282 buckets 1K size 4K action AP0
-pipeline PIPELINE0 table match stub action AP1
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-
-thread 2 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 2
-
-#AES-GCM encrypt
-pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto encrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-#AES-GCM decrypt
-#pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto decrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
diff --git a/examples/ip_pipeline/examples/l2fwd.cli b/examples/ip_pipeline/examples/l2fwd.cli
deleted file mode 100644
index 35e77cc968..0000000000
--- a/examples/ip_pipeline/examples/l2fwd.cli
+++ /dev/null
@@ -1,51 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; The pipeline below implements a simple pass-through connection between the
-; input ports to the output ports, as in this diagram:
-; ________________
-; LINK0 RXQ0 --->|................|---> LINK1 TXQ0
-; | |
-; LINK1 RXQ0 --->|................|---> LINK0 TXQ0
-; | PIPELINE0 |
-; LINK2 RXQ0 --->|................|---> LINK3 TXQ0
-; | |
-; LINK3 RXQ0 --->|................|---> LINK2 TXQ0
-; |________________|
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 1
-pipeline PIPELINE0 table 1 rule add match default action fwd port 0
-pipeline PIPELINE0 table 2 rule add match default action fwd port 3
-pipeline PIPELINE0 table 3 rule add match default action fwd port 2
diff --git a/examples/ip_pipeline/examples/route.cli b/examples/ip_pipeline/examples/route.cli
deleted file mode 100644
index 579b36a659..0000000000
--- a/examples/ip_pipeline/examples/route.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Routing |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; +-----------> SINK0 (route miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/route_ecmp.cli b/examples/ip_pipeline/examples/route_ecmp.cli
deleted file mode 100644
index 06434a2560..0000000000
--- a/examples/ip_pipeline/examples/route_ecmp.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; Equal Cost Multi-Path (ECMP) Routing
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile APRT ipv4 offset 270 fwd balance offset 278 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF outoffset 256
-table action profile APNH ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action APRT
-pipeline PIPELINE0 table match array offset 256 size 64K action APNH
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd table 1 balance 0 0 0 0 1 1 2 2
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd table 1 balance 1 1 1 1 2 2 3 3
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd table 1 balance 2 2 2 2 3 3 0 0
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd table 1 balance 3 3 3 3 0 0 1 1
-
-pipeline PIPELINE0 table 1 rule add match array 0 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 1 rule add match array 1 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 1 rule add match array 2 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 1 rule add match array 3 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/rss.cli b/examples/ip_pipeline/examples/rss.cli
deleted file mode 100644
index 29c0a91392..0000000000
--- a/examples/ip_pipeline/examples/rss.cli
+++ /dev/null
@@ -1,112 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; This setup demonstrates the usage of NIC Receive Side Scaling (RSS) feature.
-; Each NIC splits the input traffic into 4 RX queues, with each of its RX queues
-; being handled by a different pipeline:
-;
-; +-----------+ +----------+
-; +--------------------------->| | | |
-; | +------------------->| PIPELINE0 +--->| LINK 0 |--->
-; | | +------------->| (CORE A) | | TX |
-; | | | +------->| | | |
-; | | | | +-----------+ +----------+
-; +----------+ | | | |
-; | |-------+ | | |
-;--->| LINK 0 |-----------+ | | |
-; | RX |---------+ | | | |
-; | |-------+ | | | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | | +---|-----|-----|------->| | | |
-; +----------+ | | | +---|-----|------->| PIPELINE1 +--->| LINK 1 |--->
-; | |-------|-|-----+ | | +---|------->| (CORE B) | | TX |
-;--->| LINK 1 |-------|-|-------+ | | | +----->| | | |
-; | RX |-------|-|-------+ | | | | +-----------+ +----------+
-; | |-------|-|-----+ | | | | |
-; +----------+ | | | | | | | |
-; | | | | | | | |
-; +----------+ | | | | | | | |
-; | |-------|-|-----|-|---+ | | |
-;--->| LINK 2 |-------|-|-----|-|-----+ | | +-----------+ +----------+
-; | RX |-----+ | +-----|-|---------|-|----->| | | |
-; | |---+ | | | +---------|-|----->| PIPELINE2 +--->| LINK 2 |--->
-; +----------+ | +-|-------|-----------|-|----->| (CORE C) | | TX |
-; | | | | | +--->| | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | |---|---|-------|-----------+ | |
-;--->| LINK 3 |---|---|-------|-------------+ |
-; | RX |---|---|-------|---------------+
-; | |---|---|-------|-----------+
-; +----------+ | | | |
-; | | | | +-----------+ +----------+
-; | +-------|-----------|------->| | | |
-; | +-----------|------->| PIPELINE3 +--->| LINK 3 |--->
-; +-----------------------|------->| (CORE D) | | TX |
-; +------->| | | |
-; +-----------+ +----------+
-;
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK1 dev 0000:02:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK2 dev 0000:06:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK3 dev 0000:06:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE1 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE1 port in bsz 32 link LINK0 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK1 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK2 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK3 rxq 1
-pipeline PIPELINE1 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE1 table match stub
-pipeline PIPELINE1 port in 0 table 0
-pipeline PIPELINE1 port in 1 table 0
-pipeline PIPELINE1 port in 2 table 0
-pipeline PIPELINE1 port in 3 table 0
-pipeline PIPELINE1 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE2 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE2 port in bsz 32 link LINK0 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK1 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK2 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK3 rxq 2
-pipeline PIPELINE2 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE2 table match stub
-pipeline PIPELINE2 port in 0 table 0
-pipeline PIPELINE2 port in 1 table 0
-pipeline PIPELINE2 port in 2 table 0
-pipeline PIPELINE2 port in 3 table 0
-pipeline PIPELINE2 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE3 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE3 port in bsz 32 link LINK0 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK1 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK2 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK3 rxq 3
-pipeline PIPELINE3 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE3 table match stub
-pipeline PIPELINE3 port in 0 table 0
-pipeline PIPELINE3 port in 1 table 0
-pipeline PIPELINE3 port in 2 table 0
-pipeline PIPELINE3 port in 3 table 0
-pipeline PIPELINE3 table 0 rule add match default action fwd port 0
-
-thread 1 pipeline PIPELINE0 enable
-thread 2 pipeline PIPELINE1 enable
-thread 3 pipeline PIPELINE2 enable
-thread 4 pipeline PIPELINE3 enable
diff --git a/examples/ip_pipeline/examples/tap.cli b/examples/ip_pipeline/examples/tap.cli
deleted file mode 100644
index 600cea2643..0000000000
--- a/examples/ip_pipeline/examples/tap.cli
+++ /dev/null
@@ -1,66 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________ ______________________
-; | | TAP0 | |
-; LINK0 RXQ0 --->|...............|------->|--+ |
-; | | TAP1 | | br0 |
-; LINK1 TXQ0 <---|...............|<-------|<-+ |
-; | | | Linux Kernel |
-; | PIPELINE0 | | Network Stack |
-; | | TAP1 | |
-; LINK1 RXQ0 --->|...............|------->|--+ |
-; | | TAP0 | | br0 |
-; LINK0 TXQ0 <---|...............|<-------|<-+ |
-; |_______________| |______________________|
-;
-; Configure Linux kernel bridge between TAP0 and TAP1 interfaces:
-; [Linux]$ brctl addbr br0
-; [Linux]$ brctl addif br0 TAP0
-; [Linux]$ brctl addif br0 TAP1
-; [Linux]$ ifconfig TAP0 up
-; [Linux]$ ifconfig TAP1 up
-; [Linux]$ ifconfig br0 up
-;
-; Monitor packet forwarding performed by Linux kernel between TAP0 and TAP1:
-; [Linux]$ tcpdump -i TAP0
-; [Linux]$ tcpdump -i TAP1
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-tap TAP0
-tap TAP1
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP1 mempool MEMPOOL0 mtu 1500
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP0 mempool MEMPOOL0 mtu 1500
-
-pipeline PIPELINE0 port out bsz 32 tap TAP0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 tap TAP1
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
-pipeline PIPELINE0 table 2 rule add match default action fwd port 2
-pipeline PIPELINE0 table 3 rule add match default action fwd port 3
diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
deleted file mode 100644
index 4d69ebebfb..0000000000
--- a/examples/ip_pipeline/link.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_ethdev.h>
-#include <rte_string_fns.h>
-
-#include "link.h"
-#include "mempool.h"
-
-static struct link_list link_list;
-
-int
-link_init(void)
-{
- TAILQ_INIT(&link_list);
-
- return 0;
-}
-
-struct link *
-link_find(const char *name)
-{
- struct link *link;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(link, &link_list, node)
- if (strcmp(link->name, name) == 0)
- return link;
-
- return NULL;
-}
-
-struct link *
-link_next(struct link *link)
-{
- return (link == NULL) ? TAILQ_FIRST(&link_list) : TAILQ_NEXT(link, node);
-}
-
-static struct rte_eth_conf port_conf_default = {
- .link_speeds = 0,
- .rxmode = {
- .mq_mode = RTE_ETH_MQ_RX_NONE,
- .mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_key_len = 40,
- .rss_hf = 0,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
- .lpbk_mode = 0,
-};
-
-#define RETA_CONF_SIZE (RTE_ETH_RSS_RETA_SIZE_512 / RTE_ETH_RETA_GROUP_SIZE)
-
-static int
-rss_setup(uint16_t port_id,
- uint16_t reta_size,
- struct link_params_rss *rss)
-{
- struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
- uint32_t i;
- int status;
-
- /* RETA setting */
- memset(reta_conf, 0, sizeof(reta_conf));
-
- for (i = 0; i < reta_size; i++)
- reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX;
-
- for (i = 0; i < reta_size; i++) {
- uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE;
- uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE;
- uint32_t rss_qs_pos = i % rss->n_queues;
-
- reta_conf[reta_id].reta[reta_pos] =
- (uint16_t) rss->queue_id[rss_qs_pos];
- }
-
- /* RETA update */
- status = rte_eth_dev_rss_reta_update(port_id,
- reta_conf,
- reta_size);
-
- return status;
-}
-
-struct link *
-link_create(const char *name, struct link_params *params)
-{
- struct rte_eth_dev_info port_info;
- struct rte_eth_conf port_conf;
- struct link *link;
- struct link_params_rss *rss;
- struct mempool *mempool;
- uint32_t cpu_id, i;
- int status;
- uint16_t port_id;
-
- /* Check input params */
- if ((name == NULL) ||
- link_find(name) ||
- (params == NULL) ||
- (params->rx.n_queues == 0) ||
- (params->rx.queue_size == 0) ||
- (params->tx.n_queues == 0) ||
- (params->tx.queue_size == 0))
- return NULL;
-
- port_id = params->port_id;
- if (params->dev_name) {
- status = rte_eth_dev_get_port_by_name(params->dev_name,
- &port_id);
-
- if (status)
- return NULL;
- } else
- if (!rte_eth_dev_is_valid_port(port_id))
- return NULL;
-
- if (rte_eth_dev_info_get(port_id, &port_info) != 0)
- return NULL;
-
- mempool = mempool_find(params->rx.mempool_name);
- if (mempool == NULL)
- return NULL;
-
- rss = params->rx.rss;
- if (rss) {
- if ((port_info.reta_size == 0) ||
- (port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512))
- return NULL;
-
- if ((rss->n_queues == 0) ||
- (rss->n_queues >= LINK_RXQ_RSS_MAX))
- return NULL;
-
- for (i = 0; i < rss->n_queues; i++)
- if (rss->queue_id[i] >= port_info.max_rx_queues)
- return NULL;
- }
-
- /**
- * Resource create
- */
- /* Port */
- memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
- if (rss) {
- port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
- port_conf.rx_adv_conf.rss_conf.rss_hf =
- (RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP) &
- port_info.flow_type_rss_offloads;
- }
-
- cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
- if (cpu_id == (uint32_t) SOCKET_ID_ANY)
- cpu_id = 0;
-
- status = rte_eth_dev_configure(
- port_id,
- params->rx.n_queues,
- params->tx.n_queues,
- &port_conf);
-
- if (status < 0)
- return NULL;
-
- if (params->promiscuous) {
- status = rte_eth_promiscuous_enable(port_id);
- if (status != 0)
- return NULL;
- }
-
- /* Port RX */
- for (i = 0; i < params->rx.n_queues; i++) {
- status = rte_eth_rx_queue_setup(
- port_id,
- i,
- params->rx.queue_size,
- cpu_id,
- NULL,
- mempool->m);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port TX */
- for (i = 0; i < params->tx.n_queues; i++) {
- status = rte_eth_tx_queue_setup(
- port_id,
- i,
- params->tx.queue_size,
- cpu_id,
- NULL);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port start */
- status = rte_eth_dev_start(port_id);
- if (status < 0)
- return NULL;
-
- if (rss) {
- status = rss_setup(port_id, port_info.reta_size, rss);
-
- if (status) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
- }
-
- /* Port link up */
- status = rte_eth_dev_set_link_up(port_id);
- if ((status < 0) && (status != -ENOTSUP)) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node allocation */
- link = calloc(1, sizeof(struct link));
- if (link == NULL) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(link->name, name, sizeof(link->name));
- link->port_id = port_id;
- link->n_rxq = params->rx.n_queues;
- link->n_txq = params->tx.n_queues;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&link_list, link, node);
-
- return link;
-}
-
-int
-link_is_up(const char *name)
-{
- struct rte_eth_link link_params;
- struct link *link;
-
- /* Check input params */
- if (name == NULL)
- return 0;
-
- link = link_find(name);
- if (link == NULL)
- return 0;
-
- /* Resource */
- if (rte_eth_link_get(link->port_id, &link_params) < 0)
- return 0;
-
- return (link_params.link_status == RTE_ETH_LINK_DOWN) ? 0 : 1;
-}
diff --git a/examples/ip_pipeline/link.h b/examples/ip_pipeline/link.h
deleted file mode 100644
index 34ff1149e0..0000000000
--- a/examples/ip_pipeline/link.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_LINK_H_
-#define _INCLUDE_LINK_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include "common.h"
-
-#ifndef LINK_RXQ_RSS_MAX
-#define LINK_RXQ_RSS_MAX 16
-#endif
-
-struct link {
- TAILQ_ENTRY(link) node;
- char name[NAME_SIZE];
- uint16_t port_id;
- uint32_t n_rxq;
- uint32_t n_txq;
-};
-
-TAILQ_HEAD(link_list, link);
-
-int
-link_init(void);
-
-struct link *
-link_find(const char *name);
-
-struct link *
-link_next(struct link *link);
-
-struct link_params_rss {
- uint32_t queue_id[LINK_RXQ_RSS_MAX];
- uint32_t n_queues;
-};
-
-struct link_params {
- const char *dev_name;
- uint16_t port_id; /**< Valid only when *dev_name* is NULL. */
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- const char *mempool_name;
- struct link_params_rss *rss;
- } rx;
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- } tx;
-
- int promiscuous;
-};
-
-struct link *
-link_create(const char *name, struct link_params *params);
-
-int
-link_is_up(const char *name);
-
-#endif /* _INCLUDE_LINK_H_ */
diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c
deleted file mode 100644
index 663f538f02..0000000000
--- a/examples/ip_pipeline/main.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include <rte_launch.h>
-#include <rte_eal.h>
-
-#include "cli.h"
-#include "conn.h"
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-static const char usage[] =
- "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n";
-
-static const char welcome[] =
- "\n"
- "Welcome to IP Pipeline!\n"
- "\n";
-
-static const char prompt[] = "pipeline> ";
-
-static struct app_params {
- struct conn_params conn;
- char *script_name;
-} app = {
- .conn = {
- .welcome = welcome,
- .prompt = prompt,
- .addr = "0.0.0.0",
- .port = 8086,
- .buf_size = 1024 * 1024,
- .msg_in_len_max = 1024,
- .msg_out_len_max = 1024 * 1024,
- .msg_handle = cli_process,
- },
- .script_name = NULL,
-};
-
-static int
-parse_args(int argc, char **argv)
-{
- char *app_name = argv[0];
- struct option lgopts[] = {
- { NULL, 0, 0, 0 }
- };
- int opt, option_index;
- int h_present, p_present, s_present, n_args, i;
-
- /* Skip EAL input args */
- n_args = argc;
- for (i = 0; i < n_args; i++)
- if (strcmp(argv[i], "--") == 0) {
- argc -= i;
- argv += i;
- break;
- }
-
- if (i == n_args)
- return 0;
-
- /* Parse args */
- h_present = 0;
- p_present = 0;
- s_present = 0;
-
- while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index))
- != EOF)
- switch (opt) {
- case 'h':
- if (h_present) {
- printf("Error: Multiple -h arguments\n");
- return -1;
- }
- h_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -h not provided\n");
- return -1;
- }
-
- app.conn.addr = strdup(optarg);
- if (app.conn.addr == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- case 'p':
- if (p_present) {
- printf("Error: Multiple -p arguments\n");
- return -1;
- }
- p_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -p not provided\n");
- return -1;
- }
-
- app.conn.port = (uint16_t) atoi(optarg);
- break;
-
- case 's':
- if (s_present) {
- printf("Error: Multiple -s arguments\n");
- return -1;
- }
- s_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -s not provided\n");
- return -1;
- }
-
- app.script_name = strdup(optarg);
- if (app.script_name == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- default:
- printf(usage, app_name);
- return -1;
- }
-
- optind = 1; /* reset getopt lib */
-
- return 0;
-}
-
-int
-main(int argc, char **argv)
-{
- struct conn *conn;
- int status;
-
- /* Parse application arguments */
- status = parse_args(argc, argv);
- if (status < 0)
- return status;
-
- /* EAL */
- status = rte_eal_init(argc, argv);
- if (status < 0) {
- printf("Error: EAL initialization failed (%d)\n", status);
- return status;
- };
-
- /* Connectivity */
- conn = conn_init(&app.conn);
- if (conn == NULL) {
- printf("Error: Connectivity initialization failed (%d)\n",
- status);
- return status;
- };
-
- /* Mempool */
- status = mempool_init();
- if (status) {
- printf("Error: Mempool initialization failed (%d)\n", status);
- return status;
- }
-
- /* Link */
- status = link_init();
- if (status) {
- printf("Error: Link initialization failed (%d)\n", status);
- return status;
- }
-
- /* SWQ */
- status = swq_init();
- if (status) {
- printf("Error: SWQ initialization failed (%d)\n", status);
- return status;
- }
-
- /* Traffic Manager */
- status = tmgr_init();
- if (status) {
- printf("Error: TMGR initialization failed (%d)\n", status);
- return status;
- }
-
- /* TAP */
- status = tap_init();
- if (status) {
- printf("Error: TAP initialization failed (%d)\n", status);
- return status;
- }
-
- /* Sym Crypto */
- status = cryptodev_init();
- if (status) {
- printf("Error: Cryptodev initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Action */
- status = port_in_action_profile_init();
- if (status) {
- printf("Error: Input port action profile initialization failed (%d)\n", status);
- return status;
- }
-
- status = table_action_profile_init();
- if (status) {
- printf("Error: Action profile initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Pipeline */
- status = pipeline_init();
- if (status) {
- printf("Error: Pipeline initialization failed (%d)\n", status);
- return status;
- }
-
- /* Thread */
- status = thread_init();
- if (status) {
- printf("Error: Thread initialization failed (%d)\n", status);
- return status;
- }
-
- rte_eal_mp_remote_launch(
- thread_main,
- NULL,
- SKIP_MAIN);
-
- /* Script */
- if (app.script_name)
- cli_script_process(app.script_name,
- app.conn.msg_in_len_max,
- app.conn.msg_out_len_max);
-
- /* Dispatch loop */
- for ( ; ; ) {
- conn_poll_for_conn(conn);
-
- conn_poll_for_msg(conn);
- }
-}
diff --git a/examples/ip_pipeline/mempool.c b/examples/ip_pipeline/mempool.c
deleted file mode 100644
index f5d2a7d108..0000000000
--- a/examples/ip_pipeline/mempool.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-
-#include "mempool.h"
-
-#define BUFFER_SIZE_MIN (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-
-static struct mempool_list mempool_list;
-
-int
-mempool_init(void)
-{
- TAILQ_INIT(&mempool_list);
-
- return 0;
-}
-
-struct mempool *
-mempool_find(const char *name)
-{
- struct mempool *mempool;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(mempool, &mempool_list, node)
- if (strcmp(mempool->name, name) == 0)
- return mempool;
-
- return NULL;
-}
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params)
-{
- struct mempool *mempool;
- struct rte_mempool *m;
-
- /* Check input params */
- if ((name == NULL) ||
- mempool_find(name) ||
- (params == NULL) ||
- (params->buffer_size < BUFFER_SIZE_MIN) ||
- (params->pool_size == 0))
- return NULL;
-
- /* Resource create */
- m = rte_pktmbuf_pool_create(
- name,
- params->pool_size,
- params->cache_size,
- 0,
- params->buffer_size - sizeof(struct rte_mbuf),
- params->cpu_id);
-
- if (m == NULL)
- return NULL;
-
- /* Node allocation */
- mempool = calloc(1, sizeof(struct mempool));
- if (mempool == NULL) {
- rte_mempool_free(m);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(mempool->name, name, sizeof(mempool->name));
- mempool->m = m;
- mempool->buffer_size = params->buffer_size;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&mempool_list, mempool, node);
-
- return mempool;
-}
diff --git a/examples/ip_pipeline/mempool.h b/examples/ip_pipeline/mempool.h
deleted file mode 100644
index bd46a11ca0..0000000000
--- a/examples/ip_pipeline/mempool.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_MEMPOOL_H_
-#define _INCLUDE_MEMPOOL_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_mempool.h>
-
-#include "common.h"
-
-struct mempool {
- TAILQ_ENTRY(mempool) node;
- char name[NAME_SIZE];
- struct rte_mempool *m;
- uint32_t buffer_size;
-};
-
-TAILQ_HEAD(mempool_list, mempool);
-
-int
-mempool_init(void);
-
-struct mempool *
-mempool_find(const char *name);
-
-struct mempool_params {
- uint32_t buffer_size;
- uint32_t pool_size;
- uint32_t cache_size;
- uint32_t cpu_id;
-};
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params);
-
-#endif /* _INCLUDE_MEMPOOL_H_ */
diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build
deleted file mode 100644
index 68049157e4..0000000000
--- a/examples/ip_pipeline/meson.build
+++ /dev/null
@@ -1,30 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017-2018 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'
-
-build = cc.has_header('sys/epoll.h')
-if not build
- subdir_done()
-endif
-
-deps += ['pipeline', 'bus_pci']
-allow_experimental_apis = true
-sources = files(
- 'action.c',
- 'cli.c',
- 'conn.c',
- 'cryptodev.c',
- 'link.c',
- 'main.c',
- 'mempool.c',
- 'parser.c',
- 'pipeline.c',
- 'swq.c',
- 'tap.c',
- 'thread.c',
- 'tmgr.c',
-)
diff --git a/examples/ip_pipeline/parser.c b/examples/ip_pipeline/parser.c
deleted file mode 100644
index 8baa70e1f4..0000000000
--- a/examples/ip_pipeline/parser.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation.
- * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
- * All rights reserved.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <libgen.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include <rte_errno.h>
-#include <rte_string_fns.h>
-
-#include "parser.h"
-
-static uint32_t
-get_hex_val(char c)
-{
- switch (c) {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- return c - '0';
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- return c - 'A' + 10;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- return c - 'a' + 10;
- default:
- return 0;
- }
-}
-
-int
-parser_read_arg_bool(const char *p)
-{
- p = rte_str_skip_leading_spaces(p);
- int result = -EINVAL;
-
- if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
- ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
- p += 3;
- result = 1;
- }
-
- if (((p[0] == 'o') && (p[1] == 'n')) ||
- ((p[0] == 'O') && (p[1] == 'N'))) {
- p += 2;
- result = 1;
- }
-
- if (((p[0] == 'n') && (p[1] == 'o')) ||
- ((p[0] == 'N') && (p[1] == 'O'))) {
- p += 2;
- result = 0;
- }
-
- if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
- ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
- p += 3;
- result = 0;
- }
-
- p = rte_str_skip_leading_spaces(p);
-
- if (p[0] != '\0')
- return -EINVAL;
-
- return result;
-}
-
-int
-parser_read_uint64(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
- if (!isdigit(*p))
- return -EINVAL;
-
- val = strtoul(p, &next, 10);
- if (p == next)
- return -EINVAL;
-
- p = next;
- switch (*p) {
- case 'T':
- val *= 1024ULL;
- /* fall through */
- case 'G':
- val *= 1024ULL;
- /* fall through */
- case 'M':
- val *= 1024ULL;
- /* fall through */
- case 'k':
- case 'K':
- val *= 1024ULL;
- p++;
- break;
- }
-
- p = rte_str_skip_leading_spaces(p);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint64_hex(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
-
- val = strtoul(p, &next, 16);
- if (p == next)
- return -EINVAL;
-
- p = rte_str_skip_leading_spaces(next);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32_hex(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16_hex(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8_hex(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
-{
- uint32_t i;
-
- if ((string == NULL) ||
- (tokens == NULL) ||
- (*n_tokens < 1))
- return -EINVAL;
-
- for (i = 0; i < *n_tokens; i++) {
- tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
- if (tokens[i] == NULL)
- break;
- }
-
- if ((i == *n_tokens) &&
- (NULL != strtok_r(string, PARSE_DELIMITER, &string)))
- return -E2BIG;
-
- *n_tokens = i;
- return 0;
-}
-
-int
-parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
-{
- char *c;
- uint32_t len, i;
-
- /* Check input parameters */
- if ((src == NULL) ||
- (dst == NULL) ||
- (size == NULL) ||
- (*size == 0))
- return -1;
-
- len = strlen(src);
- if (((len & 3) != 0) ||
- (len > (*size) * 2))
- return -1;
- *size = len / 2;
-
- for (c = src; *c != 0; c++) {
- if ((((*c) >= '0') && ((*c) <= '9')) ||
- (((*c) >= 'A') && ((*c) <= 'F')) ||
- (((*c) >= 'a') && ((*c) <= 'f')))
- continue;
-
- return -1;
- }
-
- /* Convert chars to bytes */
- for (i = 0; i < *size; i++)
- dst[i] = get_hex_val(src[2 * i]) * 16 +
- get_hex_val(src[2 * i + 1]);
-
- return 0;
-}
-
-int
-parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels)
-{
- uint32_t n_max_labels = *n_labels, count = 0;
-
- /* Check for void list of labels */
- if (strcmp(string, "<void>") == 0) {
- *n_labels = 0;
- return 0;
- }
-
- /* At least one label should be present */
- for ( ; (*string != '\0'); ) {
- char *next;
- int value;
-
- if (count >= n_max_labels)
- return -1;
-
- if (count > 0) {
- if (string[0] != ':')
- return -1;
-
- string++;
- }
-
- value = strtol(string, &next, 10);
- if (next == string)
- return -1;
- string = next;
-
- labels[count++] = (uint32_t) value;
- }
-
- *n_labels = count;
- return 0;
-}
-
-static struct rte_ether_addr *
-my_ether_aton(const char *a)
-{
- int i;
- char *end;
- unsigned long o[RTE_ETHER_ADDR_LEN];
- static struct rte_ether_addr ether_addr;
-
- i = 0;
- do {
- errno = 0;
- o[i] = strtoul(a, &end, 16);
- if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
- return NULL;
- a = end + 1;
- } while (++i != RTE_DIM(o) && end[0] != 0);
-
- /* Junk at the end of line */
- if (end[0] != 0)
- return NULL;
-
- /* Support the format XX:XX:XX:XX:XX:XX */
- if (i == RTE_ETHER_ADDR_LEN) {
- while (i-- != 0) {
- if (o[i] > UINT8_MAX)
- return NULL;
- ether_addr.addr_bytes[i] = (uint8_t)o[i];
- }
- /* Support the format XXXX:XXXX:XXXX */
- } else if (i == RTE_ETHER_ADDR_LEN / 2) {
- while (i-- != 0) {
- if (o[i] > UINT16_MAX)
- return NULL;
- ether_addr.addr_bytes[i * 2] = (uint8_t)(o[i] >> 8);
- ether_addr.addr_bytes[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
- }
- /* unknown format */
- } else
- return NULL;
-
- return (struct rte_ether_addr *)ðer_addr;
-}
-
-int
-parse_ipv4_addr(const char *token, struct in_addr *ipv4)
-{
- if (strlen(token) >= INET_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET, token, ipv4) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6)
-{
- if (strlen(token) >= INET6_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET6, token, ipv6) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_mac_addr(const char *token, struct rte_ether_addr *addr)
-{
- struct rte_ether_addr *tmp;
-
- tmp = my_ether_aton(token);
- if (tmp == NULL)
- return -1;
-
- *addr = *tmp;
- return 0;
-}
-
-int
-parse_cpu_core(const char *entry,
- struct cpu_core_params *p)
-{
- size_t num_len;
- char num[8];
-
- uint32_t s = 0, c = 0, h = 0, val;
- uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
- const char *next = rte_str_skip_leading_spaces(entry);
- char type;
-
- if (p == NULL)
- return -EINVAL;
-
- /* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
- while (*next != '\0') {
- /* If everything parsed nothing should left */
- if (s_parsed && c_parsed && h_parsed)
- return -EINVAL;
-
- type = *next;
- switch (type) {
- case 's':
- case 'S':
- if (s_parsed || c_parsed || h_parsed)
- return -EINVAL;
- s_parsed = 1;
- next++;
- break;
- case 'c':
- case 'C':
- if (c_parsed || h_parsed)
- return -EINVAL;
- c_parsed = 1;
- next++;
- break;
- case 'h':
- case 'H':
- if (h_parsed)
- return -EINVAL;
- h_parsed = 1;
- next++;
- break;
- default:
- /* If it start from digit it must be only core id. */
- if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
- return -EINVAL;
-
- type = 'C';
- }
-
- for (num_len = 0; *next != '\0'; next++, num_len++) {
- if (num_len == RTE_DIM(num))
- return -EINVAL;
-
- if (!isdigit(*next))
- break;
-
- num[num_len] = *next;
- }
-
- if (num_len == 0 && type != 'h' && type != 'H')
- return -EINVAL;
-
- if (num_len != 0 && (type == 'h' || type == 'H'))
- return -EINVAL;
-
- num[num_len] = '\0';
- val = strtol(num, NULL, 10);
-
- h = 0;
- switch (type) {
- case 's':
- case 'S':
- s = val;
- break;
- case 'c':
- case 'C':
- c = val;
- break;
- case 'h':
- case 'H':
- h = 1;
- break;
- }
- }
-
- p->socket_id = s;
- p->core_id = c;
- p->thread_id = h;
- return 0;
-}
diff --git a/examples/ip_pipeline/parser.h b/examples/ip_pipeline/parser.h
deleted file mode 100644
index c8f0187d71..0000000000
--- a/examples/ip_pipeline/parser.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_PARSER_H__
-#define __INCLUDE_PARSER_H__
-
-#include <ctype.h>
-#include <stdint.h>
-
-#include <rte_ip.h>
-#include <rte_ether.h>
-
-#define PARSE_DELIMITER " \f\n\r\t\v"
-
-static inline size_t
-skip_digits(const char *src)
-{
- size_t i;
-
- for (i = 0; isdigit(src[i]); i++)
- ;
-
- return i;
-}
-
-int parser_read_arg_bool(const char *p);
-
-int parser_read_uint64(uint64_t *value, const char *p);
-int parser_read_uint32(uint32_t *value, const char *p);
-int parser_read_uint16(uint16_t *value, const char *p);
-int parser_read_uint8(uint8_t *value, const char *p);
-
-int parser_read_uint64_hex(uint64_t *value, const char *p);
-int parser_read_uint32_hex(uint32_t *value, const char *p);
-int parser_read_uint16_hex(uint16_t *value, const char *p);
-int parser_read_uint8_hex(uint8_t *value, const char *p);
-
-int parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
-
-int parse_ipv4_addr(const char *token, struct in_addr *ipv4);
-int parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6);
-int parse_mac_addr(const char *token, struct rte_ether_addr *addr);
-int parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels);
-
-struct cpu_core_params {
- uint32_t socket_id;
- uint32_t core_id;
- uint32_t thread_id;
-};
-
-int parse_cpu_core(const char *entry, struct cpu_core_params *p);
-
-int parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens);
-
-#endif
diff --git a/examples/ip_pipeline/pipeline.c b/examples/ip_pipeline/pipeline.c
deleted file mode 100644
index 792aab0059..0000000000
--- a/examples/ip_pipeline/pipeline.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-
-#include <rte_string_fns.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_ring.h>
-#include <rte_port_source_sink.h>
-#include <rte_port_fd.h>
-#include <rte_port_sched.h>
-#include <rte_port_sym_crypto.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_func.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_stub.h>
-
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "tap.h"
-#include "tmgr.h"
-#include "swq.h"
-#include "cryptodev.h"
-
-#ifndef PIPELINE_MSGQ_SIZE
-#define PIPELINE_MSGQ_SIZE 64
-#endif
-
-#ifndef TABLE_LPM_NUMBER_TBL8
-#define TABLE_LPM_NUMBER_TBL8 256
-#endif
-
-static struct pipeline_list pipeline_list;
-
-int
-pipeline_init(void)
-{
- TAILQ_INIT(&pipeline_list);
-
- return 0;
-}
-
-struct pipeline *
-pipeline_find(const char *name)
-{
- struct pipeline *pipeline;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(pipeline, &pipeline_list, node)
- if (strcmp(name, pipeline->name) == 0)
- return pipeline;
-
- return NULL;
-}
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params)
-{
- char msgq_name[NAME_MAX];
- struct rte_pipeline_params pp;
- struct pipeline *pipeline;
- struct rte_pipeline *p;
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- /* Check input params */
- if ((name == NULL) ||
- pipeline_find(name) ||
- (params == NULL) ||
- (params->timer_period_ms == 0))
- return NULL;
-
- /* Resource create */
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-REQ", name);
-
- msgq_req = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_req == NULL)
- return NULL;
-
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-RSP", name);
-
- msgq_rsp = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_rsp == NULL) {
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- pp.name = name;
- pp.socket_id = (int) params->cpu_id;
- pp.offset_port_id = params->offset_port_id;
-
- p = rte_pipeline_create(&pp);
- if (p == NULL) {
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node allocation */
- pipeline = calloc(1, sizeof(struct pipeline));
- if (pipeline == NULL) {
- rte_pipeline_free(p);
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(pipeline->name, name, sizeof(pipeline->name));
- pipeline->p = p;
- pipeline->n_ports_in = 0;
- pipeline->n_ports_out = 0;
- pipeline->n_tables = 0;
- pipeline->msgq_req = msgq_req;
- pipeline->msgq_rsp = msgq_rsp;
- pipeline->timer_period_ms = params->timer_period_ms;
- pipeline->enabled = 0;
- pipeline->cpu_id = params->cpu_id;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&pipeline_list, pipeline, node);
-
- return pipeline;
-}
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled)
-{
- struct rte_pipeline_port_in_params p;
-
- union {
- struct rte_port_ethdev_reader_params ethdev;
- struct rte_port_ring_reader_params ring;
- struct rte_port_sched_reader_params sched;
- struct rte_port_fd_reader_params fd;
- struct rte_port_source_params source;
- struct rte_port_sym_crypto_reader_params sym_crypto;
- } pp;
-
- struct pipeline *pipeline;
- struct port_in *port_in;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *action;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = port_in_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- switch (params->type) {
- case PORT_IN_RXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->rxq.queue_id >= link->n_rxq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->rxq.queue_id;
-
- p.ops = &rte_port_ethdev_reader_ops;
- p.arg_create = &pp.ethdev;
- break;
- }
-
- case PORT_IN_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
-
- p.ops = &rte_port_ring_reader_ops;
- p.arg_create = &pp.ring;
- break;
- }
-
- case PORT_IN_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
-
- p.ops = &rte_port_sched_reader_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_IN_TAP:
- {
- struct tap *tap;
- struct mempool *mempool;
-
- tap = tap_find(params->dev_name);
- mempool = mempool_find(params->tap.mempool_name);
- if ((tap == NULL) || (mempool == NULL))
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.mempool = mempool->m;
- pp.fd.mtu = params->tap.mtu;
-
- p.ops = &rte_port_fd_reader_ops;
- p.arg_create = &pp.fd;
- break;
- }
-
-
- case PORT_IN_SOURCE:
- {
- struct mempool *mempool;
-
- mempool = mempool_find(params->source.mempool_name);
- if (mempool == NULL)
- return -1;
-
- pp.source.mempool = mempool->m;
- pp.source.file_name = params->source.file_name;
- pp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;
-
- p.ops = &rte_port_source_ops;
- p.arg_create = &pp.source;
- break;
- }
-
- case PORT_IN_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->rxq.queue_id > cryptodev->n_queues - 1)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.f_callback = params->cryptodev.f_callback;
- pp.sym_crypto.arg_callback = params->cryptodev.arg_callback;
- p.ops = &rte_port_sym_crypto_reader_ops;
- p.arg_create = &pp.sym_crypto;
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.burst_size = params->burst_size;
-
- /* Resource create */
- action = NULL;
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_port_in_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_port_in_action_params_get(
- action,
- &p);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
- }
-
- status = rte_pipeline_port_in_create(pipeline->p,
- &p,
- &port_id);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
-
- if (enabled)
- rte_pipeline_port_in_enable(pipeline->p, port_id);
-
- /* Pipeline */
- port_in = &pipeline->port_in[pipeline->n_ports_in];
- memcpy(&port_in->params, params, sizeof(*params));
- port_in->ap = ap;
- port_in->a = action;
- pipeline->n_ports_in++;
-
- return 0;
-}
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct pipeline *pipeline;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (port_id >= pipeline->n_ports_in) ||
- (table_id >= pipeline->n_tables))
- return -1;
-
- /* Resource */
- status = rte_pipeline_port_in_connect_to_table(pipeline->p,
- port_id,
- table_id);
-
- return status;
-
-}
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params)
-{
- struct rte_pipeline_port_out_params p;
-
- union {
- struct rte_port_ethdev_writer_params ethdev;
- struct rte_port_ring_writer_params ring;
- struct rte_port_sched_writer_params sched;
- struct rte_port_fd_writer_params fd;
- struct rte_port_sink_params sink;
- struct rte_port_sym_crypto_writer_params sym_crypto;
- } pp;
-
- union {
- struct rte_port_ethdev_writer_nodrop_params ethdev;
- struct rte_port_ring_writer_nodrop_params ring;
- struct rte_port_fd_writer_nodrop_params fd;
- struct rte_port_sym_crypto_writer_nodrop_params sym_crypto;
- } pp_nodrop;
-
- struct pipeline *pipeline;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
- memset(&pp_nodrop, 0, sizeof(pp_nodrop));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- switch (params->type) {
- case PORT_OUT_TXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->txq.queue_id >= link->n_txq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->txq.queue_id;
- pp.ethdev.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ethdev.port_id = link->port_id;
- pp_nodrop.ethdev.queue_id = params->txq.queue_id;
- pp_nodrop.ethdev.tx_burst_sz = params->burst_size;
- pp_nodrop.ethdev.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ethdev_writer_ops;
- p.arg_create = &pp.ethdev;
- } else {
- p.ops = &rte_port_ethdev_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ethdev;
- }
- break;
- }
-
- case PORT_OUT_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
- pp.ring.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ring.ring = swq->r;
- pp_nodrop.ring.tx_burst_sz = params->burst_size;
- pp_nodrop.ring.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ring_writer_ops;
- p.arg_create = &pp.ring;
- } else {
- p.ops = &rte_port_ring_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ring;
- }
- break;
- }
-
- case PORT_OUT_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
- pp.sched.tx_burst_sz = params->burst_size;
-
- p.ops = &rte_port_sched_writer_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_OUT_TAP:
- {
- struct tap *tap;
-
- tap = tap_find(params->dev_name);
- if (tap == NULL)
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.tx_burst_sz = params->burst_size;
-
- pp_nodrop.fd.fd = tap->fd;
- pp_nodrop.fd.tx_burst_sz = params->burst_size;
- pp_nodrop.fd.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_fd_writer_ops;
- p.arg_create = &pp.fd;
- } else {
- p.ops = &rte_port_fd_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.fd;
- }
- break;
- }
-
-
- case PORT_OUT_SINK:
- {
- pp.sink.file_name = params->sink.file_name;
- pp.sink.max_n_pkts = params->sink.max_n_pkts;
-
- p.ops = &rte_port_sink_ops;
- p.arg_create = &pp.sink;
- break;
- }
-
- case PORT_OUT_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->cryptodev.queue_id >= cryptodev->n_queues)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.tx_burst_sz = params->burst_size;
- pp.sym_crypto.crypto_op_offset = params->cryptodev.op_offset;
-
- pp_nodrop.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp_nodrop.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp_nodrop.sym_crypto.tx_burst_sz = params->burst_size;
- pp_nodrop.sym_crypto.n_retries = params->retry;
- pp_nodrop.sym_crypto.crypto_op_offset =
- params->cryptodev.op_offset;
-
- if (params->retry == 0) {
- p.ops = &rte_port_sym_crypto_writer_ops;
- p.arg_create = &pp.sym_crypto;
- } else {
- p.ops = &rte_port_sym_crypto_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.sym_crypto;
- }
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- /* Resource create */
- status = rte_pipeline_port_out_create(pipeline->p,
- &p,
- &port_id);
-
- if (status)
- return -1;
-
- /* Pipeline */
- pipeline->n_ports_out++;
-
- return 0;
-}
-
-static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
-
- /* Source IP address (IPv4) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv4_hdr, src_addr),
- },
-
- /* Destination IP address (IPv4) */
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv4_hdr, dst_addr),
- },
-
- /* Source Port */
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 3,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 4,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv6_hdr, proto),
- },
-
- /* Source IP address (IPv6) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[0]),
- },
-
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[4]),
- },
-
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 3,
- .input_index = 3,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[8]),
- },
-
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 4,
- .input_index = 4,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[12]),
- },
-
- /* Destination IP address (IPv6) */
- [5] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 5,
- .input_index = 5,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[0]),
- },
-
- [6] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 6,
- .input_index = 6,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[4]),
- },
-
- [7] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 7,
- .input_index = 7,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[8]),
- },
-
- [8] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 8,
- .input_index = 8,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[12]),
- },
-
- /* Source Port */
- [9] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 9,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [10] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 10,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params)
-{
- char name[NAME_MAX];
- struct rte_pipeline_table_params p;
-
- union {
- struct rte_table_acl_params acl;
- struct rte_table_array_params array;
- struct rte_table_hash_params hash;
- struct rte_table_lpm_params lpm;
- struct rte_table_lpm_ipv6_params lpm_ipv6;
- } pp;
-
- struct pipeline *pipeline;
- struct table *table;
- struct table_action_profile *ap;
- struct rte_table_action *action;
- uint32_t table_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX))
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = table_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- snprintf(name, NAME_MAX, "%s_table%u",
- pipeline_name, pipeline->n_tables);
-
- switch (params->match_type) {
- case TABLE_ACL:
- {
- uint32_t ip_header_offset = params->match.acl.ip_header_offset -
- (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
- uint32_t i;
-
- if (params->match.acl.n_rules == 0)
- return -1;
-
- pp.acl.name = name;
- pp.acl.n_rules = params->match.acl.n_rules;
- if (params->match.acl.ip_version) {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv4,
- sizeof(table_acl_field_format_ipv4));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv4);
- } else {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv6,
- sizeof(table_acl_field_format_ipv6));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv6);
- }
-
- for (i = 0; i < pp.acl.n_rule_fields; i++)
- pp.acl.field_format[i].offset += ip_header_offset;
-
- p.ops = &rte_table_acl_ops;
- p.arg_create = &pp.acl;
- break;
- }
-
- case TABLE_ARRAY:
- {
- if (params->match.array.n_keys == 0)
- return -1;
-
- pp.array.n_entries = params->match.array.n_keys;
- pp.array.offset = params->match.array.key_offset;
-
- p.ops = &rte_table_array_ops;
- p.arg_create = &pp.array;
- break;
- }
-
- case TABLE_HASH:
- {
- struct rte_table_ops *ops;
- rte_table_hash_op_hash f_hash;
-
- if (params->match.hash.n_keys == 0)
- return -1;
-
- switch (params->match.hash.key_size) {
- case 8:
- f_hash = rte_table_hash_crc_key8;
- break;
- case 16:
- f_hash = rte_table_hash_crc_key16;
- break;
- case 24:
- f_hash = rte_table_hash_crc_key24;
- break;
- case 32:
- f_hash = rte_table_hash_crc_key32;
- break;
- case 40:
- f_hash = rte_table_hash_crc_key40;
- break;
- case 48:
- f_hash = rte_table_hash_crc_key48;
- break;
- case 56:
- f_hash = rte_table_hash_crc_key56;
- break;
- case 64:
- f_hash = rte_table_hash_crc_key64;
- break;
- default:
- return -1;
- }
-
- pp.hash.name = name;
- pp.hash.key_size = params->match.hash.key_size;
- pp.hash.key_offset = params->match.hash.key_offset;
- pp.hash.key_mask = params->match.hash.key_mask;
- pp.hash.n_keys = params->match.hash.n_keys;
- pp.hash.n_buckets = params->match.hash.n_buckets;
- pp.hash.f_hash = f_hash;
- pp.hash.seed = 0;
-
- if (params->match.hash.extendable_bucket)
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_ext_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_ext_ops;
- break;
- default:
- ops = &rte_table_hash_ext_ops;
- }
- else
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_lru_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_lru_ops;
- break;
- default:
- ops = &rte_table_hash_lru_ops;
- }
-
- p.ops = ops;
- p.arg_create = &pp.hash;
- break;
- }
-
- case TABLE_LPM:
- {
- if (params->match.lpm.n_rules == 0)
- return -1;
-
- switch (params->match.lpm.key_size) {
- case 4:
- {
- pp.lpm.name = name;
- pp.lpm.n_rules = params->match.lpm.n_rules;
- pp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm.flags = 0;
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ops;
- p.arg_create = &pp.lpm;
- break;
- }
-
- case 16:
- {
- pp.lpm_ipv6.name = name;
- pp.lpm_ipv6.n_rules = params->match.lpm.n_rules;
- pp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm_ipv6.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ipv6_ops;
- p.arg_create = &pp.lpm_ipv6;
- break;
- }
-
- default:
- return -1;
- }
-
- break;
- }
-
- case TABLE_STUB:
- {
- p.ops = &rte_table_stub_ops;
- p.arg_create = NULL;
- break;
- }
-
- default:
- return -1;
- }
-
- /* Resource create */
- action = NULL;
- p.f_action_hit = NULL;
- p.f_action_miss = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_table_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_table_action_table_params_get(
- action,
- &p);
- if (status ||
- ((p.action_data_size +
- sizeof(struct rte_pipeline_table_entry)) >
- TABLE_RULE_ACTION_SIZE_MAX)) {
- rte_table_action_free(action);
- return -1;
- }
- }
-
- if (params->match_type == TABLE_LPM) {
- if (params->match.lpm.key_size == 4)
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
-
- if (params->match.lpm.key_size == 16)
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- }
-
- status = rte_pipeline_table_create(pipeline->p,
- &p,
- &table_id);
- if (status) {
- rte_table_action_free(action);
- return -1;
- }
-
- /* Pipeline */
- table = &pipeline->table[pipeline->n_tables];
- memcpy(&table->params, params, sizeof(*params));
- table->ap = ap;
- table->a = action;
- TAILQ_INIT(&table->rules);
- table->rule_default = NULL;
-
- pipeline->n_tables++;
-
- return 0;
-}
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- TAILQ_FOREACH(rule, &table->rules, node)
- if (memcmp(&rule->match, match, sizeof(*match)) == 0)
- return rule;
-
- return NULL;
-}
-
-void
-table_rule_add(struct table *table,
- struct table_rule *new_rule)
-{
- struct table_rule *existing_rule;
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
-}
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules)
-{
- uint32_t i;
-
- for (i = 0; i < n_rules; i++) {
- struct table_rule *existing_rule, *new_rule;
-
- new_rule = TAILQ_FIRST(list);
- if (new_rule == NULL)
- break;
-
- TAILQ_REMOVE(list, new_rule, node);
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
- }
-}
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return;
-
- TAILQ_REMOVE(&table->rules, rule, node);
- free(rule);
-}
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule)
-{
- free(table->rule_default);
- table->rule_default = rule;
-}
-
-void
-table_rule_default_delete(struct table *table)
-{
- free(table->rule_default);
- table->rule_default = NULL;
-}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
deleted file mode 100644
index 89696480fc..0000000000
--- a/examples/ip_pipeline/pipeline.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_PIPELINE_H_
-#define _INCLUDE_PIPELINE_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_pipeline.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-#include "action.h"
-
-struct pipeline_params {
- uint32_t timer_period_ms;
- uint32_t offset_port_id;
- uint32_t cpu_id;
-};
-
-enum port_in_type {
- PORT_IN_RXQ,
- PORT_IN_SWQ,
- PORT_IN_TMGR,
- PORT_IN_TAP,
- PORT_IN_SOURCE,
- PORT_IN_CRYPTODEV,
-};
-
-struct port_in_params {
- /* Read */
- enum port_in_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } rxq;
-
- struct {
- const char *mempool_name;
- uint32_t mtu;
- } tap;
-
- struct {
- const char *mempool_name;
- const char *file_name;
- uint32_t n_bytes_per_pkt;
- } source;
-
- struct {
- uint16_t queue_id;
- void *f_callback;
- void *arg_callback;
- } cryptodev;
- };
- uint32_t burst_size;
-
- /* Action */
- const char *action_profile_name;
-};
-
-enum port_out_type {
- PORT_OUT_TXQ,
- PORT_OUT_SWQ,
- PORT_OUT_TMGR,
- PORT_OUT_TAP,
- PORT_OUT_SINK,
- PORT_OUT_CRYPTODEV,
-};
-
-struct port_out_params {
- enum port_out_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } txq;
-
- struct {
- const char *file_name;
- uint32_t max_n_pkts;
- } sink;
-
- struct {
- uint16_t queue_id;
- uint32_t op_offset;
- } cryptodev;
- };
- uint32_t burst_size;
- int retry;
- uint32_t n_retries;
-};
-
-enum table_type {
- TABLE_ACL,
- TABLE_ARRAY,
- TABLE_HASH,
- TABLE_LPM,
- TABLE_STUB,
-};
-
-struct table_acl_params {
- uint32_t n_rules;
- uint32_t ip_header_offset;
- int ip_version;
-};
-
-struct table_array_params {
- uint32_t n_keys;
- uint32_t key_offset;
-};
-
-struct table_hash_params {
- uint32_t n_keys;
- uint32_t key_offset;
- uint32_t key_size;
- uint8_t *key_mask;
- uint32_t n_buckets;
- int extendable_bucket;
-};
-
-struct table_lpm_params {
- uint32_t n_rules;
- uint32_t key_offset;
- uint32_t key_size;
-};
-
-struct table_params {
- /* Match */
- enum table_type match_type;
- union {
- struct table_acl_params acl;
- struct table_array_params array;
- struct table_hash_params hash;
- struct table_lpm_params lpm;
- } match;
-
- /* Action */
- const char *action_profile_name;
-};
-
-struct table_rule;
-
-TAILQ_HEAD(table_rule_list, table_rule);
-
-struct port_in {
- struct port_in_params params;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *a;
-};
-
-struct table {
- struct table_params params;
- struct table_action_profile *ap;
- struct rte_table_action *a;
- struct table_rule_list rules;
- struct table_rule *rule_default;
-};
-
-struct pipeline {
- TAILQ_ENTRY(pipeline) node;
- char name[NAME_SIZE];
-
- struct rte_pipeline *p;
- struct port_in port_in[RTE_PIPELINE_PORT_IN_MAX];
- struct table table[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
-
- int enabled;
- uint32_t thread_id;
- uint32_t cpu_id;
-};
-
-TAILQ_HEAD(pipeline_list, pipeline);
-
-int
-pipeline_init(void);
-
-struct pipeline *
-pipeline_find(const char *name);
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params);
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled);
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id);
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params);
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params);
-
-struct table_rule_match_acl {
- int ip_version;
-
- union {
- struct {
- uint32_t sa;
- uint32_t da;
- } ipv4;
-
- struct {
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- } ipv6;
- };
-
- uint32_t sa_depth;
- uint32_t da_depth;
- uint16_t sp0;
- uint16_t sp1;
- uint16_t dp0;
- uint16_t dp1;
- uint8_t proto;
- uint8_t proto_mask;
- uint32_t priority;
-};
-
-struct table_rule_match_array {
- uint32_t pos;
-};
-
-#ifndef TABLE_RULE_MATCH_SIZE_MAX
-#define TABLE_RULE_MATCH_SIZE_MAX 256
-#endif
-
-#ifndef TABLE_RULE_ACTION_SIZE_MAX
-#define TABLE_RULE_ACTION_SIZE_MAX 2048
-#endif
-
-struct table_rule_match_hash {
- uint8_t key[TABLE_RULE_MATCH_SIZE_MAX];
-};
-
-struct table_rule_match_lpm {
- int ip_version;
-
- union {
- uint32_t ipv4;
- struct rte_ipv6_addr ipv6;
- };
-
- uint8_t depth;
-};
-
-struct table_rule_match {
- enum table_type match_type;
-
- union {
- struct table_rule_match_acl acl;
- struct table_rule_match_array array;
- struct table_rule_match_hash hash;
- struct table_rule_match_lpm lpm;
- } match;
-};
-
-#ifndef SYM_CRYPTO_MAX_KEY_SIZE
-#define SYM_CRYPTO_MAX_KEY_SIZE (256)
-#endif
-
-struct table_rule_action {
- uint64_t action_mask;
- struct rte_table_action_fwd_params fwd;
- struct rte_table_action_lb_params lb;
- struct rte_table_action_mtr_params mtr;
- struct rte_table_action_tm_params tm;
- struct rte_table_action_encap_params encap;
- struct rte_table_action_nat_params nat;
- struct rte_table_action_ttl_params ttl;
- struct rte_table_action_stats_params stats;
- struct rte_table_action_time_params time;
- struct rte_table_action_sym_crypto_params sym_crypto;
- uint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];
- struct rte_table_action_tag_params tag;
- struct rte_table_action_decap_params decap;
-
-};
-
-struct table_rule {
- TAILQ_ENTRY(table_rule) node;
- struct table_rule_match match;
- struct table_rule_action action;
- void *data;
-};
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear);
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear);
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear);
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added);
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match);
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id);
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id);
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table);
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp);
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules);
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_default_delete(struct table *table);
-
-#endif /* _INCLUDE_PIPELINE_H_ */
diff --git a/examples/ip_pipeline/swq.c b/examples/ip_pipeline/swq.c
deleted file mode 100644
index 7e54a1dbfe..0000000000
--- a/examples/ip_pipeline/swq.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-
-#include "swq.h"
-
-static struct swq_list swq_list;
-
-int
-swq_init(void)
-{
- TAILQ_INIT(&swq_list);
-
- return 0;
-}
-
-struct swq *
-swq_find(const char *name)
-{
- struct swq *swq;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(swq, &swq_list, node)
- if (strcmp(swq->name, name) == 0)
- return swq;
-
- return NULL;
-}
-
-struct swq *
-swq_create(const char *name, struct swq_params *params)
-{
- struct swq *swq;
- struct rte_ring *r;
- unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ;
-
- /* Check input params */
- if ((name == NULL) ||
- swq_find(name) ||
- (params == NULL) ||
- (params->size == 0))
- return NULL;
-
- /* Resource create */
- r = rte_ring_create(
- name,
- params->size,
- params->cpu_id,
- flags);
-
- if (r == NULL)
- return NULL;
-
- /* Node allocation */
- swq = calloc(1, sizeof(struct swq));
- if (swq == NULL) {
- rte_ring_free(r);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(swq->name, name, sizeof(swq->name));
- swq->r = r;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&swq_list, swq, node);
-
- return swq;
-}
diff --git a/examples/ip_pipeline/swq.h b/examples/ip_pipeline/swq.h
deleted file mode 100644
index c8440ee3cd..0000000000
--- a/examples/ip_pipeline/swq.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SWQ_H_
-#define _INCLUDE_SWQ_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_ring.h>
-
-#include "common.h"
-
-struct swq {
- TAILQ_ENTRY(swq) node;
- char name[NAME_SIZE];
- struct rte_ring *r;
-};
-
-TAILQ_HEAD(swq_list, swq);
-
-int
-swq_init(void);
-
-struct swq *
-swq_find(const char *name);
-
-struct swq_params {
- uint32_t size;
- uint32_t cpu_id;
-};
-
-struct swq *
-swq_create(const char *name, struct swq_params *params);
-
-#endif /* _INCLUDE_SWQ_H_ */
diff --git a/examples/ip_pipeline/tap.c b/examples/ip_pipeline/tap.c
deleted file mode 100644
index adae640c1e..0000000000
--- a/examples/ip_pipeline/tap.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <netinet/in.h>
-#ifdef RTE_EXEC_ENV_LINUX
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <rte_string_fns.h>
-
-#include "tap.h"
-
-#define TAP_DEV "/dev/net/tun"
-
-static struct tap_list tap_list;
-
-int
-tap_init(void)
-{
- TAILQ_INIT(&tap_list);
-
- return 0;
-}
-
-struct tap *
-tap_find(const char *name)
-{
- struct tap *tap;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tap, &tap_list, node)
- if (strcmp(tap->name, name) == 0)
- return tap;
-
- return NULL;
-}
-
-#ifndef RTE_EXEC_ENV_LINUX
-
-struct tap *
-tap_create(const char *name __rte_unused)
-{
- return NULL;
-}
-
-#else
-
-struct tap *
-tap_create(const char *name)
-{
- struct tap *tap;
- struct ifreq ifr;
- int fd, status;
-
- /* Check input params */
- if ((name == NULL) ||
- tap_find(name))
- return NULL;
-
- /* Resource create */
- fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
- if (fd < 0)
- return NULL;
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
- strlcpy(ifr.ifr_name, name, IFNAMSIZ);
-
- status = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (status < 0) {
- close(fd);
- return NULL;
- }
-
- /* Node allocation */
- tap = calloc(1, sizeof(struct tap));
- if (tap == NULL) {
- close(fd);
- return NULL;
- }
- /* Node fill in */
- strlcpy(tap->name, name, sizeof(tap->name));
- tap->fd = fd;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tap_list, tap, node);
-
- return tap;
-}
-
-#endif
diff --git a/examples/ip_pipeline/tap.h b/examples/ip_pipeline/tap.h
deleted file mode 100644
index 0dce72fe3c..0000000000
--- a/examples/ip_pipeline/tap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TAP_H_
-#define _INCLUDE_TAP_H_
-
-#include <sys/queue.h>
-
-#include "common.h"
-
-struct tap {
- TAILQ_ENTRY(tap) node;
- char name[NAME_SIZE];
- int fd;
-};
-
-TAILQ_HEAD(tap_list, tap);
-
-int
-tap_init(void);
-
-struct tap *
-tap_find(const char *name);
-
-struct tap *
-tap_create(const char *name);
-
-#endif /* _INCLUDE_TAP_H_ */
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
deleted file mode 100644
index 0a44bddd90..0000000000
--- a/examples/ip_pipeline/thread.c
+++ /dev/null
@@ -1,3137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_lcore.h>
-#include <rte_ring.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-
-#include "common.h"
-#include "thread.h"
-#include "pipeline.h"
-
-#ifndef THREAD_PIPELINES_MAX
-#define THREAD_PIPELINES_MAX 256
-#endif
-
-#ifndef THREAD_MSGQ_SIZE
-#define THREAD_MSGQ_SIZE 64
-#endif
-
-#ifndef THREAD_TIMER_PERIOD_MS
-#define THREAD_TIMER_PERIOD_MS 100
-#endif
-
-/**
- * Main thread: data plane thread context
- */
-struct thread {
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- uint32_t enabled;
-};
-
-static struct thread thread[RTE_MAX_LCORE];
-
-/**
- * Data plane threads: context
- */
-struct table_data {
- struct rte_table_action *a;
-};
-
-struct pipeline_data {
- struct rte_pipeline *p;
- struct table_data table_data[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
-
- uint8_t buffer[TABLE_RULE_ACTION_SIZE_MAX];
-};
-
-struct __rte_cache_aligned thread_data {
- struct rte_pipeline *p[THREAD_PIPELINES_MAX];
- uint32_t n_pipelines;
-
- struct pipeline_data pipeline_data[THREAD_PIPELINES_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
- uint64_t time_next_min;
-};
-
-static struct thread_data thread_data[RTE_MAX_LCORE];
-
-/**
- * Main thread: data plane thread init
- */
-static void
-thread_free(void)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- struct thread *t = &thread[i];
-
- if (!rte_lcore_is_enabled(i))
- continue;
-
- /* MSGQs */
- rte_ring_free(t->msgq_req);
-
- rte_ring_free(t->msgq_rsp);
- }
-}
-
-int
-thread_init(void)
-{
- uint32_t i;
-
- RTE_LCORE_FOREACH_WORKER(i) {
- char name[NAME_MAX];
- struct rte_ring *msgq_req, *msgq_rsp;
- struct thread *t = &thread[i];
- struct thread_data *t_data = &thread_data[i];
- uint32_t cpu_id = rte_lcore_to_socket_id(i);
-
- /* MSGQs */
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-REQ", i);
-
- msgq_req = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_req == NULL) {
- thread_free();
- return -1;
- }
-
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-RSP", i);
-
- msgq_rsp = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_rsp == NULL) {
- thread_free();
- return -1;
- }
-
- /* Main thread records */
- t->msgq_req = msgq_req;
- t->msgq_rsp = msgq_rsp;
- t->enabled = 1;
-
- /* Data plane thread records */
- t_data->n_pipelines = 0;
- t_data->msgq_req = msgq_req;
- t_data->msgq_rsp = msgq_rsp;
- t_data->timer_period =
- (rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;
- t_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;
- t_data->time_next_min = t_data->time_next;
- }
-
- return 0;
-}
-
-static inline int
-thread_is_running(uint32_t thread_id)
-{
- enum rte_lcore_state_t thread_state;
-
- thread_state = rte_eal_get_lcore_state(thread_id);
- return (thread_state == RUNNING) ? 1 : 0;
-}
-
-/**
- * Pipeline is running when:
- * (A) Pipeline is mapped to a data plane thread AND
- * (B) Its data plane thread is in RUNNING state.
- */
-static inline int
-pipeline_is_running(struct pipeline *p)
-{
- if (p->enabled == 0)
- return 0;
-
- return thread_is_running(p->thread_id);
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum thread_req_type {
- THREAD_REQ_PIPELINE_ENABLE = 0,
- THREAD_REQ_PIPELINE_DISABLE,
- THREAD_REQ_MAX
-};
-
-struct thread_msg_req {
- enum thread_req_type type;
-
- union {
- struct {
- struct rte_pipeline *p;
- struct {
- struct rte_table_action *a;
- } table[RTE_PIPELINE_TABLE_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
- uint32_t n_tables;
- } pipeline_enable;
-
- struct {
- struct rte_pipeline *p;
- } pipeline_disable;
- };
-};
-
-struct thread_msg_rsp {
- int status;
-};
-
-/**
- * Main thread
- */
-static struct thread_msg_req *
-thread_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct thread_msg_req),
- sizeof(struct thread_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-thread_msg_free(struct thread_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct thread_msg_rsp *
-thread_msg_send_recv(uint32_t thread_id,
- struct thread_msg_req *req)
-{
- struct thread *t = &thread[thread_id];
- struct rte_ring *msgq_req = t->msgq_req;
- struct rte_ring *msgq_rsp = t->msgq_rsp;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- uint32_t i;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL) ||
- (p->n_ports_in == 0) ||
- (p->n_ports_out == 0) ||
- (p->n_tables == 0))
- return -1;
-
- t = &thread[thread_id];
- if ((t->enabled == 0) ||
- p->enabled)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- struct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];
-
- if (td->n_pipelines >= THREAD_PIPELINES_MAX)
- return -1;
-
- /* Data plane thread */
- td->p[td->n_pipelines] = p->p;
-
- tdp->p = p->p;
- for (i = 0; i < p->n_tables; i++)
- tdp->table_data[i].a = p->table[i].a;
-
- tdp->n_tables = p->n_tables;
-
- tdp->msgq_req = p->msgq_req;
- tdp->msgq_rsp = p->msgq_rsp;
- tdp->timer_period = (rte_get_tsc_hz() * p->timer_period_ms) / 1000;
- tdp->time_next = rte_get_tsc_cycles() + tdp->timer_period;
-
- td->n_pipelines++;
-
- /* Pipeline */
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_ENABLE;
- req->pipeline_enable.p = p->p;
- for (i = 0; i < p->n_tables; i++)
- req->pipeline_enable.table[i].a =
- p->table[i].a;
- req->pipeline_enable.msgq_req = p->msgq_req;
- req->pipeline_enable.msgq_rsp = p->msgq_rsp;
- req->pipeline_enable.timer_period_ms = p->timer_period_ms;
- req->pipeline_enable.n_tables = p->n_tables;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
-}
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL))
- return -1;
-
- t = &thread[thread_id];
- if (t->enabled == 0)
- return -1;
-
- if (p->enabled == 0)
- return 0;
-
- if (p->thread_id != thread_id)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- uint32_t i;
-
- for (i = 0; i < td->n_pipelines; i++) {
- struct pipeline_data *tdp = &td->pipeline_data[i];
-
- if (tdp->p != p->p)
- continue;
-
- /* Data plane thread */
- if (i < td->n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- td->p[td->n_pipelines - 1];
- struct pipeline_data *tdp_last =
- &td->pipeline_data[td->n_pipelines - 1];
-
- td->p[i] = pipeline_last;
- memcpy(tdp, tdp_last, sizeof(*tdp));
- }
-
- td->n_pipelines--;
-
- /* Pipeline */
- p->enabled = 0;
-
- break;
- }
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_DISABLE;
- req->pipeline_disable.p = p->p;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->enabled = 0;
-
- return 0;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct thread_msg_req *
-thread_msg_recv(struct rte_ring *msgq_req)
-{
- struct thread_msg_req *req = NULL;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-thread_msg_send(struct rte_ring *msgq_rsp,
- struct thread_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_enable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- struct pipeline_data *p = &t->pipeline_data[t->n_pipelines];
- uint32_t i;
-
- /* Request */
- if (t->n_pipelines >= THREAD_PIPELINES_MAX) {
- rsp->status = -1;
- return rsp;
- }
-
- t->p[t->n_pipelines] = req->pipeline_enable.p;
-
- p->p = req->pipeline_enable.p;
- for (i = 0; i < req->pipeline_enable.n_tables; i++)
- p->table_data[i].a =
- req->pipeline_enable.table[i].a;
-
- p->n_tables = req->pipeline_enable.n_tables;
-
- p->msgq_req = req->pipeline_enable.msgq_req;
- p->msgq_rsp = req->pipeline_enable.msgq_rsp;
- p->timer_period =
- (rte_get_tsc_hz() * req->pipeline_enable.timer_period_ms) / 1000;
- p->time_next = rte_get_tsc_cycles() + p->timer_period;
-
- t->n_pipelines++;
-
- /* Response */
- rsp->status = 0;
- return rsp;
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_disable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- uint32_t n_pipelines = t->n_pipelines;
- struct rte_pipeline *pipeline = req->pipeline_disable.p;
- uint32_t i;
-
- /* find pipeline */
- for (i = 0; i < n_pipelines; i++) {
- struct pipeline_data *p = &t->pipeline_data[i];
-
- if (p->p != pipeline)
- continue;
-
- if (i < n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- t->p[n_pipelines - 1];
- struct pipeline_data *p_last =
- &t->pipeline_data[n_pipelines - 1];
-
- t->p[i] = pipeline_last;
- memcpy(p, p_last, sizeof(*p));
- }
-
- t->n_pipelines--;
-
- rsp->status = 0;
- return rsp;
- }
-
- /* should not get here */
- rsp->status = 0;
- return rsp;
-}
-
-static void
-thread_msg_handle(struct thread_data *t)
-{
- for ( ; ; ) {
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
-
- req = thread_msg_recv(t->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case THREAD_REQ_PIPELINE_ENABLE:
- rsp = thread_msg_handle_pipeline_enable(t, req);
- break;
-
- case THREAD_REQ_PIPELINE_DISABLE:
- rsp = thread_msg_handle_pipeline_disable(t, req);
- break;
-
- default:
- rsp = (struct thread_msg_rsp *) req;
- rsp->status = -1;
- }
-
- thread_msg_send(t->msgq_rsp, rsp);
- }
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum pipeline_req_type {
- /* Port IN */
- PIPELINE_REQ_PORT_IN_STATS_READ,
- PIPELINE_REQ_PORT_IN_ENABLE,
- PIPELINE_REQ_PORT_IN_DISABLE,
-
- /* Port OUT */
- PIPELINE_REQ_PORT_OUT_STATS_READ,
-
- /* Table */
- PIPELINE_REQ_TABLE_STATS_READ,
- PIPELINE_REQ_TABLE_RULE_ADD,
- PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_ADD_BULK,
- PIPELINE_REQ_TABLE_RULE_DELETE,
- PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_STATS_READ,
- PIPELINE_REQ_TABLE_MTR_PROFILE_ADD,
- PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE,
- PIPELINE_REQ_TABLE_RULE_MTR_READ,
- PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,
- PIPELINE_REQ_TABLE_RULE_TTL_READ,
- PIPELINE_REQ_TABLE_RULE_TIME_READ,
- PIPELINE_REQ_MAX
-};
-
-struct pipeline_msg_req_port_in_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_port_out_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_add {
- struct table_rule_match match;
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_default {
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_bulk {
- struct table_rule_list *list;
- int bulk;
-};
-
-struct pipeline_msg_req_table_rule_delete {
- struct table_rule_match match;
-};
-
-struct pipeline_msg_req_table_rule_stats_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_mtr_profile_add {
- uint32_t meter_profile_id;
- struct rte_table_action_meter_profile profile;
-};
-
-struct pipeline_msg_req_table_mtr_profile_delete {
- uint32_t meter_profile_id;
-};
-
-struct pipeline_msg_req_table_rule_mtr_read {
- void *data;
- uint32_t tc_mask;
- int clear;
-};
-
-struct pipeline_msg_req_table_dscp_table_update {
- uint64_t dscp_mask;
- struct rte_table_action_dscp_table dscp_table;
-};
-
-struct pipeline_msg_req_table_rule_ttl_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_time_read {
- void *data;
-};
-
-struct pipeline_msg_req {
- enum pipeline_req_type type;
- uint32_t id; /* Port IN, port OUT or table ID */
-
- union {
- struct pipeline_msg_req_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_req_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_req_table_stats_read table_stats_read;
- struct pipeline_msg_req_table_rule_add table_rule_add;
- struct pipeline_msg_req_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_req_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_req_table_rule_delete table_rule_delete;
- struct pipeline_msg_req_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_req_table_mtr_profile_add table_mtr_profile_add;
- struct pipeline_msg_req_table_mtr_profile_delete table_mtr_profile_delete;
- struct pipeline_msg_req_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_req_table_dscp_table_update table_dscp_table_update;
- struct pipeline_msg_req_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_req_table_rule_time_read table_rule_time_read;
- };
-};
-
-struct pipeline_msg_rsp_port_in_stats_read {
- struct rte_pipeline_port_in_stats stats;
-};
-
-struct pipeline_msg_rsp_port_out_stats_read {
- struct rte_pipeline_port_out_stats stats;
-};
-
-struct pipeline_msg_rsp_table_stats_read {
- struct rte_pipeline_table_stats stats;
-};
-
-struct pipeline_msg_rsp_table_rule_add {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_default {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_bulk {
- uint32_t n_rules;
-};
-
-struct pipeline_msg_rsp_table_rule_stats_read {
- struct rte_table_action_stats_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_mtr_read {
- struct rte_table_action_mtr_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_ttl_read {
- struct rte_table_action_ttl_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_time_read {
- uint64_t timestamp;
-};
-
-struct pipeline_msg_rsp {
- int status;
-
- union {
- struct pipeline_msg_rsp_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_rsp_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_rsp_table_stats_read table_stats_read;
- struct pipeline_msg_rsp_table_rule_add table_rule_add;
- struct pipeline_msg_rsp_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_rsp_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_rsp_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_rsp_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_rsp_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_rsp_table_rule_time_read table_rule_time_read;
- };
-};
-
-/**
- * Main thread
- */
-static struct pipeline_msg_req *
-pipeline_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct pipeline_msg_req),
- sizeof(struct pipeline_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-pipeline_msg_free(struct pipeline_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_send_recv(struct pipeline *p,
- struct pipeline_msg_req *req)
-{
- struct rte_ring *msgq_req = p->msgq_req;
- struct rte_ring *msgq_rsp = p->msgq_rsp;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_STATS_READ;
- req->id = port_id;
- req->port_in_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_enable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_ENABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_disable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_DISABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_out))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_OUT_STATS_READ;
- req->id = port_id;
- req->port_out_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_stats_read(p->p,
- table_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_STATS_READ;
- req->id = table_id;
- req->table_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static int
-match_check(struct table_rule_match *match,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table *table;
-
- if ((match == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
- if (match->match_type != table->params.match_type)
- return -1;
-
- switch (match->match_type) {
- case TABLE_ACL:
- {
- struct table_acl_params *t = &table->params.match.acl;
- struct table_rule_match_acl *r = &match->match.acl;
-
- if ((r->ip_version && (t->ip_version == 0)) ||
- ((r->ip_version == 0) && t->ip_version))
- return -1;
-
- if (r->ip_version) {
- if ((r->sa_depth > 32) ||
- (r->da_depth > 32))
- return -1;
- } else {
- if ((r->sa_depth > 128) ||
- (r->da_depth > 128))
- return -1;
- }
- return 0;
- }
-
- case TABLE_ARRAY:
- return 0;
-
- case TABLE_HASH:
- return 0;
-
- case TABLE_LPM:
- {
- struct table_lpm_params *t = &table->params.match.lpm;
- struct table_rule_match_lpm *r = &match->match.lpm;
-
- if ((r->ip_version && (t->key_size != 4)) ||
- ((r->ip_version == 0) && (t->key_size != 16)))
- return -1;
-
- if (r->ip_version) {
- if (r->depth > 32)
- return -1;
- } else {
- if (r->depth > 128)
- return -1;
- }
- return 0;
- }
-
- case TABLE_STUB:
- return -1;
-
- default:
- return -1;
- }
-}
-
-static int
-action_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table_action_profile *ap;
-
- if ((action == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- ap = p->table[table_id].ap;
- if (action->action_mask != ap->params.action_mask)
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- uint32_t tc_mask0 = (1 << ap->params.mtr.n_tc) - 1;
- uint32_t tc_mask1 = action->mtr.tc_mask;
-
- if (tc_mask1 != tc_mask0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- uint32_t n_subports_per_port =
- ap->params.tm.n_subports_per_port;
- uint32_t n_pipes_per_subport =
- ap->params.tm.n_pipes_per_subport;
- uint32_t subport_id = action->tm.subport_id;
- uint32_t pipe_id = action->tm.pipe_id;
-
- if ((subport_id >= n_subports_per_port) ||
- (pipe_id >= n_pipes_per_subport))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- uint64_t encap_mask = ap->params.encap.encap_mask;
- enum rte_table_action_encap_type type = action->encap.type;
-
- if ((encap_mask & (1LLU << type)) == 0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- int ip_version0 = ap->params.common.ip_version;
- int ip_version1 = action->nat.ip_version;
-
- if ((ip_version1 && (ip_version0 == 0)) ||
- ((ip_version1 == 0) && ip_version0))
- return -1;
- }
-
- return 0;
-}
-
-static int
-action_default_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- if ((action == NULL) ||
- (action->action_mask != (1LLU << RTE_TABLE_ACTION_FWD)) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- return 0;
-}
-
-union table_rule_match_low_level {
- struct rte_table_acl_rule_add_params acl_add;
- struct rte_table_acl_rule_delete_params acl_delete;
- struct rte_table_array_key array;
- uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
- struct rte_table_lpm_key lpm_ipv4;
- struct rte_table_lpm_ipv6_key lpm_ipv6;
-};
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add);
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data);
-
-struct table_ll {
- struct rte_pipeline *p;
- int table_id;
- struct rte_table_action *a;
- int bulk_supported;
-};
-
-static int
-table_rule_add_bulk_ll(struct table_ll *table,
- struct table_rule_list *list,
- uint32_t *n_rules)
-{
- union table_rule_match_low_level *match_ll = NULL;
- uint8_t *action_ll = NULL;
- void **match_ll_ptr = NULL;
- struct rte_pipeline_table_entry **action_ll_ptr = NULL;
- struct rte_pipeline_table_entry **entries_ptr = NULL;
- int *found = NULL;
- struct table_rule *rule;
- uint32_t n, i;
- int status = 0;
-
- n = 0;
- TAILQ_FOREACH(rule, list, node)
- n++;
-
- /* Memory allocation */
- match_ll = calloc(n, sizeof(union table_rule_match_low_level));
- action_ll = calloc(n, TABLE_RULE_ACTION_SIZE_MAX);
-
- match_ll_ptr = calloc(n, sizeof(void *));
- action_ll_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
-
- entries_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
- found = calloc(n, sizeof(int));
-
- if (match_ll == NULL ||
- action_ll == NULL ||
- match_ll_ptr == NULL ||
- action_ll_ptr == NULL ||
- entries_ptr == NULL ||
- found == NULL) {
- status = -ENOMEM;
- goto table_rule_add_bulk_ll_free;
- }
-
- /* Init */
- for (i = 0; i < n; i++) {
- match_ll_ptr[i] = (void *)&match_ll[i];
- action_ll_ptr[i] = (struct rte_pipeline_table_entry *)
- &action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
- }
-
- /* Rule (match, action) conversion */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- status = match_convert(&rule->match, match_ll_ptr[i], 1);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- status = action_convert(table->a, &rule->action, action_ll_ptr[i]);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- i++;
- }
-
- /* Add rule (match, action) to table */
- if (table->bulk_supported) {
- status = rte_pipeline_table_entry_add_bulk(table->p,
- table->table_id,
- match_ll_ptr,
- action_ll_ptr,
- n,
- found,
- entries_ptr);
- if (status)
- goto table_rule_add_bulk_ll_free;
- } else
- for (i = 0; i < n; i++) {
- status = rte_pipeline_table_entry_add(table->p,
- table->table_id,
- match_ll_ptr[i],
- action_ll_ptr[i],
- &found[i],
- &entries_ptr[i]);
- if (status) {
- if (i == 0)
- goto table_rule_add_bulk_ll_free;
-
- /* No roll-back. */
- status = 0;
- n = i;
- break;
- }
- }
-
- /* Write back to the rule list. */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- if (i >= n)
- break;
-
- rule->data = entries_ptr[i];
-
- i++;
- }
-
- *n_rules = n;
-
- /* Free */
-table_rule_add_bulk_ll_free:
- free(found);
- free(entries_ptr);
- free(action_ll_ptr);
- free(match_ll_ptr);
- free(action_ll);
- free(match_ll);
-
- return status;
-}
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id) ||
- action_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->match, match, sizeof(*match));
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- struct rte_pipeline_table_entry *data_in, *data_out;
- int key_found;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Table match-action rule conversion */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- status = action_convert(table->a, action, data_in);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Add rule (match, action) to table */
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD;
- req->id = table_id;
- memcpy(&req->table_rule_add.match, match, sizeof(*match));
- memcpy(&req->table_rule_add.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add.data;
- table_rule_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- action_default_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Apply actions */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_default_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT;
- req->id = table_id;
- memcpy(&req->table_rule_add_default.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add_default.data;
- table_rule_default_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static uint32_t
-table_rule_list_free(struct table_rule_list *list)
-{
- uint32_t n = 0;
-
- if (!list)
- return 0;
-
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- n++;
- }
-
- free(list);
- return n;
-}
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status = 0;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (list == NULL) ||
- TAILQ_EMPTY(list) ||
- (n_rules_added == NULL) ||
- (n_rules_not_added == NULL)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- table = &p->table[table_id];
-
- TAILQ_FOREACH(rule, list, node)
- if (match_check(&rule->match, p, table_id) ||
- action_check(&rule->action, p, table_id)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- if (!pipeline_is_running(p)) {
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = table->a,
- .bulk_supported = table->params.match_type == TABLE_ACL,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, n_rules_added);
- if (status) {
- table_rule_list_free(list);
- return status;
- }
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- table_rule_list_free(list);
- return -ENOMEM;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;
- req->id = table_id;
- req->table_rule_add_bulk.list = list;
- req->table_rule_add_bulk.bulk = table->params.match_type == TABLE_ACL;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- *n_rules_added = rsp->table_rule_add_bulk.n_rules;
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- } else
- table_rule_list_free(list);
-
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- int key_found;
-
- status = match_convert(match, &match_ll, 0);
- if (status)
- return -1;
-
- status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- if (status == 0)
- table_rule_delete(table, match);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE;
- req->id = table_id;
- memcpy(&req->table_rule_delete.match, match, sizeof(*match));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_delete(table, match);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- if (status == 0)
- table_rule_default_delete(table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT;
- req->id = table_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_default_delete(table);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_stats_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_STATS_READ;
- req->id = table_id;
- req->table_rule_stats_read.data = rule->data;
- req->table_rule_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (profile == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
- req->id = table_id;
- req->table_mtr_profile_add.meter_profile_id = meter_profile_id;
- memcpy(&req->table_mtr_profile_add.profile, profile, sizeof(*profile));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE;
- req->id = table_id;
- req->table_mtr_profile_delete.meter_profile_id = meter_profile_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- uint32_t tc_mask;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- tc_mask = (1 << table->ap->params.mtr.n_tc) - 1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_meter_read(table->a,
- rule->data,
- tc_mask,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_MTR_READ;
- req->id = table_id;
- req->table_rule_mtr_read.data = rule->data;
- req->table_rule_mtr_read.tc_mask = tc_mask;
- req->table_rule_mtr_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_mtr_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (dscp_table == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE;
- req->id = table_id;
- req->table_dscp_table_update.dscp_mask = dscp_mask;
- memcpy(&req->table_dscp_table_update.dscp_table,
- dscp_table, sizeof(*dscp_table));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- if (!table->ap->params.ttl.n_packets_enabled)
- return -1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_ttl_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TTL_READ;
- req->id = table_id;
- req->table_rule_ttl_read.data = rule->data;
- req->table_rule_ttl_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (timestamp == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_time_read(table->a,
- rule->data,
- timestamp);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TIME_READ;
- req->id = table_id;
- req->table_rule_time_read.data = rule->data;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- *timestamp = rsp->table_rule_time_read.timestamp;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct pipeline_msg_req *
-pipeline_msg_recv(struct rte_ring *msgq_req)
-{
- struct pipeline_msg_req *req;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-pipeline_msg_send(struct rte_ring *msgq_rsp,
- struct pipeline_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_in_stats_read.clear;
-
- rsp->status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- &rsp->port_in_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_enable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_enable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_disable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_disable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_out_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_out_stats_read.clear;
-
- rsp->status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- &rsp->port_out_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->table_stats_read.clear;
-
- rsp->status = rte_pipeline_table_stats_read(p->p,
- port_id,
- &rsp->table_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static int
-match_convert_ipv6_depth(uint32_t depth, uint32_t *depth32)
-{
- if (depth > 128)
- return -1;
-
- switch (depth / 32) {
- case 0:
- depth32[0] = depth;
- depth32[1] = 0;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 1:
- depth32[0] = 32;
- depth32[1] = depth - 32;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 2:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = depth - 64;
- depth32[3] = 0;
- return 0;
-
- case 3:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = depth - 96;
- return 0;
-
- case 4:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = 32;
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add)
-{
- memset(ml, 0, sizeof(*ml));
-
- switch (mh->match_type) {
- case TABLE_ACL:
- if (mh->match.acl.ip_version)
- if (add) {
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_add.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_add.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_add.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_add.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_delete.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_delete.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_delete.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_delete.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
- }
- else
- if (add) {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_add.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_add.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_add.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_add.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_add.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_add.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_add.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_add.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_add.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_add.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_add.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_add.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_add.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_add.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_add.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_add.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_delete.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_delete.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_delete.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_delete.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_delete.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_delete.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_delete.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_delete.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_delete.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_delete.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_delete.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_delete.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_delete.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_delete.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_delete.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_delete.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
- }
- return 0;
-
- case TABLE_ARRAY:
- ml->array.pos = mh->match.array.pos;
- return 0;
-
- case TABLE_HASH:
- memcpy(ml->hash, mh->match.hash.key, sizeof(ml->hash));
- return 0;
-
- case TABLE_LPM:
- if (mh->match.lpm.ip_version) {
- ml->lpm_ipv4.ip = mh->match.lpm.ipv4;
- ml->lpm_ipv4.depth = mh->match.lpm.depth;
- } else {
- ml->lpm_ipv6.ip = mh->match.lpm.ipv6;
- ml->lpm_ipv6.depth = mh->match.lpm.depth;
- }
-
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data)
-{
- int status;
-
- /* Apply actions */
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_FWD,
- &action->fwd);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_LB,
- &action->lb);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_MTR,
- &action->mtr);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TM,
- &action->tm);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_ENCAP,
- &action->encap);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_NAT,
- &action->nat);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TTL,
- &action->ttl);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_STATS,
- &action->stats);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TIME,
- &action->time);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- &action->sym_crypto);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TAG,
- &action->tag);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_DECAP,
- &action->decap);
-
- if (status)
- return status;
- }
-
- return 0;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_add.match;
- struct table_rule_action *action = &req->table_rule_add.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int key_found, status;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = action_convert(a, action, data_in);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_action *action = &req->table_rule_add_default.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int status;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_default.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
-
- uint32_t table_id = req->id;
- struct table_rule_list *list = req->table_rule_add_bulk.list;
- uint32_t bulk = req->table_rule_add_bulk.bulk;
-
- uint32_t n_rules_added;
- int status;
-
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = p->table_data[table_id].a,
- .bulk_supported = bulk,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, &n_rules_added);
- if (status) {
- rsp->status = -1;
- rsp->table_rule_add_bulk.n_rules = 0;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_bulk.n_rules = n_rules_added;
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_delete.match;
- uint32_t table_id = req->id;
- int key_found, status;
-
- status = match_convert(match, &match_ll, 0);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_stats_read.data;
- int clear = req->table_rule_stats_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_stats_read(a,
- data,
- &rsp->table_rule_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id = req->table_mtr_profile_add.meter_profile_id;
- struct rte_table_action_meter_profile *profile =
- &req->table_mtr_profile_add.profile;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id =
- req->table_mtr_profile_delete.meter_profile_id;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_mtr_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_mtr_read.data;
- uint32_t tc_mask = req->table_rule_mtr_read.tc_mask;
- int clear = req->table_rule_mtr_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_read(a,
- data,
- tc_mask,
- &rsp->table_rule_mtr_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_dscp_table_update(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint64_t dscp_mask = req->table_dscp_table_update.dscp_mask;
- struct rte_table_action_dscp_table *dscp_table =
- &req->table_dscp_table_update.dscp_table;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_ttl_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_ttl_read.data;
- int clear = req->table_rule_ttl_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_ttl_read(a,
- data,
- &rsp->table_rule_ttl_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_time_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_time_read.data;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_time_read(a,
- data,
- &rsp->table_rule_time_read.timestamp);
-
- return rsp;
-}
-
-static void
-pipeline_msg_handle(struct pipeline_data *p)
-{
- for ( ; ; ) {
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
-
- req = pipeline_msg_recv(p->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case PIPELINE_REQ_PORT_IN_STATS_READ:
- rsp = pipeline_msg_handle_port_in_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_ENABLE:
- rsp = pipeline_msg_handle_port_in_enable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_DISABLE:
- rsp = pipeline_msg_handle_port_in_disable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_OUT_STATS_READ:
- rsp = pipeline_msg_handle_port_out_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_STATS_READ:
- rsp = pipeline_msg_handle_table_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD:
- rsp = pipeline_msg_handle_table_rule_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_add_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_BULK:
- rsp = pipeline_msg_handle_table_rule_add_bulk(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE:
- rsp = pipeline_msg_handle_table_rule_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_delete_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_STATS_READ:
- rsp = pipeline_msg_handle_table_rule_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_ADD:
- rsp = pipeline_msg_handle_table_mtr_profile_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE:
- rsp = pipeline_msg_handle_table_mtr_profile_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_MTR_READ:
- rsp = pipeline_msg_handle_table_rule_mtr_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE:
- rsp = pipeline_msg_handle_table_dscp_table_update(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TTL_READ:
- rsp = pipeline_msg_handle_table_rule_ttl_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TIME_READ:
- rsp = pipeline_msg_handle_table_rule_time_read(p, req);
- break;
-
- default:
- rsp = (struct pipeline_msg_rsp *) req;
- rsp->status = -1;
- }
-
- pipeline_msg_send(p->msgq_rsp, rsp);
- }
-}
-
-/**
- * Data plane threads: main
- */
-int
-thread_main(void *arg __rte_unused)
-{
- struct thread_data *t;
- uint32_t thread_id, i;
-
- thread_id = rte_lcore_id();
- t = &thread_data[thread_id];
-
- /* Dispatch loop */
- for (i = 0; ; i++) {
- uint32_t j;
-
- /* Data Plane */
- for (j = 0; j < t->n_pipelines; j++)
- rte_pipeline_run(t->p[j]);
-
- /* Control Plane */
- if ((i & 0xF) == 0) {
- uint64_t time = rte_get_tsc_cycles();
- uint64_t time_next_min = UINT64_MAX;
-
- if (time < t->time_next_min)
- continue;
-
- /* Pipeline message queues */
- for (j = 0; j < t->n_pipelines; j++) {
- struct pipeline_data *p =
- &t->pipeline_data[j];
- uint64_t time_next = p->time_next;
-
- if (time_next <= time) {
- pipeline_msg_handle(p);
- rte_pipeline_flush(p->p);
- time_next = time + p->timer_period;
- p->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- /* Thread message queues */
- {
- uint64_t time_next = t->time_next;
-
- if (time_next <= time) {
- thread_msg_handle(t);
- time_next = time + t->timer_period;
- t->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- t->time_next_min = time_next_min;
- }
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h
deleted file mode 100644
index facdf004eb..0000000000
--- a/examples/ip_pipeline/thread.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_THREAD_H_
-#define _INCLUDE_THREAD_H_
-
-#include <stdint.h>
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_init(void);
-
-int
-thread_main(void *arg);
-
-#endif /* _INCLUDE_THREAD_H_ */
diff --git a/examples/ip_pipeline/tmgr.c b/examples/ip_pipeline/tmgr.c
deleted file mode 100644
index 2432b56aee..0000000000
--- a/examples/ip_pipeline/tmgr.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_string_fns.h>
-
-#include "tmgr.h"
-
-static struct rte_sched_subport_profile_params
- subport_profile[TMGR_SUBPORT_PROFILE_MAX];
-
-static uint32_t n_subport_profiles;
-
-static struct rte_sched_pipe_params
- pipe_profile[TMGR_PIPE_PROFILE_MAX];
-
-static uint32_t n_pipe_profiles;
-
-static const struct rte_sched_subport_params subport_params_default = {
- .n_pipes_per_subport_enabled = 0, /* filled at runtime */
- .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
- .pipe_profiles = pipe_profile,
- .n_pipe_profiles = 0, /* filled at run time */
- .n_max_pipe_profiles = RTE_DIM(pipe_profile),
- .cman_params = NULL,
-};
-
-static struct tmgr_port_list tmgr_port_list;
-
-int
-tmgr_init(void)
-{
- TAILQ_INIT(&tmgr_port_list);
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_find(const char *name)
-{
- struct tmgr_port *tmgr_port;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tmgr_port, &tmgr_port_list, node)
- if (strcmp(tmgr_port->name, name) == 0)
- return tmgr_port;
-
- return NULL;
-}
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *params)
-{
- /* Check input params */
- if (params == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&subport_profile[n_subport_profiles],
- params,
- sizeof(*params));
-
- n_subport_profiles++;
-
- return 0;
-}
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p)
-{
- /* Check input params */
- if (p == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&pipe_profile[n_pipe_profiles],
- p,
- sizeof(*p));
-
- n_pipe_profiles++;
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params)
-{
- struct rte_sched_subport_params subport_params;
- struct rte_sched_port_params p;
- struct tmgr_port *tmgr_port;
- struct rte_sched_port *s;
- uint32_t i, j;
-
- /* Check input params */
- if ((name == NULL) ||
- tmgr_port_find(name) ||
- (params == NULL) ||
- (params->n_subports_per_port == 0) ||
- (params->n_pipes_per_subport == 0) ||
- (params->cpu_id >= RTE_MAX_NUMA_NODES) ||
- (n_subport_profiles == 0) ||
- (n_pipe_profiles == 0))
- return NULL;
-
- /* Resource create */
- p.name = name;
- p.socket = (int) params->cpu_id;
- p.rate = params->rate;
- p.mtu = params->mtu;
- p.frame_overhead = params->frame_overhead;
- p.n_subports_per_port = params->n_subports_per_port;
- p.n_subport_profiles = n_subport_profiles;
- p.subport_profiles = subport_profile;
- p.n_max_subport_profiles = TMGR_SUBPORT_PROFILE_MAX;
- p.n_pipes_per_subport = params->n_pipes_per_subport;
-
-
- s = rte_sched_port_config(&p);
- if (s == NULL)
- return NULL;
-
- memcpy(&subport_params, &subport_params_default,
- sizeof(subport_params_default));
-
- subport_params.n_pipe_profiles = n_pipe_profiles;
- subport_params.n_pipes_per_subport_enabled =
- params->n_pipes_per_subport;
-
- for (i = 0; i < params->n_subports_per_port; i++) {
- int status;
-
- status = rte_sched_subport_config(
- s,
- i,
- &subport_params,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- for (j = 0; j < params->n_pipes_per_subport; j++) {
-
- status = rte_sched_pipe_config(
- s,
- i,
- j,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
- }
- }
-
- /* Node allocation */
- tmgr_port = calloc(1, sizeof(struct tmgr_port));
- if (tmgr_port == NULL) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(tmgr_port->name, name, sizeof(tmgr_port->name));
- tmgr_port->s = s;
- tmgr_port->n_subports_per_port = params->n_subports_per_port;
- tmgr_port->n_pipes_per_subport = params->n_pipes_per_subport;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tmgr_port_list, tmgr_port, node);
-
- return tmgr_port;
-}
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id)
-{
- struct tmgr_port *port;
- int status;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (subport_profile_id >= n_subport_profiles))
- return -1;
-
- /* Resource config */
- status = rte_sched_subport_config(
- port->s,
- subport_id,
- NULL,
- subport_profile_id);
-
- return status;
-}
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id)
-{
- struct tmgr_port *port;
- uint32_t i;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (pipe_id_first >= port->n_pipes_per_subport) ||
- (pipe_id_last >= port->n_pipes_per_subport) ||
- (pipe_id_first > pipe_id_last) ||
- (pipe_profile_id >= n_pipe_profiles))
- return -1;
-
- /* Resource config */
- for (i = pipe_id_first; i <= pipe_id_last; i++) {
- int status;
-
- status = rte_sched_pipe_config(
- port->s,
- subport_id,
- i,
- (int) pipe_profile_id);
-
- if (status)
- return status;
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/tmgr.h b/examples/ip_pipeline/tmgr.h
deleted file mode 100644
index 1994c55bcc..0000000000
--- a/examples/ip_pipeline/tmgr.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TMGR_H_
-#define _INCLUDE_TMGR_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_sched.h>
-#include <rte_red.h>
-
-#include "common.h"
-
-#ifndef TMGR_PIPE_SUBPORT_MAX
-#define TMGR_PIPE_SUBPORT_MAX 4096
-#endif
-
-#ifndef TMGR_SUBPORT_PROFILE_MAX
-#define TMGR_SUBPORT_PROFILE_MAX 256
-#endif
-
-#ifndef TMGR_PIPE_PROFILE_MAX
-#define TMGR_PIPE_PROFILE_MAX 256
-#endif
-
-struct tmgr_port {
- TAILQ_ENTRY(tmgr_port) node;
- char name[NAME_SIZE];
- struct rte_sched_port *s;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
-};
-
-TAILQ_HEAD(tmgr_port_list, tmgr_port);
-
-int
-tmgr_init(void);
-
-struct tmgr_port *
-tmgr_port_find(const char *name);
-
-struct tmgr_port_params {
- uint64_t rate;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
- uint32_t frame_overhead;
- uint32_t mtu;
- uint32_t cpu_id;
-};
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *sp);
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p);
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params);
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id);
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id);
-
-#endif /* _INCLUDE_TMGR_H_ */
diff --git a/examples/meson.build b/examples/meson.build
index 25d9c88457..544ec5eadd 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -19,7 +19,6 @@ all_examples = [
'flow_filtering',
'helloworld',
'ip_fragmentation',
- 'ip_pipeline',
'ip_reassembly',
'ipsec-secgw',
'ipv4_multicast',
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC v2 4/6] pipeline: remove legacy API
2026-07-27 23:11 ` [RFC v2 0/6] remove legacy packet framework Stephen Hemminger
` (2 preceding siblings ...)
2026-07-27 23:11 ` [RFC v2 3/6] examples/ip_pipeline: remove example Stephen Hemminger
@ 2026-07-27 23:11 ` Stephen Hemminger
2026-07-27 23:11 ` [RFC v2 6/6] port: " Stephen Hemminger
4 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-27 23:11 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy pipeline API (rte_pipeline_*) together with the
port and table action APIs built on top of it, as announced for
removal in the 24.11 release. The SWX pipeline API remains.
The sched dependency was only used by the table action API,
so drop it.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 3 -
doc/guides/prog_guide/packet_framework.rst | 203 --
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 4 +
lib/pipeline/meson.build | 8 +-
lib/pipeline/rte_pipeline.c | 1640 ---------
lib/pipeline/rte_pipeline.h | 840 -----
lib/pipeline/rte_port_in_action.c | 539 ---
lib/pipeline/rte_port_in_action.h | 311 --
lib/pipeline/rte_table_action.c | 3483 --------------------
lib/pipeline/rte_table_action.h | 1137 -------
11 files changed, 5 insertions(+), 8168 deletions(-)
delete mode 100644 lib/pipeline/rte_pipeline.c
delete mode 100644 lib/pipeline/rte_pipeline.h
delete mode 100644 lib/pipeline/rte_port_in_action.c
delete mode 100644 lib/pipeline/rte_port_in_action.h
delete mode 100644 lib/pipeline/rte_table_action.c
delete mode 100644 lib/pipeline/rte_table_action.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 9296042119..17c15027b8 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -196,9 +196,6 @@ The public API headers are grouped by topics:
[hash](@ref rte_table_hash.h),
[array](@ref rte_table_array.h),
[stub](@ref rte_table_stub.h)
- * [pipeline](@ref rte_pipeline.h)
- [port_in_action](@ref rte_port_in_action.h)
- [table_action](@ref rte_table_action.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index ac302938dc..9eb2c5d3de 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -942,209 +942,6 @@ Additional notes:
This does not impact the performance of the key lookup operation,
as the probability of having the bucket in extended state is relatively small.
-Pipeline Library Design
------------------------
-
-A pipeline is defined by:
-
-#. The set of input ports;
-
-#. The set of output ports;
-
-#. The set of tables;
-
-#. The set of actions.
-
-The input ports are connected with the output ports through tree-like topologies of interconnected tables.
-The table entries contain the actions defining the operations to be executed on the input packets and the packet flow within the pipeline.
-
-Connectivity of Ports and Tables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To avoid any dependencies on the order in which pipeline elements are created,
-the connectivity of pipeline elements is defined after all the pipeline input ports,
-output ports and tables have been created.
-
-General connectivity rules:
-
-#. Each input port is connected to a single table. No input port should be left unconnected;
-
-#. The table connectivity to other tables or to output ports is regulated by the next hop actions of each table entry and the default table entry.
- The table connectivity is fluid, as the table entries and the default table entry can be updated during run-time.
-
- * A table can have multiple entries (including the default entry) connected to the same output port.
- A table can have different entries connected to different output ports.
- Different tables can have entries (including default table entry) connected to the same output port.
-
- * A table can have multiple entries (including the default entry) connected to another table,
- in which case all these entries have to point to the same table.
- This constraint is enforced by the API and prevents tree-like topologies from being created (allowing table chaining only),
- with the purpose of simplifying the implementation of the pipeline run-time execution engine.
-
-Port Actions
-~~~~~~~~~~~~
-
-Port Action Handler
-^^^^^^^^^^^^^^^^^^^
-
-An action handler can be assigned to each input/output port to define actions to be executed on each input packet that is received by the port.
-Defining the action handler for a specific input/output port is optional (i.e. the action handler can be disabled).
-
-For input ports, the action handler is executed after RX function. For output ports, the action handler is executed before the TX function.
-
-The action handler can decide to drop packets.
-
-Table Actions
-~~~~~~~~~~~~~
-
-Table Action Handler
-^^^^^^^^^^^^^^^^^^^^
-
-An action handler to be executed on each input packet can be assigned to each table.
-Defining the action handler for a specific table is optional (i.e. the action handler can be disabled).
-
-The action handler is executed after the table lookup operation is performed and the table entry associated with each input packet is identified.
-The action handler can only handle the user-defined actions, while the reserved actions (e.g. the next hop actions) are handled by the Packet Framework.
-The action handler can decide to drop the input packet.
-
-Reserved Actions
-^^^^^^^^^^^^^^^^
-
-The reserved actions are handled directly by the Packet Framework without the user being able to change their meaning
-through the table action handler configuration.
-A special category of the reserved actions is represented by the next hop actions, which regulate the packet flow between input ports,
-tables and output ports through the pipeline.
-:numref:`packet_framework_table_qos_33` lists the next hop actions.
-
-.. _packet_framework_table_qos_33:
-
-.. table:: Next Hop Actions (Reserved)
-
- +---+---------------------+-----------------------------------------------------------------------------------+
- | # | Next hop action | Description |
- | | | |
- +===+=====================+===================================================================================+
- | 1 | Drop | Drop the current packet. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 2 | Send to output port | Send the current packet to specified output port. The output port ID is metadata |
- | | | stored in the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 3 | Send to table | Send the current packet to specified table. The table ID is metadata stored in |
- | | | the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
-
-User Actions
-^^^^^^^^^^^^
-
-For each table, the meaning of user actions is defined through the configuration of the table action handler.
-Different tables can be configured with different action handlers, therefore the meaning of the user actions
-and their associated meta-data is private to each table.
-Within the same table, all the table entries (including the table default entry) share the same definition
-for the user actions and their associated meta-data,
-with each table entry having its own set of enabled user actions and its own copy of the action meta-data.
-:numref:`packet_framework_table_qos_34` contains a non-exhaustive list of user action examples.
-
-.. _packet_framework_table_qos_34:
-
-.. table:: User Action Examples
-
- +---+-----------------------------------+---------------------------------------------------------------------+
- | # | User action | Description |
- | | | |
- +===+===================================+=====================================================================+
- | 1 | Metering | Per flow traffic metering using the srTCM and trTCM algorithms. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 2 | Statistics | Update the statistics counters maintained per flow. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 3 | App ID | Per flow state machine fed by variable length sequence of packets |
- | | | at the flow initialization with the purpose of identifying the |
- | | | traffic type and application. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 4 | Push/pop labels | Push/pop VLAN/MPLS labels to/from the current packet. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 5 | Network Address Translation (NAT) | Translate between the internal (LAN) and external (WAN) IP |
- | | | destination/source address and/or L4 protocol destination/source |
- | | | port. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 6 | TTL update | Decrement IP TTL and, in case of IPv4 packets, update the IP |
- | | | checksum. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 7 | Sym Crypto | Generate Cryptodev session based on the user-specified algorithm |
- | | | and key(s), and assemble the cryptodev operation based on the |
- | | | predefined offsets. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
-
-Multicore Scaling
------------------
-
-A complex application is typically split across multiple cores, with cores communicating through SW queues.
-There is usually a performance limit on the number of table lookups
-and actions that can be fitted on the same CPU core due to HW constraints like:
-available CPU cycles, cache memory size, cache transfer BW, memory transfer BW, etc.
-
-As the application is split across multiple CPU cores, the Packet Framework facilitates the creation of several pipelines,
-the assignment of each such pipeline to a different CPU core
-and the interconnection of all CPU core-level pipelines into a single application-level complex pipeline.
-For example, if CPU core A is assigned to run pipeline P1 and CPU core B pipeline P2,
-then the interconnection of P1 with P2 could be achieved by having the same set of SW queues act like output ports
-for P1 and input ports for P2.
-
-This approach enables the application development using the pipeline, run-to-completion (clustered) or hybrid (mixed) models.
-
-It is allowed for the same core to run several pipelines, but it is not allowed for several cores to run the same pipeline.
-
-Shared Data Structures
-~~~~~~~~~~~~~~~~~~~~~~
-
-The threads performing table lookup are actually table writers rather than just readers.
-Even if the specific table lookup algorithm is thread-safe for multiple readers
-(e. g. read-only access of the search algorithm data structures is enough to conduct the lookup operation),
-once the table entry for the current packet is identified, the thread is typically expected to update the action meta-data stored in the table entry
-(e.g. increment the counter tracking the number of packets that hit this table entry), and thus modify the table entry.
-During the time this thread is accessing this table entry (either writing or reading; duration is application specific),
-for data consistency reasons, no other threads (threads performing table lookup or entry add/delete operations) are allowed to modify this table entry.
-
-Mechanisms to share the same table between multiple threads:
-
-#. **Multiple writer threads.**
- Threads need to use synchronization primitives like semaphores (distinct semaphore per table entry) or atomic instructions.
- The cost of semaphores is usually high, even when the semaphore is free.
- The cost of atomic instructions is normally higher than the cost of regular instructions.
-
-#. **Multiple writer threads, with single thread performing table lookup operations and multiple threads performing table entry add/delete operations.**
- The threads performing table entry add/delete operations send table update requests to the reader (typically through message passing queues),
- which does the actual table updates and then sends the response back to the request initiator.
-
-#. **Single writer thread performing table entry add/delete operations and multiple reader threads that perform table lookup operations with read-only access to the table entries.**
- The reader threads use the main table copy while the writer is updating the mirror copy.
- Once the writer update is done, the writer can signal to the readers and busy wait until all readers swap between the main copy (which now becomes the mirror copy) and
- the mirror copy (which now becomes the main copy).
-
-Interfacing with Accelerators
------------------------------
-
-The presence of accelerators is usually detected during the initialization phase by inspecting the HW devices that are part of the system (e.g. by PCI bus enumeration).
-Typical devices with acceleration capabilities are:
-
-* Inline accelerators: NICs, switches, FPGAs, etc;
-
-* Look-aside accelerators: chipsets, FPGAs, Intel QuickAssist, etc.
-
-Usually, to support a specific functional block, specific implementation of Packet Framework tables and/or ports and/or actions has to be provided for each accelerator,
-with all the implementations sharing the same API: pure SW implementation (no acceleration), implementation using accelerator A, implementation using accelerator B, etc.
-The selection between these implementations could be done at build time or at run-time (recommended), based on which accelerators are present in the system,
-with no application changes required.
-
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 6ad7698c6b..758652a492 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* 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_*)
- will gradually transition from experimental to stable status.
-
* table: The table library legacy API (functions rte_table_*)
will be deprecated and subsequently removed in DPDK 24.11 release.
Before this, the new table library API (functions rte_swx_table_*)
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index fc84ba367e..f7d34aa1ee 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -84,6 +84,10 @@ Removed Items
the legacy pipeline library API.
The ``pipeline`` example application covers the SWX pipeline API.
+* Removed the legacy pipeline library API: ``rte_pipeline_*``,
+ ``rte_port_in_action_*`` and ``rte_table_action_*`` functions.
+ The SWX pipeline API (``rte_swx_pipeline_*``) remains.
+
API Changes
-----------
diff --git a/lib/pipeline/meson.build b/lib/pipeline/meson.build
index 823c7929a7..997ded6792 100644
--- a/lib/pipeline/meson.build
+++ b/lib/pipeline/meson.build
@@ -10,21 +10,15 @@ endif
cflags += no_wvla_cflag
sources = files(
- 'rte_pipeline.c',
- 'rte_port_in_action.c',
- 'rte_table_action.c',
'rte_swx_ipsec.c',
'rte_swx_pipeline.c',
'rte_swx_pipeline_spec.c',
'rte_swx_ctl.c',
)
headers = files(
- 'rte_pipeline.h',
- 'rte_port_in_action.h',
- 'rte_table_action.h',
'rte_swx_ipsec.h',
'rte_swx_pipeline.h',
'rte_swx_extern.h',
'rte_swx_ctl.h',
)
-deps += ['port', 'table', 'meter', 'sched', 'cryptodev', 'ipsec']
+deps += ['port', 'table', 'meter', 'cryptodev', 'ipsec']
diff --git a/lib/pipeline/rte_pipeline.c b/lib/pipeline/rte_pipeline.c
deleted file mode 100644
index fa3c8b77ee..0000000000
--- a/lib/pipeline/rte_pipeline.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-
-#include "rte_pipeline.h"
-
-RTE_LOG_REGISTER_DEFAULT(pipeline_logtype, INFO);
-#define RTE_LOGTYPE_PIPELINE pipeline_logtype
-
-#define PIPELINE_LOG(level, ...) \
- RTE_LOG_LINE(level, PIPELINE, "" __VA_ARGS__)
-
-#define RTE_TABLE_INVALID UINT32_MAX
-
-#ifdef RTE_PIPELINE_STATS_COLLECT
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask) \
- __extension__ ({ (p)->n_pkts_ah_drop = rte_popcount64(mask); })
-
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter) \
- __extension__ ({ (counter) += (p)->n_pkts_ah_drop; (p)->n_pkts_ah_drop = 0; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p) \
- __extension__ ({ (p)->pkts_drop_mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter) \
-__extension__ ({ \
- uint64_t mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; \
- mask ^= (p)->pkts_drop_mask; \
- (counter) += rte_popcount64(mask); \
-})
-
-#else
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask)
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter)
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p)
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter)
-
-#endif
-
-struct rte_port_in {
- /* Input parameters */
- struct rte_port_in_ops ops;
- rte_pipeline_port_in_action_handler f_action;
- void *arg_ah;
- uint32_t burst_size;
-
- /* The table to which this port is connected */
- uint32_t table_id;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* List of enabled ports */
- struct rte_port_in *next;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_port_out {
- /* Input parameters */
- struct rte_port_out_ops ops;
- rte_pipeline_port_out_action_handler f_action;
- void *arg_ah;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_table {
- /* Input parameters */
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action_hit;
- rte_pipeline_table_action_handler_miss f_action_miss;
- void *arg_ah;
- struct rte_pipeline_table_entry *default_entry;
- uint32_t entry_size;
-
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
-
- /* Handle to the low-level table object */
- void *h_table;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
- uint64_t n_pkts_dropped_lkp_hit;
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct __rte_cache_aligned rte_pipeline {
- /* Input parameters */
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- int socket_id;
- uint32_t offset_port_id;
-
- /* Internal tables */
- struct rte_port_in ports_in[RTE_PIPELINE_PORT_IN_MAX];
- struct rte_port_out ports_out[RTE_PIPELINE_PORT_OUT_MAX];
- struct rte_table tables[RTE_PIPELINE_TABLE_MAX];
-
- /* Occupancy of internal tables */
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
-
- /* List of enabled ports */
- uint64_t enabled_port_in_mask;
- struct rte_port_in *port_in_next;
-
- /* Pipeline run structures */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_pipeline_table_entry *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t action_mask0[RTE_PIPELINE_ACTIONS];
- uint64_t action_mask1[RTE_PIPELINE_ACTIONS];
- uint64_t pkts_mask;
- uint64_t n_pkts_ah_drop;
- uint64_t pkts_drop_mask;
-};
-
-static inline uint32_t
-rte_mask_get_next(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask << ((63 - pos) & 0x3F)) |
- (mask >> ((pos + 1) & 0x3F));
- return (rte_ctz64(mask_rot) - (63 - pos)) & 0x3F;
-}
-
-static inline uint32_t
-rte_mask_get_prev(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask >> (pos & 0x3F)) |
- (mask << ((64 - pos) & 0x3F));
- return ((63 - rte_clz64(mask_rot)) + pos) & 0x3F;
-}
-
-static void
-rte_pipeline_table_free(struct rte_table *table);
-
-static void
-rte_pipeline_port_in_free(struct rte_port_in *port);
-
-static void
-rte_pipeline_port_out_free(struct rte_port_out *port);
-
-/*
- * Pipeline
- */
-static int
-rte_pipeline_check_params(struct rte_pipeline_params *params)
-{
- if (params == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter params", __func__);
- return -EINVAL;
- }
-
- /* name */
- if (params->name == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter name", __func__);
- return -EINVAL;
- }
-
- /* socket */
- if (params->socket_id < 0) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter socket_id",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_create)
-struct rte_pipeline *
-rte_pipeline_create(struct rte_pipeline_params *params)
-{
- struct rte_pipeline *p;
- int status;
-
- /* Check input parameters */
- status = rte_pipeline_check_params(params);
- if (status != 0) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline params check failed (%d)",
- __func__, status);
- return NULL;
- }
-
- /* Allocate memory for the pipeline on requested socket */
- p = rte_zmalloc_socket("PIPELINE", sizeof(struct rte_pipeline),
- RTE_CACHE_LINE_SIZE, params->socket_id);
-
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline memory allocation failed", __func__);
- return NULL;
- }
-
- /* Save input parameters */
- strlcpy(p->name, params->name, RTE_PIPELINE_MAX_NAME_SZ);
- p->socket_id = params->socket_id;
- p->offset_port_id = params->offset_port_id;
-
- /* Initialize pipeline internal data structure */
- p->num_ports_in = 0;
- p->num_ports_out = 0;
- p->num_tables = 0;
- p->enabled_port_in_mask = 0;
- p->port_in_next = NULL;
- p->pkts_mask = 0;
- p->n_pkts_ah_drop = 0;
-
- return p;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_free)
-int
-rte_pipeline_free(struct rte_pipeline *p)
-{
- uint32_t i;
-
- /* Check input parameters */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: rte_pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free input ports */
- for (i = 0; i < p->num_ports_in; i++) {
- struct rte_port_in *port = &p->ports_in[i];
-
- rte_pipeline_port_in_free(port);
- }
-
- /* Free tables */
- for (i = 0; i < p->num_tables; i++) {
- struct rte_table *table = &p->tables[i];
-
- rte_pipeline_table_free(table);
- }
-
- /* Free output ports */
- for (i = 0; i < p->num_ports_out; i++) {
- struct rte_port_out *port = &p->ports_out[i];
-
- rte_pipeline_port_out_free(port);
- }
-
- /* Free pipeline memory */
- rte_free(p);
-
- return 0;
-}
-
-/*
- * Table
- */
-static int
-rte_table_check_params(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (table_id == NULL) {
- PIPELINE_LOG(ERR, "%s: table_id parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_lookup == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_lookup function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- /* De we have room for one more table? */
- if (p->num_tables == RTE_PIPELINE_TABLE_MAX) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for num_tables parameter",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_create)
-int
-rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- struct rte_table *table;
- struct rte_pipeline_table_entry *default_entry;
- void *h_table;
- uint32_t entry_size, id;
- int status;
-
- /* Check input arguments */
- status = rte_table_check_params(p, params, table_id);
- if (status != 0)
- return status;
-
- id = p->num_tables;
- table = &p->tables[id];
-
- /* Allocate space for the default table entry */
- entry_size = sizeof(struct rte_pipeline_table_entry) +
- params->action_data_size;
- default_entry = rte_zmalloc_socket(
- "PIPELINE", entry_size, RTE_CACHE_LINE_SIZE, p->socket_id);
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Failed to allocate default entry", __func__);
- return -EINVAL;
- }
-
- /* Create the table */
- h_table = params->ops->f_create(params->arg_create, p->socket_id,
- entry_size);
- if (h_table == NULL) {
- rte_free(default_entry);
- PIPELINE_LOG(ERR, "%s: Table creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_tables++;
- *table_id = id;
-
- /* Save input parameters */
- table->ops = *params->ops;
- table->f_action_hit = params->f_action_hit;
- table->f_action_miss = params->f_action_miss;
- table->arg_ah = params->arg_ah;
- table->entry_size = entry_size;
-
- /* Clear the lookup miss actions (to be set later through API) */
- table->default_entry = default_entry;
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- /* Initialize table internal data structure */
- table->h_table = h_table;
- table->table_next_id = 0;
- table->table_next_id_valid = 0;
-
- return 0;
-}
-
-void
-rte_pipeline_table_free(struct rte_table *table)
-{
- if (table->ops.f_free != NULL)
- table->ops.f_free(table->h_table);
-
- rte_free(table->default_entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_add)
-int
-rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: default_entry parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (default_entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Set the lookup miss actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = default_entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- memcpy(table->default_entry, default_entry, table->entry_size);
-
- *default_entry_ptr = table->default_entry;
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_delete)
-int
-rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- /* Save the current contents of the default entry */
- if (entry)
- memcpy(entry, table->default_entry, table->entry_size);
-
- /* Clear the lookup miss actions */
- memset(table->default_entry, 0, table->entry_size);
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add)
-int
-rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entry == NULL) {
- PIPELINE_LOG(ERR, "%s: entry parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Add entry */
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- return (table->ops.f_add)(table->h_table, key, (void *) entry,
- key_found, (void **) entry_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete)
-int
-rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete)(table->h_table, key, key_found, entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add_bulk)
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr)
-{
- struct rte_table *table;
- uint32_t i;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: keys parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entries == NULL) {
- PIPELINE_LOG(ERR, "%s: entries parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add_bulk == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add_bulk function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entries[i]->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
- }
-
- /* Add entry */
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entries[i]->table_id;
- table->table_next_id_valid = 1;
- }
- }
-
- return (table->ops.f_add_bulk)(table->h_table, keys, (void **) entries,
- n_keys, key_found, (void **) entries_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete_bulk)
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete_bulk)(table->h_table, keys, n_keys, key_found,
- (void **) entries);
-}
-
-/*
- * Port
- */
-static int
-rte_pipeline_port_in_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_rx == NULL) {
- PIPELINE_LOG(ERR, "%s: f_rx function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- /* burst_size */
- if ((params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PIPELINE_LOG(ERR, "%s: invalid value for burst_size",
- __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_in == RTE_PIPELINE_PORT_IN_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_in", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-rte_pipeline_port_out_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx_bulk function pointer NULL", __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_out == RTE_PIPELINE_PORT_OUT_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_out", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_create)
-int
-rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- struct rte_port_in *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_in_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_in;
- port = &p->ports_in[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_in++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
- port->burst_size = params->burst_size;
-
- /* Initialize port internal data structure */
- port->table_id = RTE_TABLE_INVALID;
- port->h_port = h_port;
- port->next = NULL;
-
- return 0;
-}
-
-void
-rte_pipeline_port_in_free(struct rte_port_in *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_create)
-int
-rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- struct rte_port_out *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_out_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_out;
- port = &p->ports_out[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_out++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
-
- /* Initialize port internal data structure */
- port->h_port = h_port;
-
- return 0;
-}
-
-void
-rte_pipeline_port_out_free(struct rte_port_out *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_connect_to_table)
-int
-rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct rte_port_in *port;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: Table ID %u is out of range",
- __func__, table_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
- port->table_id = table_id;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_enable)
-int
-rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already enabled */
- port_mask = 1LLU << port_id;
- if (p->enabled_port_in_mask & port_mask)
- return 0;
-
- p->enabled_port_in_mask |= port_mask;
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port;
- port->next = port_next;
-
- /* Check if list of enabled ports was previously empty */
- if (p->enabled_port_in_mask == port_mask)
- p->port_in_next = port;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_disable)
-int
-rte_pipeline_port_in_disable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR, "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already disabled */
- port_mask = 1LLU << port_id;
- if ((p->enabled_port_in_mask & port_mask) == 0)
- return 0;
-
- p->enabled_port_in_mask &= ~port_mask;
-
- /* Return if no other enabled ports */
- if (p->enabled_port_in_mask == 0) {
- p->port_in_next = NULL;
-
- return 0;
- }
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port_next;
-
- /* Check if the port which has just been disabled is next to serve */
- if (port == p->port_in_next)
- p->port_in_next = port_next;
-
- return 0;
-}
-
-/*
- * Pipeline run-time
- */
-RTE_EXPORT_SYMBOL(rte_pipeline_check)
-int
-rte_pipeline_check(struct rte_pipeline *p)
-{
- uint32_t port_in_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* Check that pipeline has at least one input port, one table and one
- output port */
- if (p->num_ports_in == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 input port",
- __func__);
- return -EINVAL;
- }
- if (p->num_tables == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 table",
- __func__);
- return -EINVAL;
- }
- if (p->num_ports_out == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 output port",
- __func__);
- return -EINVAL;
- }
-
- /* Check that all input ports are connected */
- for (port_in_id = 0; port_in_id < p->num_ports_in; port_in_id++) {
- struct rte_port_in *port_in = &p->ports_in[port_in_id];
-
- if (port_in->table_id == RTE_TABLE_INVALID) {
- PIPELINE_LOG(ERR,
- "%s: Port IN ID %u is not connected",
- __func__, port_in_id);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static inline void
-rte_pipeline_compute_masks(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->action_mask1[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos = p->entries[i]->action;
-
- p->action_mask1[pos] |= pkt_mask;
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pos = p->entries[i]->action;
- p->action_mask1[pos] |= pkt_mask;
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_bulk(struct rte_pipeline *p,
- uint64_t pkts_mask, uint32_t port_id)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- p->pkts_mask = pkts_mask;
-
- /* Output port user actions */
- if (port_out->f_action != NULL) {
- port_out->f_action(p, p->pkts, pkts_mask, port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
- }
-
- /* Output port TX */
- if (p->pkts_mask != 0)
- port_out->ops.f_tx_bulk(port_out->h_port,
- p->pkts,
- p->pkts_mask);
-}
-
-static inline void
-rte_pipeline_action_handler_port(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id = p->entries[i]->port_id;
- struct rte_port_out *port_out =
- &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = p->entries[i]->port_id;
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_meta(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id =
- RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- struct rte_port_out *port_out = &p->ports_out[
- port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_drop(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- rte_pktmbuf_free(p->pkts[i]);
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- rte_pktmbuf_free(p->pkts[i]);
- }
- }
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_run)
-int
-rte_pipeline_run(struct rte_pipeline *p)
-{
- struct rte_port_in *port_in = p->port_in_next;
- uint32_t n_pkts, table_id;
-
- if (port_in == NULL)
- return 0;
-
- /* Input port RX */
- n_pkts = port_in->ops.f_rx(port_in->h_port, p->pkts,
- port_in->burst_size);
- if (n_pkts == 0) {
- p->port_in_next = port_in->next;
- return 0;
- }
-
- p->pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- /* Input port user actions */
- if (port_in->f_action != NULL) {
- port_in->f_action(p, p->pkts, n_pkts, port_in->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_in->n_pkts_dropped_by_ah);
- }
-
- /* Table */
- for (table_id = port_in->table_id; p->pkts_mask != 0; ) {
- struct rte_table *table;
- uint64_t lookup_hit_mask, lookup_miss_mask;
-
- /* Lookup */
- table = &p->tables[table_id];
- table->ops.f_lookup(table->h_table, p->pkts, p->pkts_mask,
- &lookup_hit_mask, (void **) p->entries);
- lookup_miss_mask = p->pkts_mask & (~lookup_hit_mask);
-
- /* Lookup miss */
- if (lookup_miss_mask != 0) {
- struct rte_pipeline_table_entry *default_entry =
- table->default_entry;
-
- p->pkts_mask = lookup_miss_mask;
-
- /* Table user actions */
- if (table->f_action_miss != NULL) {
- table->f_action_miss(p,
- p->pkts,
- lookup_miss_mask,
- default_entry,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_miss_ah);
- }
-
- /* Table reserved actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_PORT) &&
- (p->pkts_mask != 0))
- rte_pipeline_action_handler_port_bulk(p,
- p->pkts_mask,
- default_entry->port_id);
- else {
- uint32_t pos = default_entry->action;
-
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
-
- p->action_mask0[pos] |= p->pkts_mask;
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_miss);
- }
- }
-
- /* Lookup hit */
- if (lookup_hit_mask != 0) {
- p->pkts_mask = lookup_hit_mask;
-
- /* Table user actions */
- if (table->f_action_hit != NULL) {
- table->f_action_hit(p,
- p->pkts,
- lookup_hit_mask,
- p->entries,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_hit_ah);
- }
-
- /* Table reserved actions */
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
- rte_pipeline_compute_masks(p, p->pkts_mask);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_DROP];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT_META];
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_TABLE];
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_hit);
- }
-
- /* Prepare for next iteration */
- p->pkts_mask = p->action_mask0[RTE_PIPELINE_ACTION_TABLE];
- table_id = table->table_next_id;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
- }
-
- /* Table reserved action PORT */
- rte_pipeline_action_handler_port(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT]);
-
- /* Table reserved action PORT META */
- rte_pipeline_action_handler_port_meta(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
-
- /* Table reserved action DROP */
- rte_pipeline_action_handler_drop(p,
- p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
-
- /* Pick candidate for next port IN to serve */
- p->port_in_next = port_in->next;
-
- return (int) n_pkts;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_flush)
-int
-rte_pipeline_flush(struct rte_pipeline *p)
-{
- uint32_t port_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- for (port_id = 0; port_id < p->num_ports_out; port_id++) {
- struct rte_port_out *port = &p->ports_out[port_id];
-
- if (port->ops.f_flush != NULL)
- port->ops.f_flush(port->h_port);
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_packet_insert)
-int
-rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id, struct rte_mbuf *pkt)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- port_out->ops.f_tx(port_out->h_port, pkt); /* Output port TX */
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_hijack)
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_drop)
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
-
- RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_stats_read)
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear)
-{
- struct rte_port_in *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_stats_read)
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear)
-{
- struct rte_port_out *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_out) {
- PIPELINE_LOG(ERR,
- "%s: port OUT ID %u is out of range", __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_out[port_id];
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_stats_read)
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear)
-{
- struct rte_table *table;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table %u is out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
- if (table->ops.f_stats != NULL) {
- retval = table->ops.f_stats(table->h_table, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL) {
- stats->n_pkts_dropped_by_lkp_hit_ah =
- table->n_pkts_dropped_by_lkp_hit_ah;
- stats->n_pkts_dropped_by_lkp_miss_ah =
- table->n_pkts_dropped_by_lkp_miss_ah;
- stats->n_pkts_dropped_lkp_hit = table->n_pkts_dropped_lkp_hit;
- stats->n_pkts_dropped_lkp_miss = table->n_pkts_dropped_lkp_miss;
- }
-
- if (clear != 0) {
- table->n_pkts_dropped_by_lkp_hit_ah = 0;
- table->n_pkts_dropped_by_lkp_miss_ah = 0;
- table->n_pkts_dropped_lkp_hit = 0;
- table->n_pkts_dropped_lkp_miss = 0;
- }
-
- return 0;
-}
diff --git a/lib/pipeline/rte_pipeline.h b/lib/pipeline/rte_pipeline.h
deleted file mode 100644
index c9e7172453..0000000000
--- a/lib/pipeline/rte_pipeline.h
+++ /dev/null
@@ -1,840 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PIPELINE_H__
-#define __INCLUDE_RTE_PIPELINE_H__
-
-/**
- * @file
- * RTE Pipeline
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard methodology (logically similar to OpenFlow) for rapid development
- * of complex packet processing pipelines out of ports, tables and actions.
- *
- * <B>Basic operation.</B> A pipeline is constructed by connecting its input
- * ports to its output ports through a chain of lookup tables. As result of
- * lookup operation into the current table, one of the table entries (or the
- * default table entry, in case of lookup miss) is identified to provide the
- * actions to be executed on the current packet and the associated action
- * meta-data. The behavior of user actions is defined through the configurable
- * table action handler, while the reserved actions define the next hop for the
- * current packet (either another table, an output port or packet drop) and are
- * handled transparently by the framework.
- *
- * <B>Initialization and run-time flows.</B> Once all the pipeline elements
- * (input ports, tables, output ports) have been created, input ports connected
- * to tables, table action handlers configured, tables populated with the
- * initial set of entries (actions and action meta-data) and input ports
- * enabled, the pipeline runs automatically, pushing packets from input ports
- * to tables and output ports. At each table, the identified user actions are
- * being executed, resulting in action meta-data (stored in the table entry)
- * and packet meta-data (stored with the packet descriptor) being updated. The
- * pipeline tables can have further updates and input ports can be disabled or
- * enabled later on as required.
- *
- * <B>Multi-core scaling.</B> Typically, each CPU core will run its own
- * pipeline instance. Complex application-level pipelines can be implemented by
- * interconnecting multiple CPU core-level pipelines in tree-like topologies,
- * as the same port devices (e.g. SW rings) can serve as output ports for the
- * pipeline running on CPU core A, as well as input ports for the pipeline
- * running on CPU core B. This approach enables the application development
- * using the pipeline (CPU cores connected serially), cluster/run-to-completion
- * (CPU cores connected in parallel) or mixed (pipeline of CPU core clusters)
- * programming models.
- *
- * <B>Thread safety.</B> It is possible to have multiple pipelines running on
- * the same CPU core, but it is not allowed (for thread safety reasons) to have
- * multiple CPU cores running the same pipeline instance.
- */
-
-#include <stdint.h>
-
-#include <rte_port.h>
-#include <rte_table.h>
-#include <rte_common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_mbuf;
-
-/*
- * Pipeline
- */
-/** Opaque data type for pipeline */
-struct rte_pipeline;
-
-/** Parameters for pipeline creation */
-struct rte_pipeline_params {
- /** Pipeline name */
- const char *name;
-
- /** CPU socket ID where memory for the pipeline and its elements (ports
- and tables) should be allocated */
- int socket_id;
-
- /** Offset within packet meta-data to port_id to be used by action
- "Send packet to output port read from packet meta-data". Has to be
- 4-byte aligned. */
- uint32_t offset_port_id;
-};
-
-/** Pipeline port in stats. */
-struct rte_pipeline_port_in_stats {
- /** Port in stats. */
- struct rte_port_in_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-
-};
-
-/** Pipeline port out stats. */
-struct rte_pipeline_port_out_stats {
- /** Port out stats. */
- struct rte_port_out_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-/** Pipeline table stats. */
-struct rte_pipeline_table_stats {
- /** Table stats. */
- struct rte_table_stats stats;
-
- /** Number of packets dropped by lookup hit action handler. */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
-
- /** Number of packets dropped by lookup miss action handler. */
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_hit;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-/**
- * Pipeline create
- *
- * @param params
- * Parameters for pipeline creation
- * @return
- * Handle to pipeline instance on success or NULL otherwise
- */
-struct rte_pipeline *rte_pipeline_create(struct rte_pipeline_params *params);
-
-/**
- * Pipeline free
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_free(struct rte_pipeline *p);
-
-/**
- * Pipeline consistency check
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_check(struct rte_pipeline *p);
-
-/**
- * Pipeline run
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * Number of packets read and processed
- */
-int rte_pipeline_run(struct rte_pipeline *p);
-
-/**
- * Pipeline flush
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_flush(struct rte_pipeline *p);
-
-/*
- * Actions
- */
-/** Reserved actions */
-enum rte_pipeline_action {
- /** Drop the packet */
- RTE_PIPELINE_ACTION_DROP = 0,
-
- /** Send packet to output port */
- RTE_PIPELINE_ACTION_PORT,
-
- /** Send packet to output port read from packet meta-data */
- RTE_PIPELINE_ACTION_PORT_META,
-
- /** Send packet to table */
- RTE_PIPELINE_ACTION_TABLE,
-
- /** Number of reserved actions */
- RTE_PIPELINE_ACTIONS
-};
-
-/*
- * Table
- */
-/** Maximum number of tables allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_TABLE_MAX 64
-
-/**
- * Head format for the table entry of any pipeline table. For any given
- * pipeline table, all table entries should have the same size and format. For
- * any given pipeline table, the table entry has to start with a head of this
- * structure, which contains the reserved actions and their associated
- * meta-data, and then optionally continues with user actions and their
- * associated meta-data. As all the currently defined reserved actions are
- * mutually exclusive, only one reserved action can be set per table entry.
- */
-struct rte_pipeline_table_entry {
- /** Reserved action */
- enum rte_pipeline_action action;
-
- union {
- /** Output port ID (meta-data for "Send packet to output port"
- action) */
- uint32_t port_id;
- /** Table ID (meta-data for "Send packet to table" action) */
- uint32_t table_id;
- };
- /** Start of table entry area for user defined actions and meta-data */
- uint8_t action_data[];
-};
-
-/**
- * Pipeline table action handler on lookup hit
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet and element n of entries array is pointing to a valid table
- * entry associated with the packet, with the association typically done by
- * the table lookup operation. Otherwise, element n of pkts array and element
- * n of entries array will not be accessed.
- * @param entries
- * Set of table entries specified as array of up to 64 pointers to struct
- * rte_pipeline_table_entry
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_hit)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg);
-
-/**
- * Pipeline table action handler on lookup miss
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param entry
- * Single table entry associated with all the valid packets from the input
- * burst, specified as pointer to struct rte_pipeline_table_entry.
- * This entry is the pipeline table default entry that is associated by the
- * table lookup operation with the input packets that have resulted in lookup
- * miss.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_miss)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry *entry,
- void *arg);
-
-/** Parameters for pipeline table creation. Action handlers have to be either
- both enabled or both disabled (they can be disabled by setting them to
- NULL). */
-struct rte_pipeline_table_params {
- /** Table operations (specific to each table type) */
- struct rte_table_ops *ops;
- /** Opaque param to be passed to the table create operation when
- invoked */
- void *arg_create;
- /** Callback function to execute the user actions on input packets in
- case of lookup hit */
- rte_pipeline_table_action_handler_hit f_action_hit;
- /** Callback function to execute the user actions on input packets in
- case of lookup miss */
- rte_pipeline_table_action_handler_miss f_action_miss;
-
- /** Opaque parameter to be passed to lookup hit and/or lookup miss
- action handlers when invoked */
- void *arg_ah;
- /** Memory size to be reserved per table entry for storing the user
- actions and their meta-data */
- uint32_t action_data_size;
-};
-
-/**
- * Pipeline table create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline table creation
- * @param table_id
- * Table ID. Valid only within the scope of table IDs of the current
- * pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id);
-
-/**
- * Pipeline table default entry add
- *
- * The contents of the table default entry is updated with the provided actions
- * and meta-data. When the default entry is not configured (by using this
- * function), the built-in default entry has the action "Drop" and meta-data
- * set to all-zeros.
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param default_entry
- * New contents for the table default entry
- * @param default_entry_ptr
- * On successful invocation, pointer to the default table entry which can be
- * used for further read-write accesses to this table entry. This pointer
- * is valid until the default entry is deleted or re-added.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr);
-
-/**
- * Pipeline table default entry delete
- *
- * The new contents of the table default entry is set to reserved action "Drop
- * the packet" with meta-data cleared (i.e. set to all-zeros).
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param entry
- * On successful invocation, when entry points to a valid buffer, the
- * previous contents of the table default entry (as it was just before the
- * delete operation) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param entry
- * New contents for the table entry identified by key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * already present in the table before the add operation and to FALSE (value
- * 0) if not
- * @param entry_ptr
- * On successful invocation, pointer to the table entry associated with key.
- * This can be used for further read-write accesses to this table entry and
- * is valid until the key is deleted from the table or re-added (usually for
- * associating different actions and/or action meta-data to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr);
-
-/**
- * Pipeline table entry delete
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * found in the table before the delete operation and to FALSE (value 0) if
- * not
- * @param entry
- * On successful invocation, when key is found in the table and entry points
- * to a valid buffer, the table entry contents (as it was before the delete
- * was performed) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param entries
- * Array containing new contents for every table entry identified by key
- * @param n_keys
- * Number of keys to add
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was already present in the table
- * before the add operation and to FALSE (value 0) if not
- * @param entries_ptr
- * On successful invocation, array *entries_ptr stores pointer to every table
- * entry associated with key. This can be used for further read-write accesses
- * to this table entry and is valid until the key is deleted from the table or
- * re-added (usually for associating different actions and/or action meta-data
- * to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr);
-
-/**
- * Pipeline table entry delete bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param n_keys
- * Number of keys to delete
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was found in the table before the
- * delete operation and to FALSE (value 0) if not
- * @param entries
- * If entries pointer is NULL, this pointer is ignored for every entry found.
- * Else, after successful invocation, if specific key is found in the table
- * and entry points to a valid buffer, the table entry contents (as it was
- * before the delete was performed) is copied to this buffer.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries);
-
-/**
- * Read pipeline table stats.
- *
- * This function reads table statistics identified by *table_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param table_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear);
-
-/*
- * Port IN
- */
-/** Maximum number of input ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_IN_MAX 64
-
-/**
- * Pipeline input port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param n
- * Number of packets in the input burst. This parameter specifies that
- * elements 0 to (n-1) of pkts array are valid.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_in_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n,
- void *arg);
-
-/** Parameters for pipeline input port creation */
-struct rte_pipeline_port_in_params {
- /** Input port operations (specific to each table type) */
- struct rte_port_in_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function to execute the user actions on input packets.
- Disabled if set to NULL. */
- rte_pipeline_port_in_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-
- /** Recommended burst size for the RX operation(in number of pkts) */
- uint32_t burst_size;
-};
-
-/**
- * Pipeline input port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline input port creation
- * @param port_id
- * Input port ID. Valid only within the scope of input port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id);
-
-/**
- * Pipeline input port connect to table
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id);
-
-/**
- * Pipeline input port enable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_enable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Pipeline input port disable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_disable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Read pipeline port in stats.
- *
- * This function reads port in statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear);
-
-/*
- * Port OUT
- */
-/** Maximum number of output ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_OUT_MAX 64
-
-/**
- * Pipeline output port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_out_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- void *arg);
-
-/** Parameters for pipeline output port creation. The action handlers have to
-be either both enabled or both disabled (by setting them to NULL). When
-enabled, the pipeline selects between them at different moments, based on the
-number of packets that have to be sent to the same output port. */
-struct rte_pipeline_port_out_params {
- /** Output port operations (specific to each table type) */
- struct rte_port_out_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function executing the user actions on bust of input
- packets */
- rte_pipeline_port_out_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-};
-
-/**
- * Pipeline output port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline output port creation
- * @param port_id
- * Output port ID. Valid only within the scope of output port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id);
-
-/**
- * Read pipeline port out stats.
- *
- * This function reads port out statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear);
-
-/*
- * Functions to be called as part of the port IN/OUT or table action handlers
- */
-/**
- * Action handler packet insert to output port
- *
- * This function can be called by any input/output port or table action handler
- * to send a packet out through one of the pipeline output ports. This packet is
- * generated by the action handler, i.e. this packet is not part of the burst of
- * packets read from one of the pipeline input ports and currently processed by
- * the pipeline (this packet is not an element of the pkts array input parameter
- * of the action handler).
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Output port ID (returned by previous invocation of pipeline output port
- * create) to send the packet specified by pkt
- * @param pkt
- * New packet generated by the action handler
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id,
- struct rte_mbuf *pkt);
-
-#define rte_pipeline_ah_port_out_packet_insert \
- rte_pipeline_port_out_packet_insert
-
-/**
- * Action handler packet hijack
- *
- * This function can be called by any input/output port or table action handler
- * to hijack selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The hijacked
- * packets are removed from any further pipeline processing, with the action
- * handler now having the full ownership for these packets.
- *
- * The action handler can further send the hijacked packets out through any
- * pipeline output port by calling the rte_pipeline_ah_port_out_packet_insert()
- * function. The action handler can also drop these packets by calling the
- * rte_pktmbuf_free() function, although a better alternative is provided by
- * the action handler using the rte_pipeline_ah_packet_drop() function.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be hijacked by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is hijacked.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-/**
- * Action handler packet drop
- *
- * This function is called by the pipeline action handlers (port in/out, table)
- * to drop the packets selected using packet mask.
- *
- * This function can be called by any input/output port or table action handler
- * to drop selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The dropped
- * packets are removed from any further pipeline processing and the packet
- * buffers are eventually freed to their buffer pool.
- *
- * This function updates the drop statistics counters correctly, therefore the
- * recommended approach for dropping packets by the action handlers is to call
- * this function as opposed to the action handler hijacking the packets first
- * and then dropping them invisibly to the pipeline (by using the
- * rte_pktmbuf_free() function).
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be dropped by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is dropped.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/pipeline/rte_port_in_action.c b/lib/pipeline/rte_port_in_action.c
deleted file mode 100644
index 2378e64de9..0000000000
--- a/lib/pipeline/rte_port_in_action.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_in_action.h"
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-static int
-fltr_cfg_check(struct rte_port_in_action_fltr_config *cfg)
-{
- if (cfg == NULL)
- return -1;
-
- return 0;
-}
-
-struct fltr_data {
- uint32_t port_id;
-};
-
-static void
-fltr_init(struct fltr_data *data,
- struct rte_port_in_action_fltr_config *cfg)
-{
- data->port_id = cfg->port_id;
-}
-
-static int
-fltr_apply(struct fltr_data *data,
- struct rte_port_in_action_fltr_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- data->port_id = p->port_id;
-
- return 0;
-}
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_port_in_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct lb_data {
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-static void
-lb_init(struct lb_data *data,
- struct rte_port_in_action_lb_config *cfg)
-{
- memcpy(data->port_id, cfg->port_id, sizeof(cfg->port_id));
-}
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_port_in_action_lb_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- memcpy(data->port_id, p->port_id, sizeof(p->port_id));
-
- return 0;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- case RTE_PORT_IN_ACTION_LB:
- return 1;
- default:
- return 0;
- }
-}
-
-#define RTE_PORT_IN_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-static size_t
-action_cfg_size(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct rte_port_in_action_fltr_config);
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct rte_port_in_action_lb_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_port_in_action_type type)
-{
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return &ap_config->fltr;
-
- case RTE_PORT_IN_ACTION_LB:
- return &ap_config->lb;
-
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_port_in_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_PORT_IN_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_port_in_action_type action,
- struct ap_config *ap_config __rte_unused)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct fltr_data);
-
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct lb_data);
-
- default:
- return 0;
- }
-}
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_PORT_IN_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_port_in_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_port_in_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_create, 18.05)
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id)
-{
- struct rte_port_in_action_profile *ap;
-
- /* Memory allocation */
- ap = rte_zmalloc_socket(NULL,
- sizeof(struct rte_port_in_action_profile),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (ap == NULL)
- return NULL;
-
- return ap;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_action_register, 18.05)
-int
-rte_port_in_action_profile_action_register(struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- status = fltr_cfg_check(action_config);
- break;
-
- case RTE_PORT_IN_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_freeze, 18.05)
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_free, 18.05)
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-struct rte_port_in_action {
- struct ap_config cfg;
- struct ap_data data;
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static __rte_always_inline void *
-action_data_get(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- size_t offset = action->data.offset[type];
-
- return &action->memory[offset];
-}
-
-static void
-action_data_init(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- void *data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- fltr_init(data, &action->cfg.fltr);
- return;
-
- case RTE_PORT_IN_ACTION_LB:
- lb_init(data, &action->cfg.lb);
- return;
-
- default:
- return;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_create, 18.05)
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_port_in_action *action;
- size_t size;
- uint32_t i;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- size = sizeof(struct rte_port_in_action) + profile->data.total_size;
- size = RTE_CACHE_LINE_ROUNDUP(size);
-
- action = rte_zmalloc_socket(NULL,
- size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- for (i = 0; i < RTE_PORT_IN_ACTION_MAX; i++)
- if (action->cfg.action_mask & (1LLU << i))
- action_data_init(action,
- (enum rte_port_in_action_type)i);
-
- return action;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_apply, 18.05)
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return fltr_apply(action_data,
- action_params);
-
- case RTE_PORT_IN_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-ah_filter_on_match(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or == 0) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_filter_on_mismatch(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_lb(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_lb_config *cfg = &action->cfg.lb;
- struct lb_data *data = action_data_get(action, RTE_PORT_IN_ACTION_LB);
- uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- uint32_t i;
-
- rte_pipeline_ah_packet_hijack(p, pkt_mask);
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(pkt,
- cfg->key_offset);
-
- uint64_t digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- uint64_t pos = digest & (RTE_PORT_IN_ACTION_LB_TABLE_SIZE - 1);
- uint32_t port_id = data->port_id[pos];
-
- rte_pipeline_port_out_packet_insert(p, port_id, pkt);
- }
-
- return 0;
-}
-
-static rte_pipeline_port_in_action_handler
-ah_selector(struct rte_port_in_action *action)
-{
- if (action->cfg.action_mask == 0)
- return NULL;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_FLTR)
- return (action->cfg.fltr.filter_on_match) ?
- ah_filter_on_match : ah_filter_on_mismatch;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_LB)
- return ah_lb;
-
- return NULL;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_params_get, 18.05)
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params)
-{
- rte_pipeline_port_in_action_handler f_action;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action = ah_selector(action);
-
- /* Fill in params */
- params->f_action = f_action;
- params->arg_ah = (f_action) ? action : NULL;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_free, 18.05)
-int
-rte_port_in_action_free(struct rte_port_in_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_port_in_action.h b/lib/pipeline/rte_port_in_action.h
deleted file mode 100644
index 9d17bae988..0000000000
--- a/lib/pipeline/rte_port_in_action.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IN_ACTION_H__
-#define __INCLUDE_RTE_PORT_IN_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Input Port Actions
- *
- * This API provides a common set of actions for pipeline input ports to speed
- * up application development.
- *
- * Each pipeline input port can be assigned an action handler to be executed
- * on every input packet during the pipeline execution. The pipeline library
- * allows the user to define his own input port actions by providing customized
- * input port action handler. While the user can still follow this process, this
- * API is intended to provide a quicker development alternative for a set of
- * predefined actions.
- *
- * The typical steps to use this API are:
- * - Define an input port action profile. This is a configuration template that
- * can potentially be shared by multiple input ports from the same or
- * different pipelines, with different input ports from the same pipeline
- * able to use different action profiles. For every input port using a given
- * action profile, the profile defines the set of actions and the action
- * configuration to be executed by the input port. API functions:
- * rte_port_in_action_profile_create(),
- * rte_port_in_action_profile_action_register(),
- * rte_port_in_action_profile_freeze().
- *
- * - Instantiate the input port action profile to create input port action
- * objects. Each pipeline input port has its own action object.
- * API functions: rte_port_in_action_create().
- *
- * - Use the input port action object to generate the input port action handler
- * invoked by the pipeline. API functions:
- * rte_port_in_action_params_get().
- *
- * - Use the input port action object to generate the internal data structures
- * used by the input port action handler based on given action parameters.
- * API functions: rte_port_in_action_apply().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Input port actions. */
-enum rte_port_in_action_type {
- /** Filter selected input packets. */
- RTE_PORT_IN_ACTION_FLTR = 0,
-
- /** Load balance. */
- RTE_PORT_IN_ACTION_LB,
-};
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-/** Filter key size (number of bytes) */
-#define RTE_PORT_IN_ACTION_FLTR_KEY_SIZE 16
-
-/** Filter action configuration (per action profile). */
-struct rte_port_in_action_fltr_config {
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask. */
- uint8_t key_mask[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** Key value. */
- uint8_t key[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** When non-zero, all the input packets that match the *key* (with the
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- * When zero, all the input packets that do NOT match the *key* (with
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- */
- int filter_on_match;
-
- /** Pipeline output port ID to send the filtered input packets to.
- * Can be updated later.
- *
- * @see struct rte_port_in_action_fltr_params
- */
- uint32_t port_id;
-};
-
-/** Filter action parameters (per action). */
-struct rte_port_in_action_fltr_params {
- /** Pipeline output port ID to send the filtered input packets to. */
- uint32_t port_id;
-};
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_PORT_IN_ACTION_LB_TABLE_SIZE 16
-
-/** Load balance action configuration (per action profile). */
-struct rte_port_in_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask(*key_size* bytes are valid). */
- uint8_t key_mask[RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table. Can be updated later.
- *
- * @see struct rte_port_in_action_lb_params
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/** Load balance action parameters (per action). */
-struct rte_port_in_action_lb_params {
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table.
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * Input port action profile.
- */
-struct rte_port_in_action_profile;
-
-/**
- * Input port action profile create.
- *
- * @param[in] socket_id
- * CPU socket ID for the internal data structures memory allocation.
- * @return
- * Input port action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id);
-
-/**
- * Input port action profile free.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid).
- * If profile is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action profile action register.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid and not in frozen
- * state).
- * @param[in] type
- * Specific input port action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_port_in_action_*type*_config is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_action_register(
- struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config);
-
-/**
- * Input port action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * input port action objects.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and not in frozen
- * state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_port_in_action_create()
- */
-__rte_experimental
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action.
- */
-struct rte_port_in_action;
-
-/**
- * Input port action create.
- *
- * Instantiates the given input port action profile to create an input port
- * action object.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new input
- * port action object should be allocated.
- * @return
- * Handle to input port action object on success, NULL on error.
- */
-__rte_experimental
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Input port action free.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * If action is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_free(struct rte_port_in_action *action);
-
-/**
- * Input port params get.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[inout] params
- * Pipeline input port parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params);
-
-/**
- * Input port action apply.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[in] type
- * Specific input port action previously registered for the input port action
- * profile of the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_port_in_action_*type*_params is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_PORT_IN_ACTION_H__ */
diff --git a/lib/pipeline/rte_table_action.c b/lib/pipeline/rte_table_action.c
deleted file mode 100644
index c990d7eb56..0000000000
--- a/lib/pipeline/rte_table_action.c
+++ /dev/null
@@ -1,3483 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_cycles.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_udp.h>
-#include <rte_vxlan.h>
-#include <rte_cryptodev.h>
-
-#include "rte_table_action.h"
-
-#define rte_htons rte_cpu_to_be_16
-#define rte_htonl rte_cpu_to_be_32
-
-#define rte_ntohs rte_be_to_cpu_16
-#define rte_ntohl rte_be_to_cpu_32
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-#define fwd_data rte_pipeline_table_entry
-
-static int
-fwd_apply(struct fwd_data *data,
- struct rte_table_action_fwd_params *p)
-{
- data->action = p->action;
-
- if (p->action == RTE_PIPELINE_ACTION_PORT)
- data->port_id = p->id;
-
- if (p->action == RTE_PIPELINE_ACTION_TABLE)
- data->table_id = p->id;
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_table_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_TABLE_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_TABLE_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct __rte_packed_begin lb_data {
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-} __rte_packed_end;
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_table_action_lb_params *p)
-{
- memcpy(data->out, p->out, sizeof(data->out));
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_lb(struct rte_mbuf *mbuf,
- struct lb_data *data,
- struct rte_table_action_lb_config *cfg)
-{
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->key_offset);
- uint32_t *out = RTE_MBUF_METADATA_UINT32_PTR(mbuf, cfg->out_offset);
- uint64_t digest, pos;
- uint32_t out_val;
-
- digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- pos = digest & (RTE_TABLE_ACTION_LB_TABLE_SIZE - 1);
- out_val = data->out[pos];
-
- *out = out_val;
-}
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-static int
-mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
-{
- if ((mtr->alg == RTE_TABLE_ACTION_METER_SRTCM) ||
- ((mtr->n_tc != 1) && (mtr->n_tc != 4)) ||
- (mtr->n_bytes_enabled != 0))
- return -ENOTSUP;
- return 0;
-}
-
-struct mtr_trtcm_data {
- struct rte_meter_trtcm trtcm;
- uint64_t stats[RTE_COLORS];
-};
-
-#define MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data) \
- (((data)->stats[RTE_COLOR_GREEN] & 0xF8LLU) >> 3)
-
-static void
-mtr_trtcm_data_meter_profile_id_set(struct mtr_trtcm_data *data,
- uint32_t profile_id)
-{
- data->stats[RTE_COLOR_GREEN] &= ~0xF8LLU;
- data->stats[RTE_COLOR_GREEN] |= (profile_id % 32) << 3;
-}
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color)\
- (((data)->stats[(color)] & 4LLU) >> 2)
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color)\
- ((enum rte_color)((data)->stats[(color)] & 3LLU))
-
-static void
-mtr_trtcm_data_policer_action_set(struct mtr_trtcm_data *data,
- enum rte_color color,
- enum rte_table_action_policer action)
-{
- if (action == RTE_TABLE_ACTION_POLICER_DROP) {
- data->stats[color] |= 4LLU;
- } else {
- data->stats[color] &= ~7LLU;
- data->stats[color] |= color & 3LLU;
- }
-}
-
-static uint64_t
-mtr_trtcm_data_stats_get(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- return data->stats[color] >> 8;
-}
-
-static void
-mtr_trtcm_data_stats_reset(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- data->stats[color] &= 0xFFLU;
-}
-
-#define MTR_TRTCM_DATA_STATS_INC(data, color) \
- ((data)->stats[(color)] += (1LLU << 8))
-
-static size_t
-mtr_data_size(struct rte_table_action_mtr_config *mtr)
-{
- return mtr->n_tc * sizeof(struct mtr_trtcm_data);
-}
-
-struct dscp_table_entry_data {
- enum rte_color color;
- uint16_t tc;
- uint16_t tc_queue;
-};
-
-struct dscp_table_data {
- struct dscp_table_entry_data entry[64];
-};
-
-struct meter_profile_data {
- struct rte_meter_trtcm_profile profile;
- uint32_t profile_id;
- int valid;
-};
-
-static struct meter_profile_data *
-meter_profile_data_find(struct meter_profile_data *mp,
- uint32_t mp_size,
- uint32_t profile_id)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (mp_data->valid && (mp_data->profile_id == profile_id))
- return mp_data;
- }
-
- return NULL;
-}
-
-static struct meter_profile_data *
-meter_profile_data_find_unused(struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (!mp_data->valid)
- return mp_data;
- }
-
- return NULL;
-}
-
-static int
-mtr_apply_check(struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- if (p->tc_mask > RTE_LEN2MASK(cfg->n_tc, uint32_t))
- return -EINVAL;
-
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-mtr_apply(struct mtr_trtcm_data *data,
- struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
- int status;
-
- /* Check input arguments */
- status = mtr_apply_check(p, cfg, mp, mp_size);
- if (status)
- return status;
-
- /* Apply */
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct mtr_trtcm_data *data_tc = &data[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- /* Find profile */
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
-
- memset(data_tc, 0, sizeof(*data_tc));
-
- /* Meter object */
- status = rte_meter_trtcm_config(&data_tc->trtcm,
- &mp_data->profile);
- if (status)
- return status;
-
- /* Meter profile */
- mtr_trtcm_data_meter_profile_id_set(data_tc,
- mp_data - mp);
-
- /* Policer actions */
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_GREEN,
- p_tc->policer[RTE_COLOR_GREEN]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_YELLOW,
- p_tc->policer[RTE_COLOR_YELLOW]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_RED,
- p_tc->policer[RTE_COLOR_RED]);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_mtr(struct rte_mbuf *mbuf,
- struct mtr_trtcm_data *data,
- struct dscp_table_data *dscp_table,
- struct meter_profile_data *mp,
- uint64_t time,
- uint32_t dscp,
- uint16_t total_length)
-{
- uint64_t drop_mask;
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- enum rte_color color_in, color_meter, color_policer;
- uint32_t tc, mp_id;
-
- tc = dscp_entry->tc;
- color_in = dscp_entry->color;
- data += tc;
- mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
-
- /* Meter */
- color_meter = rte_meter_trtcm_color_aware_check(
- &data->trtcm,
- &mp[mp_id].profile,
- time,
- total_length,
- color_in);
-
- /* Stats */
- MTR_TRTCM_DATA_STATS_INC(data, color_meter);
-
- /* Police */
- drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
- color_policer =
- MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- rte_mbuf_sched_color_set(mbuf, (uint8_t)color_policer);
-
- return drop_mask;
-}
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-static int
-tm_cfg_check(struct rte_table_action_tm_config *tm)
-{
- if ((tm->n_subports_per_port == 0) ||
- (rte_is_power_of_2(tm->n_subports_per_port) == 0) ||
- (tm->n_subports_per_port > UINT16_MAX) ||
- (tm->n_pipes_per_subport == 0) ||
- (rte_is_power_of_2(tm->n_pipes_per_subport) == 0))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin tm_data {
- uint32_t queue_id;
- uint32_t reserved;
-} __rte_packed_end;
-
-static int
-tm_apply_check(struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- if ((p->subport_id >= cfg->n_subports_per_port) ||
- (p->pipe_id >= cfg->n_pipes_per_subport))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-tm_apply(struct tm_data *data,
- struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = tm_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- data->queue_id = p->subport_id <<
- (rte_ctz32(cfg->n_pipes_per_subport) + 4) |
- p->pipe_id << 4;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tm(struct rte_mbuf *mbuf,
- struct tm_data *data,
- struct dscp_table_data *dscp_table,
- uint32_t dscp)
-{
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- uint32_t queue_id = data->queue_id |
- dscp_entry->tc_queue;
- rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc,
- (uint8_t)dscp_entry->color);
-}
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-static int
-encap_valid(enum rte_table_action_encap_type encap)
-{
- switch (encap) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 1;
- default:
- return 0;
- }
-}
-
-static int
-encap_cfg_check(struct rte_table_action_encap_config *encap)
-{
- if ((encap->encap_mask == 0) ||
- (rte_popcount64(encap->encap_mask) != 1))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct encap_ether_data {
- struct rte_ether_hdr ether;
-};
-
-#define VLAN(pcp, dei, vid) \
- ((uint16_t)((((uint64_t)(pcp)) & 0x7LLU) << 13) | \
- ((((uint64_t)(dei)) & 0x1LLU) << 12) | \
- (((uint64_t)(vid)) & 0xFFFLLU)) \
-
-struct encap_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
-};
-
-struct encap_qinq_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
-};
-
-#define ETHER_TYPE_MPLS_UNICAST 0x8847
-
-#define ETHER_TYPE_MPLS_MULTICAST 0x8848
-
-#define MPLS(label, tc, s, ttl) \
- ((uint32_t)(((((uint64_t)(label)) & 0xFFFFFLLU) << 12) |\
- ((((uint64_t)(tc)) & 0x7LLU) << 9) | \
- ((((uint64_t)(s)) & 0x1LLU) << 8) | \
- (((uint64_t)(ttl)) & 0xFFLLU)))
-
-struct __rte_aligned(2) __rte_packed_begin encap_mpls_data {
- struct rte_ether_hdr ether;
- uint32_t mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
- uint32_t mpls_count;
-} __rte_packed_end;
-
-#define PPP_PROTOCOL_IP 0x0021
-
-struct pppoe_ppp_hdr {
- uint16_t ver_type_code;
- uint16_t session_id;
- uint16_t length;
- uint16_t protocol;
-};
-
-struct encap_pppoe_data {
- struct rte_ether_hdr ether;
- struct pppoe_ppp_hdr pppoe_ppp;
-};
-
-#define IP_PROTO_UDP 17
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_data {
- struct rte_ether_hdr ether;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_data {
- struct rte_ether_hdr ether;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_qinq_pppoe_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
- struct pppoe_ppp_hdr pppoe_ppp;
-} __rte_packed_end;
-
-static size_t
-encap_data_size(struct rte_table_action_encap_config *encap)
-{
- switch (encap->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- return sizeof(struct encap_ether_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- return sizeof(struct encap_vlan_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- return sizeof(struct encap_qinq_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- return sizeof(struct encap_mpls_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- return sizeof(struct encap_pppoe_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- if (encap->vxlan.ip_version)
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv4_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv4_data);
- else
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv6_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv6_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return sizeof(struct encap_qinq_pppoe_data);
-
- default:
- return 0;
- }
-}
-
-static int
-encap_apply_check(struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((encap_valid(p->type) == 0) ||
- ((cfg->encap_mask & (1LLU << p->type)) == 0))
- return -EINVAL;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- if ((p->mpls.mpls_count == 0) ||
- (p->mpls.mpls_count > RTE_TABLE_ACTION_MPLS_LABELS_MAX))
- return -EINVAL;
-
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-encap_ether_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_ether_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->ether.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->ether.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_vlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_vlan_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vlan.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vlan.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vlan.vlan.pcp,
- p->vlan.vlan.dei,
- p->vlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_qinq_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_QINQ);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_qinq_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->qinq_pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_mpls_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_mpls_data *d = data;
- uint16_t ethertype = (p->mpls.unicast) ?
- ETHER_TYPE_MPLS_UNICAST :
- ETHER_TYPE_MPLS_MULTICAST;
- uint32_t i;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->mpls.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->mpls.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- /* MPLS */
- for (i = 0; i < p->mpls.mpls_count - 1; i++)
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 0,
- p->mpls.mpls[i].ttl));
-
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 1,
- p->mpls.mpls[i].ttl));
-
- d->mpls_count = p->mpls.mpls_count;
- return 0;
-}
-
-static int
-encap_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->pppoe.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->pppoe.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_vxlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((p->vxlan.vxlan.vni > 0xFFFFFF) ||
- (cfg->vxlan.ip_version && (p->vxlan.ipv4.dscp > 0x3F)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.flow_label > 0xFFFFF)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.dscp > 0x3F)) ||
- (cfg->vxlan.vlan && (p->vxlan.vlan.vid > 0xFFF)))
- return -1;
-
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv4_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv4_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
- else
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv6_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv6_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
-}
-
-static int
-encap_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg,
- struct rte_table_action_common_config *common_cfg)
-{
- int status;
-
- /* Check input arguments */
- status = encap_apply_check(p, cfg);
- if (status)
- return status;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return encap_ether_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return encap_vlan_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return encap_qinq_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- return encap_mpls_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return encap_pppoe_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return encap_vxlan_apply(data, p, cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return encap_qinq_pppoe_apply(data, p);
-
- default:
- return -EINVAL;
- }
-}
-
-static __rte_always_inline uint16_t
-encap_vxlan_ipv4_checksum_update(uint16_t cksum0,
- uint16_t total_length)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Add total length (one's complement logic) */
- cksum1 += total_length;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void *
-encap(void *dst, const void *src, size_t n)
-{
- dst = ((uint8_t *) dst) - n;
- return rte_memcpy(dst, src, n);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap(struct rte_mbuf *mbuf,
- void *data,
- struct rte_table_action_encap_config *cfg,
- void *ip,
- uint16_t total_length,
- uint32_t ip_offset)
-{
- switch (cfg->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- encap(ip, data, sizeof(struct encap_ether_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_ether_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_ether_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- encap(ip, data, sizeof(struct encap_vlan_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_vlan_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_vlan_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- encap(ip, data, sizeof(struct encap_qinq_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- {
- struct encap_mpls_data *mpls = data;
- size_t size = sizeof(struct rte_ether_hdr) +
- mpls->mpls_count * 4;
-
- encap(ip, data, size);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) + size);
- mbuf->pkt_len = mbuf->data_len = total_length + size;
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- {
- struct encap_pppoe_data *pppoe =
- encap(ip, data, sizeof(struct encap_pppoe_data));
- pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- {
- struct encap_qinq_pppoe_data *qinq_pppoe =
- encap(ip, data, sizeof(struct encap_qinq_pppoe_data));
- qinq_pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- {
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv4_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv4(mbuf, data, cfg);
- else
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv6_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv6(mbuf, data, cfg);
- }
-
- default:
- break;
- }
-}
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-static int
-nat_cfg_check(struct rte_table_action_nat_config *nat)
-{
- if ((nat->proto != 0x06) &&
- (nat->proto != 0x11))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin nat_ipv4_data {
- uint32_t addr;
- uint16_t port;
-} __rte_packed_end;
-
-struct __rte_packed_begin nat_ipv6_data {
- struct rte_ipv6_addr addr;
- uint16_t port;
-} __rte_packed_end;
-
-static size_t
-nat_data_size(struct rte_table_action_nat_config *nat __rte_unused,
- struct rte_table_action_common_config *common)
-{
- int ip_version = common->ip_version;
-
- return (ip_version) ?
- sizeof(struct nat_ipv4_data) :
- sizeof(struct nat_ipv6_data);
-}
-
-static int
-nat_apply_check(struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- if ((p->ip_version && (cfg->ip_version == 0)) ||
- ((p->ip_version == 0) && cfg->ip_version))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-nat_apply(void *data,
- struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = nat_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- if (p->ip_version) {
- struct nat_ipv4_data *d = data;
-
- d->addr = rte_htonl(p->addr.ipv4);
- d->port = rte_htons(p->port);
- } else {
- struct nat_ipv6_data *d = data;
-
- d->addr = p->addr.ipv6;
- d->port = rte_htons(p->port);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_tcp_udp_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF) + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF) + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv6_tcp_udp_checksum_update(uint16_t cksum0,
- uint16_t *ip0,
- uint16_t *ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= ip0[0] + ip0[1] + ip0[2] + ip0[3] +
- ip0[4] + ip0[5] + ip0[6] + ip0[7] + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += ip1[0] + ip1[1] + ip1[2] + ip1[3] +
- ip1[4] + ip1[5] + ip1[6] + ip1[7] + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void
-pkt_ipv4_work_nat(struct rte_ipv4_hdr *ip,
- struct nat_ipv4_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->src_addr,
- data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->src_addr,
- data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->src_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->dst_addr,
- data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->dst_addr,
- data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->dst_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-static __rte_always_inline void
-pkt_ipv6_work_nat(struct rte_ipv6_hdr *ip,
- struct nat_ipv6_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- udp->src_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- udp->dst_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-static int
-ttl_cfg_check(struct rte_table_action_ttl_config *ttl)
-{
- if (ttl->drop == 0)
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin ttl_data {
- uint32_t n_packets;
-} __rte_packed_end;
-
-#define TTL_INIT(data, decrement) \
- ((data)->n_packets = (decrement) ? 1 : 0)
-
-#define TTL_DEC_GET(data) \
- ((uint8_t)((data)->n_packets & 1))
-
-#define TTL_STATS_RESET(data) \
- ((data)->n_packets = ((data)->n_packets & 1))
-
-#define TTL_STATS_READ(data) \
- ((data)->n_packets >> 1)
-
-#define TTL_STATS_ADD(data, value) \
- ((data)->n_packets = \
- (((((data)->n_packets >> 1) + (value)) << 1) | \
- ((data)->n_packets & 1)))
-
-static int
-ttl_apply(void *data,
- struct rte_table_action_ttl_params *p)
-{
- struct ttl_data *d = data;
-
- TTL_INIT(d, p->decrement);
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv4_work_ttl(struct rte_ipv4_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint16_t cksum = ip->hdr_checksum;
- uint8_t ttl = ip->time_to_live;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- cksum += ttl_diff;
- ttl -= ttl_diff;
-
- ip->hdr_checksum = cksum;
- ip->time_to_live = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv6_work_ttl(struct rte_ipv6_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint8_t ttl = ip->hop_limits;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- ttl -= ttl_diff;
-
- ip->hop_limits = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-static int
-stats_cfg_check(struct rte_table_action_stats_config *stats)
-{
- if ((stats->n_packets_enabled == 0) && (stats->n_bytes_enabled == 0))
- return -EINVAL;
-
- return 0;
-}
-
-struct __rte_packed_begin stats_data {
- uint64_t n_packets;
- uint64_t n_bytes;
-} __rte_packed_end;
-
-static int
-stats_apply(struct stats_data *data,
- struct rte_table_action_stats_params *p)
-{
- data->n_packets = p->n_packets;
- data->n_bytes = p->n_bytes;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_stats(struct stats_data *data,
- uint16_t total_length)
-{
- data->n_packets++;
- data->n_bytes += total_length;
-}
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-struct __rte_packed_begin time_data {
- uint64_t time;
-} __rte_packed_end;
-
-static int
-time_apply(struct time_data *data,
- struct rte_table_action_time_params *p)
-{
- data->time = p->time;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_time(struct time_data *data,
- uint64_t time)
-{
- data->time = time;
-}
-
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-
-#define CRYPTO_OP_MASK_CIPHER 0x1
-#define CRYPTO_OP_MASK_AUTH 0x2
-#define CRYPTO_OP_MASK_AEAD 0x4
-
-struct crypto_op_sym_iv_aad {
- struct rte_crypto_op op;
- struct rte_crypto_sym_op sym_op;
- union {
- struct {
- uint8_t cipher_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t auth_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- } cipher_auth;
-
- struct {
- uint8_t iv[RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t aad[RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX];
- } aead_iv_aad;
-
- } iv_aad;
-};
-
-struct __rte_packed_begin sym_crypto_data {
-
- union {
- struct {
-
- /** Length of cipher iv. */
- uint16_t cipher_iv_len;
-
- /** Offset from start of IP header to the cipher iv. */
- uint16_t cipher_iv_data_offset;
-
- /** Length of cipher iv to be updated in the mbuf. */
- uint16_t cipher_iv_update_len;
-
- /** Offset from start of IP header to the auth iv. */
- uint16_t auth_iv_data_offset;
-
- /** Length of auth iv in the mbuf. */
- uint16_t auth_iv_len;
-
- /** Length of auth iv to be updated in the mbuf. */
- uint16_t auth_iv_update_len;
-
- } cipher_auth;
- struct {
-
- /** Length of iv. */
- uint16_t iv_len;
-
- /** Offset from start of IP header to the aead iv. */
- uint16_t iv_data_offset;
-
- /** Length of iv to be updated in the mbuf. */
- uint16_t iv_update_len;
-
- /** Length of aad */
- uint16_t aad_len;
-
- /** Offset from start of IP header to the aad. */
- uint16_t aad_data_offset;
-
- /** Length of aad to updated in the mbuf. */
- uint16_t aad_update_len;
-
- } aead;
- };
-
- /** Offset from start of IP header to the data. */
- uint16_t data_offset;
-
- /** Digest length. */
- uint16_t digest_len;
-
- /** block size */
- uint16_t block_size;
-
- /** Mask of crypto operation */
- uint16_t op_mask;
-
- /** Session pointer. */
- struct rte_cryptodev_sym_session *session;
-
- /** Direction of crypto, encrypt or decrypt */
- uint16_t direction;
-
- /** Private data size to store cipher iv / aad. */
- uint8_t iv_aad_data[32];
-
-} __rte_packed_end;
-
-static int
-sym_crypto_cfg_check(struct rte_table_action_sym_crypto_config *cfg)
-{
- if (!rte_cryptodev_is_valid_dev(cfg->cryptodev_id))
- return -EINVAL;
- if (cfg->mp_create == NULL || cfg->mp_init == NULL)
- return -EINVAL;
-
- return 0;
-}
-
-static int
-get_block_size(const struct rte_crypto_sym_xform *xform, uint8_t cdev_id)
-{
- struct rte_cryptodev_info dev_info;
- const struct rte_cryptodev_capabilities *cap;
- uint32_t i;
-
- rte_cryptodev_info_get(cdev_id, &dev_info);
-
- for (i = 0; dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
- i++) {
- cap = &dev_info.capabilities[i];
-
- if (cap->sym.xform_type != xform->type)
- continue;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
- (cap->sym.cipher.algo == xform->cipher.algo))
- return cap->sym.cipher.block_size;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
- (cap->sym.aead.algo == xform->aead.algo))
- return cap->sym.aead.block_size;
-
- if (xform->type == RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED)
- break;
- }
-
- return -1;
-}
-
-static int
-sym_crypto_apply(struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- struct rte_table_action_sym_crypto_params *p)
-{
- const struct rte_crypto_cipher_xform *cipher_xform = NULL;
- const struct rte_crypto_auth_xform *auth_xform = NULL;
- const struct rte_crypto_aead_xform *aead_xform = NULL;
- struct rte_crypto_sym_xform *xform = p->xform;
- struct rte_cryptodev_sym_session *session;
- int ret;
-
- memset(data, 0, sizeof(*data));
-
- while (xform) {
- if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
- cipher_xform = &xform->cipher;
-
- if (cipher_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- if (cipher_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_CIPHER;
-
- data->cipher_auth.cipher_iv_len =
- cipher_xform->iv.length;
- data->cipher_auth.cipher_iv_data_offset = (uint16_t)
- p->cipher_auth.cipher_iv_update.offset;
- data->cipher_auth.cipher_iv_update_len = (uint16_t)
- p->cipher_auth.cipher_iv_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.cipher_iv.val,
- p->cipher_auth.cipher_iv.length);
-
- data->direction = cipher_xform->op;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
- auth_xform = &xform->auth;
- if (auth_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- data->op_mask |= CRYPTO_OP_MASK_AUTH;
-
- data->cipher_auth.auth_iv_len = auth_xform->iv.length;
- data->cipher_auth.auth_iv_data_offset = (uint16_t)
- p->cipher_auth.auth_iv_update.offset;
- data->cipher_auth.auth_iv_update_len = (uint16_t)
- p->cipher_auth.auth_iv_update.length;
- data->digest_len = auth_xform->digest_length;
-
- data->direction = (auth_xform->op ==
- RTE_CRYPTO_AUTH_OP_GENERATE) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
- aead_xform = &xform->aead;
-
- if ((aead_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX) || (
- aead_xform->aad_length >
- RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX))
- return -EINVAL;
- if (aead_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_AEAD;
-
- data->digest_len = aead_xform->digest_length;
- data->aead.iv_len = aead_xform->iv.length;
- data->aead.aad_len = aead_xform->aad_length;
-
- data->aead.iv_data_offset = (uint16_t)
- p->aead.iv_update.offset;
- data->aead.iv_update_len = (uint16_t)
- p->aead.iv_update.length;
- data->aead.aad_data_offset = (uint16_t)
- p->aead.aad_update.offset;
- data->aead.aad_update_len = (uint16_t)
- p->aead.aad_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->aead.iv.val,
- p->aead.iv.length);
-
- rte_memcpy(data->iv_aad_data + p->aead.iv.length,
- p->aead.aad.val,
- p->aead.aad.length);
-
- data->direction = (aead_xform->op ==
- RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
- } else
- return -EINVAL;
-
- xform = xform->next;
- }
-
- if (auth_xform && auth_xform->iv.length) {
- if (cipher_xform) {
- if (auth_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET +
- cipher_xform->iv.length)
- return -EINVAL;
-
- rte_memcpy(data->iv_aad_data + cipher_xform->iv.length,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- } else {
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- }
- }
-
- session = rte_cryptodev_sym_session_create(cfg->cryptodev_id,
- p->xform, cfg->mp_create);
- if (!session)
- return -ENOMEM;
-
- data->data_offset = (uint16_t)p->data_offset;
- data->session = session;
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_sym_crypto(struct rte_mbuf *mbuf, struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- uint16_t ip_offset)
-{
- struct crypto_op_sym_iv_aad *crypto_op = (struct crypto_op_sym_iv_aad *)
- RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->op_offset);
- struct rte_crypto_op *op = &crypto_op->op;
- struct rte_crypto_sym_op *sym = op->sym;
- uint32_t pkt_offset = sizeof(*mbuf) + mbuf->data_off;
- uint32_t payload_len = pkt_offset + mbuf->data_len - data->data_offset;
-
- op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
- op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
- op->phys_addr = rte_mbuf_iova_get(mbuf) + cfg->op_offset - sizeof(*mbuf);
- op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
- sym->m_src = mbuf;
- sym->m_dst = NULL;
- sym->session = data->session;
-
- /** pad the packet */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
- uint32_t append_len = RTE_ALIGN_CEIL(payload_len,
- data->block_size) - payload_len;
-
- if (unlikely(rte_pktmbuf_append(mbuf, append_len +
- data->digest_len) == NULL))
- return 1;
-
- payload_len += append_len;
- } else
- payload_len -= data->digest_len;
-
- if (data->op_mask & CRYPTO_OP_MASK_CIPHER) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.cipher_iv;
-
- sym->cipher.data.length = payload_len;
- sym->cipher.data.offset = data->data_offset - pkt_offset;
-
- if (data->cipher_auth.cipher_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.cipher_iv_data_offset
- + ip_offset);
-
- /** For encryption, update the pkt iv field, otherwise
- * update the iv_aad_field
- */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_update_len);
- else
- rte_memcpy(data->iv_aad_data, pkt_iv,
- data->cipher_auth.cipher_iv_update_len);
- }
-
- /** write iv */
- rte_memcpy(iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_len);
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AUTH) {
- /** authentication always start from IP header. */
- sym->auth.data.offset = ip_offset - pkt_offset;
- sym->auth.data.length = mbuf->data_len - sym->auth.data.offset -
- data->digest_len;
- sym->auth.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->auth.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
-
- if (data->cipher_auth.auth_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.auth_iv_data_offset
- + ip_offset);
- uint8_t *data_iv = data->iv_aad_data +
- data->cipher_auth.cipher_iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->cipher_auth.auth_iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->cipher_auth.auth_iv_update_len);
- }
-
- if (data->cipher_auth.auth_iv_len) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.auth_iv;
-
- rte_memcpy(iv, data->iv_aad_data +
- data->cipher_auth.cipher_iv_len,
- data->cipher_auth.auth_iv_len);
- }
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AEAD) {
- uint8_t *iv = crypto_op->iv_aad.aead_iv_aad.iv;
- uint8_t *aad = crypto_op->iv_aad.aead_iv_aad.aad;
-
- sym->aead.aad.data = aad;
- sym->aead.aad.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- aad - rte_pktmbuf_mtod(mbuf, uint8_t *));
- sym->aead.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->aead.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
- sym->aead.data.offset = data->data_offset - pkt_offset;
- sym->aead.data.length = payload_len;
-
- if (data->aead.iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.iv_data_offset + ip_offset);
- uint8_t *data_iv = data->iv_aad_data;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(iv, data->iv_aad_data, data->aead.iv_len);
-
- if (data->aead.aad_update_len) {
- uint8_t *pkt_aad = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.aad_data_offset + ip_offset);
- uint8_t *data_aad = data->iv_aad_data +
- data->aead.iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_aad, data_aad,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_aad, pkt_aad,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(aad, data->iv_aad_data + data->aead.iv_len,
- data->aead.aad_len);
- }
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-struct __rte_packed_begin tag_data {
- uint32_t tag;
-} __rte_packed_end;
-
-static int
-tag_apply(struct tag_data *data,
- struct rte_table_action_tag_params *p)
-{
- data->tag = p->tag;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tag(struct rte_mbuf *mbuf,
- struct tag_data *data)
-{
- mbuf->hash.fdir.hi = data->tag;
- mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-static __rte_always_inline void
-pkt4_work_tag(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct tag_data *data0,
- struct tag_data *data1,
- struct tag_data *data2,
- struct tag_data *data3)
-{
- mbuf0->hash.fdir.hi = data0->tag;
- mbuf1->hash.fdir.hi = data1->tag;
- mbuf2->hash.fdir.hi = data2->tag;
- mbuf3->hash.fdir.hi = data3->tag;
-
- mbuf0->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf1->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf2->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf3->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-struct __rte_packed_begin decap_data {
- uint16_t n;
-} __rte_packed_end;
-
-static int
-decap_apply(struct decap_data *data,
- struct rte_table_action_decap_params *p)
-{
- data->n = p->n;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_decap(struct rte_mbuf *mbuf,
- struct decap_data *data)
-{
- uint16_t data_off = mbuf->data_off;
- uint16_t data_len = mbuf->data_len;
- uint32_t pkt_len = mbuf->pkt_len;
- uint16_t n = data->n;
-
- mbuf->data_off = data_off + n;
- mbuf->data_len = data_len - n;
- mbuf->pkt_len = pkt_len - n;
-}
-
-static __rte_always_inline void
-pkt4_work_decap(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct decap_data *data0,
- struct decap_data *data1,
- struct decap_data *data2,
- struct decap_data *data3)
-{
- uint16_t data_off0 = mbuf0->data_off;
- uint16_t data_len0 = mbuf0->data_len;
- uint32_t pkt_len0 = mbuf0->pkt_len;
-
- uint16_t data_off1 = mbuf1->data_off;
- uint16_t data_len1 = mbuf1->data_len;
- uint32_t pkt_len1 = mbuf1->pkt_len;
-
- uint16_t data_off2 = mbuf2->data_off;
- uint16_t data_len2 = mbuf2->data_len;
- uint32_t pkt_len2 = mbuf2->pkt_len;
-
- uint16_t data_off3 = mbuf3->data_off;
- uint16_t data_len3 = mbuf3->data_len;
- uint32_t pkt_len3 = mbuf3->pkt_len;
-
- uint16_t n0 = data0->n;
- uint16_t n1 = data1->n;
- uint16_t n2 = data2->n;
- uint16_t n3 = data3->n;
-
- mbuf0->data_off = data_off0 + n0;
- mbuf0->data_len = data_len0 - n0;
- mbuf0->pkt_len = pkt_len0 - n0;
-
- mbuf1->data_off = data_off1 + n1;
- mbuf1->data_len = data_len1 - n1;
- mbuf1->pkt_len = pkt_len1 - n1;
-
- mbuf2->data_off = data_off2 + n2;
- mbuf2->data_len = data_len2 - n2;
- mbuf2->pkt_len = pkt_len2 - n2;
-
- mbuf3->data_off = data_off3 + n3;
- mbuf3->data_len = data_len3 - n3;
- mbuf3->pkt_len = pkt_len3 - n3;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- case RTE_TABLE_ACTION_LB:
- case RTE_TABLE_ACTION_MTR:
- case RTE_TABLE_ACTION_TM:
- case RTE_TABLE_ACTION_ENCAP:
- case RTE_TABLE_ACTION_NAT:
- case RTE_TABLE_ACTION_TTL:
- case RTE_TABLE_ACTION_STATS:
- case RTE_TABLE_ACTION_TIME:
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- case RTE_TABLE_ACTION_TAG:
- case RTE_TABLE_ACTION_DECAP:
- return 1;
- default:
- return 0;
- }
-}
-
-
-#define RTE_TABLE_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-static size_t
-action_cfg_size(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct rte_table_action_lb_config);
- case RTE_TABLE_ACTION_MTR:
- return sizeof(struct rte_table_action_mtr_config);
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct rte_table_action_tm_config);
- case RTE_TABLE_ACTION_ENCAP:
- return sizeof(struct rte_table_action_encap_config);
- case RTE_TABLE_ACTION_NAT:
- return sizeof(struct rte_table_action_nat_config);
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct rte_table_action_ttl_config);
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct rte_table_action_stats_config);
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sizeof(struct rte_table_action_sym_crypto_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_table_action_type type)
-{
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- return &ap_config->lb;
-
- case RTE_TABLE_ACTION_MTR:
- return &ap_config->mtr;
-
- case RTE_TABLE_ACTION_TM:
- return &ap_config->tm;
-
- case RTE_TABLE_ACTION_ENCAP:
- return &ap_config->encap;
-
- case RTE_TABLE_ACTION_NAT:
- return &ap_config->nat;
-
- case RTE_TABLE_ACTION_TTL:
- return &ap_config->ttl;
-
- case RTE_TABLE_ACTION_STATS:
- return &ap_config->stats;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return &ap_config->sym_crypto;
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_table_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_TABLE_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_table_action_type action,
- struct ap_config *ap_config)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- return sizeof(struct fwd_data);
-
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct lb_data);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_data_size(&ap_config->mtr);
-
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct tm_data);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_data_size(&ap_config->encap);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_data_size(&ap_config->nat,
- &ap_config->common);
-
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct ttl_data);
-
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct stats_data);
-
- case RTE_TABLE_ACTION_TIME:
- return sizeof(struct time_data);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return (sizeof(struct sym_crypto_data));
-
- case RTE_TABLE_ACTION_TAG:
- return sizeof(struct tag_data);
-
- case RTE_TABLE_ACTION_DECAP:
- return sizeof(struct decap_data);
-
- default:
- return 0;
- }
-}
-
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_TABLE_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_table_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_table_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_create, 18.05)
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common)
-{
- struct rte_table_action_profile *ap;
-
- /* Check input arguments */
- if (common == NULL)
- return NULL;
-
- /* Memory allocation */
- ap = calloc(1, sizeof(struct rte_table_action_profile));
- if (ap == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&ap->cfg.common, common, sizeof(*common));
-
- return ap;
-}
-
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_action_register, 18.05)
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_MTR:
- status = mtr_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TM:
- status = tm_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_ENCAP:
- status = encap_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_NAT:
- status = nat_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TTL:
- status = ttl_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_STATS:
- status = stats_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- status = sym_crypto_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_freeze, 18.05)
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- profile->cfg.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_free, 18.05)
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-#define METER_PROFILES_MAX 32
-
-struct rte_table_action {
- struct ap_config cfg;
- struct ap_data data;
- struct dscp_table_data dscp_table;
- struct meter_profile_data mp[METER_PROFILES_MAX];
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_create, 18.05)
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_table_action *action;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- action = rte_zmalloc_socket(NULL,
- sizeof(struct rte_table_action),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- return action;
-}
-
-static __rte_always_inline void *
-action_data_get(void *data,
- struct rte_table_action *action,
- enum rte_table_action_type type)
-{
- size_t offset = action->data.offset[type];
- uint8_t *data_bytes = data;
-
- return &data_bytes[offset];
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_apply, 18.05)
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (data == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(data, action, type);
-
- switch (type) {
- case RTE_TABLE_ACTION_FWD:
- return fwd_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_apply(action_data,
- action_params,
- &action->cfg.mtr,
- action->mp,
- RTE_DIM(action->mp));
-
- case RTE_TABLE_ACTION_TM:
- return tm_apply(action_data,
- action_params,
- &action->cfg.tm);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_apply(action_data,
- action_params,
- &action->cfg.encap,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_apply(action_data,
- action_params,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_TTL:
- return ttl_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_STATS:
- return stats_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_TIME:
- return time_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sym_crypto_apply(action_data,
- &action->cfg.sym_crypto,
- action_params);
-
- case RTE_TABLE_ACTION_TAG:
- return tag_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_DECAP:
- return decap_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_dscp_table_update, 18.05)
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table)
-{
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TM))) == 0) ||
- (dscp_mask == 0) ||
- (table == NULL))
- return -EINVAL;
-
- for (i = 0; i < RTE_DIM(table->entry); i++) {
- struct dscp_table_entry_data *data =
- &action->dscp_table.entry[i];
- struct rte_table_action_dscp_table_entry *entry =
- &table->entry[i];
-
- if ((dscp_mask & (1LLU << i)) == 0)
- continue;
-
- data->color = entry->color;
- data->tc = entry->tc_id;
- data->tc_queue = entry->tc_queue_id;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_add, 18.05)
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct meter_profile_data *mp_data;
- uint32_t status;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (profile == NULL))
- return -EINVAL;
-
- if (profile->alg != RTE_TABLE_ACTION_METER_TRTCM)
- return -ENOTSUP;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (mp_data)
- return -EEXIST;
-
- mp_data = meter_profile_data_find_unused(action->mp,
- RTE_DIM(action->mp));
- if (!mp_data)
- return -ENOSPC;
-
- /* Install new profile */
- status = rte_meter_trtcm_profile_config(&mp_data->profile,
- &profile->trtcm);
- if (status)
- return status;
-
- mp_data->profile_id = meter_profile_id;
- mp_data->valid = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_delete, 18.05)
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id)
-{
- struct meter_profile_data *mp_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0))
- return -EINVAL;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (!mp_data)
- return 0;
-
- /* Uninstall profile */
- mp_data->valid = 0;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_read, 18.05)
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct mtr_trtcm_data *mtr_data;
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (data == NULL) ||
- (tc_mask > RTE_LEN2MASK(action->cfg.mtr.n_tc, uint32_t)))
- return -EINVAL;
-
- mtr_data = action_data_get(data, action, RTE_TABLE_ACTION_MTR);
-
- /* Read */
- if (stats) {
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_counters_tc *dst =
- &stats->stats[i];
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- dst->n_packets[RTE_COLOR_GREEN] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_GREEN);
-
- dst->n_packets[RTE_COLOR_YELLOW] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_YELLOW);
-
- dst->n_packets[RTE_COLOR_RED] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_RED);
-
- dst->n_packets_valid = 1;
- dst->n_bytes_valid = 0;
- }
-
- stats->tc_mask = tc_mask;
- }
-
- /* Clear */
- if (clear)
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_GREEN);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_YELLOW);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_RED);
- }
-
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_ttl_read, 18.05)
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct ttl_data *ttl_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TTL)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- ttl_data = action_data_get(data, action, RTE_TABLE_ACTION_TTL);
-
- /* Read */
- if (stats)
- stats->n_packets = TTL_STATS_READ(ttl_data);
-
- /* Clear */
- if (clear)
- TTL_STATS_RESET(ttl_data);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_stats_read, 18.05)
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct stats_data *stats_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_STATS)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- stats_data = action_data_get(data, action,
- RTE_TABLE_ACTION_STATS);
-
- /* Read */
- if (stats) {
- stats->n_packets = stats_data->n_packets;
- stats->n_bytes = stats_data->n_bytes;
- stats->n_packets_valid = 1;
- stats->n_bytes_valid = 1;
- }
-
- /* Clear */
- if (clear) {
- stats_data->n_packets = 0;
- stats_data->n_bytes = 0;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_time_read, 18.05)
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp)
-{
- struct time_data *time_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TIME)) == 0) ||
- (data == NULL) ||
- (timestamp == NULL))
- return -EINVAL;
-
- time_data = action_data_get(data, action, RTE_TABLE_ACTION_TIME);
-
- /* Read */
- *timestamp = time_data->time;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_crypto_sym_session_get, 18.11)
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data)
-{
- struct sym_crypto_data *sym_crypto_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) == 0) ||
- (data == NULL))
- return NULL;
-
- sym_crypto_data = action_data_get(data, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- return sym_crypto_data->session;
-}
-
-static __rte_always_inline uint64_t
-pkt_work(struct rte_mbuf *mbuf,
- struct rte_pipeline_table_entry *table_entry,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask = 0;
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ip_offset);
-
- uint32_t dscp;
- uint16_t total_length;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr = ip;
-
- dscp = hdr->type_of_service >> 2;
- total_length = rte_ntohs(hdr->total_length);
- } else {
- struct rte_ipv6_hdr *hdr = ip;
-
- dscp = (rte_ntohl(hdr->vtc_flow) & 0x0F600000) >> 18;
- total_length = rte_ntohs(hdr->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf,
- data,
- &cfg->lb);
- }
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask |= pkt_work_mtr(mbuf,
- data,
- &action->dscp_table,
- action->mp,
- time,
- dscp,
- total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf,
- data,
- &action->dscp_table,
- dscp);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt_work_decap(mbuf, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf,
- data,
- &cfg->encap,
- ip,
- total_length,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version)
- pkt_ipv4_work_nat(ip, data, &cfg->nat);
- else
- pkt_ipv6_work_nat(ip, data, &cfg->nat);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version)
- drop_mask |= pkt_ipv4_work_ttl(ip, data);
- else
- drop_mask |= pkt_ipv6_work_ttl(ip, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data, total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data = action_data_get(table_entry, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask |= pkt_work_sym_crypto(mbuf, data, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt_work_tag(mbuf, data);
- }
-
- return drop_mask;
-}
-
-static __rte_always_inline uint64_t
-pkt4_work(struct rte_mbuf **mbufs,
- struct rte_pipeline_table_entry **table_entries,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask0 = 0;
- uint64_t drop_mask1 = 0;
- uint64_t drop_mask2 = 0;
- uint64_t drop_mask3 = 0;
-
- struct rte_mbuf *mbuf0 = mbufs[0];
- struct rte_mbuf *mbuf1 = mbufs[1];
- struct rte_mbuf *mbuf2 = mbufs[2];
- struct rte_mbuf *mbuf3 = mbufs[3];
-
- struct rte_pipeline_table_entry *table_entry0 = table_entries[0];
- struct rte_pipeline_table_entry *table_entry1 = table_entries[1];
- struct rte_pipeline_table_entry *table_entry2 = table_entries[2];
- struct rte_pipeline_table_entry *table_entry3 = table_entries[3];
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip0 = RTE_MBUF_METADATA_UINT32_PTR(mbuf0, ip_offset);
- void *ip1 = RTE_MBUF_METADATA_UINT32_PTR(mbuf1, ip_offset);
- void *ip2 = RTE_MBUF_METADATA_UINT32_PTR(mbuf2, ip_offset);
- void *ip3 = RTE_MBUF_METADATA_UINT32_PTR(mbuf3, ip_offset);
-
- uint32_t dscp0, dscp1, dscp2, dscp3;
- uint16_t total_length0, total_length1, total_length2, total_length3;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr0 = ip0;
- struct rte_ipv4_hdr *hdr1 = ip1;
- struct rte_ipv4_hdr *hdr2 = ip2;
- struct rte_ipv4_hdr *hdr3 = ip3;
-
- dscp0 = hdr0->type_of_service >> 2;
- dscp1 = hdr1->type_of_service >> 2;
- dscp2 = hdr2->type_of_service >> 2;
- dscp3 = hdr3->type_of_service >> 2;
-
- total_length0 = rte_ntohs(hdr0->total_length);
- total_length1 = rte_ntohs(hdr1->total_length);
- total_length2 = rte_ntohs(hdr2->total_length);
- total_length3 = rte_ntohs(hdr3->total_length);
- } else {
- struct rte_ipv6_hdr *hdr0 = ip0;
- struct rte_ipv6_hdr *hdr1 = ip1;
- struct rte_ipv6_hdr *hdr2 = ip2;
- struct rte_ipv6_hdr *hdr3 = ip3;
-
- dscp0 = (rte_ntohl(hdr0->vtc_flow) & 0x0F600000) >> 18;
- dscp1 = (rte_ntohl(hdr1->vtc_flow) & 0x0F600000) >> 18;
- dscp2 = (rte_ntohl(hdr2->vtc_flow) & 0x0F600000) >> 18;
- dscp3 = (rte_ntohl(hdr3->vtc_flow) & 0x0F600000) >> 18;
-
- total_length0 = rte_ntohs(hdr0->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length1 = rte_ntohs(hdr1->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length2 = rte_ntohs(hdr2->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length3 = rte_ntohs(hdr3->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_LB);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_LB);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_LB);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf0,
- data0,
- &cfg->lb);
-
- pkt_work_lb(mbuf1,
- data1,
- &cfg->lb);
-
- pkt_work_lb(mbuf2,
- data2,
- &cfg->lb);
-
- pkt_work_lb(mbuf3,
- data3,
- &cfg->lb);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_MTR);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_MTR);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_MTR);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask0 |= pkt_work_mtr(mbuf0,
- data0,
- &action->dscp_table,
- action->mp,
- time,
- dscp0,
- total_length0);
-
- drop_mask1 |= pkt_work_mtr(mbuf1,
- data1,
- &action->dscp_table,
- action->mp,
- time,
- dscp1,
- total_length1);
-
- drop_mask2 |= pkt_work_mtr(mbuf2,
- data2,
- &action->dscp_table,
- action->mp,
- time,
- dscp2,
- total_length2);
-
- drop_mask3 |= pkt_work_mtr(mbuf3,
- data3,
- &action->dscp_table,
- action->mp,
- time,
- dscp3,
- total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TM);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TM);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TM);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf0,
- data0,
- &action->dscp_table,
- dscp0);
-
- pkt_work_tm(mbuf1,
- data1,
- &action->dscp_table,
- dscp1);
-
- pkt_work_tm(mbuf2,
- data2,
- &action->dscp_table,
- dscp2);
-
- pkt_work_tm(mbuf3,
- data3,
- &action->dscp_table,
- dscp3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt4_work_decap(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_ENCAP);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_ENCAP);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_ENCAP);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf0,
- data0,
- &cfg->encap,
- ip0,
- total_length0,
- ip_offset);
-
- pkt_work_encap(mbuf1,
- data1,
- &cfg->encap,
- ip1,
- total_length1,
- ip_offset);
-
- pkt_work_encap(mbuf2,
- data2,
- &cfg->encap,
- ip2,
- total_length2,
- ip_offset);
-
- pkt_work_encap(mbuf3,
- data3,
- &cfg->encap,
- ip3,
- total_length3,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_NAT);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_NAT);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_NAT);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version) {
- pkt_ipv4_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv4_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv4_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv4_work_nat(ip3, data3, &cfg->nat);
- } else {
- pkt_ipv6_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv6_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv6_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv6_work_nat(ip3, data3, &cfg->nat);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TTL);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TTL);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TTL);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version) {
- drop_mask0 |= pkt_ipv4_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv4_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv4_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv4_work_ttl(ip3, data3);
- } else {
- drop_mask0 |= pkt_ipv6_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv6_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv6_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv6_work_ttl(ip3, data3);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_STATS);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_STATS);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_STATS);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data0, total_length0);
- pkt_work_stats(data1, total_length1);
- pkt_work_stats(data2, total_length2);
- pkt_work_stats(data3, total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TIME);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TIME);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TIME);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data0, time);
- pkt_work_time(data1, time);
- pkt_work_time(data2, time);
- pkt_work_time(data3, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data0 = action_data_get(table_entry0, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data1 = action_data_get(table_entry1, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data2 = action_data_get(table_entry2, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data3 = action_data_get(table_entry3, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask0 |= pkt_work_sym_crypto(mbuf0, data0, &cfg->sym_crypto,
- ip_offset);
- drop_mask1 |= pkt_work_sym_crypto(mbuf1, data1, &cfg->sym_crypto,
- ip_offset);
- drop_mask2 |= pkt_work_sym_crypto(mbuf2, data2, &cfg->sym_crypto,
- ip_offset);
- drop_mask3 |= pkt_work_sym_crypto(mbuf3, data3, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt4_work_tag(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- return drop_mask0 |
- (drop_mask1 << 1) |
- (drop_mask2 << 2) |
- (drop_mask3 << 3);
-}
-
-static __rte_always_inline int
-ah(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t pkts_drop_mask = 0;
- uint64_t time = 0;
-
- if (cfg->action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TIME)))
- time = rte_rdtsc();
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {
- uint64_t drop_mask;
-
- drop_mask = pkt4_work(&pkts[i],
- &entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
-
- for ( ; i < n_pkts; i++) {
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[i],
- entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
- } else
- for ( ; pkts_mask; ) {
- uint32_t pos = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pos;
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[pos],
- entries[pos],
- time,
- action,
- cfg);
-
- pkts_mask &= ~pkt_mask;
- pkts_drop_mask |= drop_mask << pos;
- }
-
- rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
-
- return 0;
-}
-
-static int
-ah_default(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg)
-{
- struct rte_table_action *action = arg;
-
- return ah(p,
- pkts,
- pkts_mask,
- entries,
- action,
- &action->cfg);
-}
-
-static rte_pipeline_table_action_handler_hit
-ah_selector(struct rte_table_action *action)
-{
- if (action->cfg.action_mask == (1LLU << RTE_TABLE_ACTION_FWD))
- return NULL;
-
- return ah_default;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_table_params_get, 18.05)
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params)
-{
- rte_pipeline_table_action_handler_hit f_action_hit;
- uint32_t total_size;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action_hit = ah_selector(action);
- total_size = rte_align32pow2(action->data.total_size);
-
- /* Fill in params */
- params->f_action_hit = f_action_hit;
- params->f_action_miss = NULL;
- params->arg_ah = (f_action_hit) ? action : NULL;
- params->action_data_size = total_size -
- sizeof(struct rte_pipeline_table_entry);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_free, 18.05)
-int
-rte_table_action_free(struct rte_table_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_table_action.h b/lib/pipeline/rte_table_action.h
deleted file mode 100644
index 47a7bdfc01..0000000000
--- a/lib/pipeline/rte_table_action.h
+++ /dev/null
@@ -1,1137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_ACTION_H__
-#define __INCLUDE_RTE_TABLE_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Table Actions
- *
- * This API provides a common set of actions for pipeline tables to speed up
- * application development.
- *
- * Each match-action rule added to a pipeline table has associated data that
- * stores the action context. This data is input to the table action handler
- * called for every input packet that hits the rule as part of the table lookup
- * during the pipeline execution. The pipeline library allows the user to define
- * his own table actions by providing customized table action handlers (table
- * lookup) and complete freedom of setting the rules and their data (table rule
- * add/delete). While the user can still follow this process, this API is
- * intended to provide a quicker development alternative for a set of predefined
- * actions.
- *
- * The typical steps to use this API are:
- * - Define a table action profile. This is a configuration template that can
- * potentially be shared by multiple tables from the same or different
- * pipelines, with different tables from the same pipeline likely to use
- * different action profiles. For every table using a given action profile,
- * the profile defines the set of actions and the action configuration to be
- * implemented for all the table rules. API functions:
- * rte_table_action_profile_create(),
- * rte_table_action_profile_action_register(),
- * rte_table_action_profile_freeze().
- *
- * - Instantiate the table action profile to create table action objects. Each
- * pipeline table has its own table action object. API functions:
- * rte_table_action_create().
- *
- * - Use the table action object to generate the pipeline table action handlers
- * (invoked by the pipeline table lookup operation). API functions:
- * rte_table_action_table_params_get().
- *
- * - Use the table action object to generate the rule data (for the pipeline
- * table rule add operation) based on given action parameters. API functions:
- * rte_table_action_apply().
- *
- * - Use the table action object to read action data (e.g. stats counters) for
- * any given rule. API functions: rte_table_action_XYZ_read().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_ether.h>
-#include <rte_ip6.h>
-#include <rte_meter.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Table actions. */
-enum rte_table_action_type {
- /** Forward to next pipeline table, output port or drop. */
- RTE_TABLE_ACTION_FWD = 0,
-
- /** Load balance. */
- RTE_TABLE_ACTION_LB,
-
- /** Traffic Metering and Policing. */
- RTE_TABLE_ACTION_MTR,
-
- /** Traffic Management. */
- RTE_TABLE_ACTION_TM,
-
- /** Packet encapsulations. */
- RTE_TABLE_ACTION_ENCAP,
-
- /** Network Address Translation (NAT). */
- RTE_TABLE_ACTION_NAT,
-
- /** Time to Live (TTL) update. */
- RTE_TABLE_ACTION_TTL,
-
- /** Statistics. */
- RTE_TABLE_ACTION_STATS,
-
- /** Timestamp. */
- RTE_TABLE_ACTION_TIME,
-
- /** Crypto. */
- RTE_TABLE_ACTION_SYM_CRYPTO,
-
- /** Tag. */
- RTE_TABLE_ACTION_TAG,
-
- /** Packet decapsulations. */
- RTE_TABLE_ACTION_DECAP,
-};
-
-/** Common action configuration (per table action profile). */
-struct rte_table_action_common_config {
- /** Input packet Internet Protocol (IP) version. Non-zero for IPv4, zero
- * for IPv6.
- */
- int ip_version;
-
- /** IP header offset within the input packet buffer. Offset 0 points to
- * the first byte of the MBUF structure.
- */
- uint32_t ip_offset;
-};
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-/** Forward action parameters (per table rule). */
-struct rte_table_action_fwd_params {
- /** Forward action. */
- enum rte_pipeline_action action;
-
- /** Pipeline table ID or output port ID. */
- uint32_t id;
-};
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_TABLE_ACTION_LB_TABLE_SIZE 8
-
-/** Load balance action configuration (per table action profile). */
-struct rte_table_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask (*key_size* bytes are valid). */
- uint8_t key_mask[RTE_TABLE_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Output value offset within the input packet buffer. Offset 0 points
- * to the first byte of the MBUF structure.
- */
- uint32_t out_offset;
-};
-
-/** Load balance action parameters (per table rule). */
-struct rte_table_action_lb_params {
- /** Table defining the output values and their weights. The weights are
- * set in 1/RTE_TABLE_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_TABLE_ACTION_LB_TABLE_SIZE to a given output value
- * (0 <= N <= RTE_TABLE_ACTION_LB_TABLE_SIZE), the same output value
- * needs to show up exactly N times in this table.
- */
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-/** Max number of traffic classes (TCs). */
-#define RTE_TABLE_ACTION_TC_MAX 16
-
-/** Max number of queues per traffic class. */
-#define RTE_TABLE_ACTION_TC_QUEUE_MAX 16
-
-/** Differentiated Services Code Point (DSCP) translation table entry. */
-struct rte_table_action_dscp_table_entry {
- /** Traffic class. Used by the meter or the traffic management actions.
- * Has to be strictly smaller than *RTE_TABLE_ACTION_TC_MAX*. Traffic
- * class 0 is the highest priority.
- */
- uint32_t tc_id;
-
- /** Traffic class queue. Used by the traffic management action. Has to
- * be strictly smaller than *RTE_TABLE_ACTION_TC_QUEUE_MAX*.
- */
- uint32_t tc_queue_id;
-
- /** Packet color. Used by the meter action as the packet input color
- * for the color aware mode of the traffic metering algorithm.
- */
- enum rte_color color;
-};
-
-/** DSCP translation table. */
-struct rte_table_action_dscp_table {
- /** Array of DSCP table entries */
- struct rte_table_action_dscp_table_entry entry[64];
-};
-
-/** Supported traffic metering algorithms. */
-enum rte_table_action_meter_algorithm {
- /** Single Rate Three Color Marker (srTCM) - IETF RFC 2697. */
- RTE_TABLE_ACTION_METER_SRTCM,
-
- /** Two Rate Three Color Marker (trTCM) - IETF RFC 2698. */
- RTE_TABLE_ACTION_METER_TRTCM,
-};
-
-/** Traffic metering profile (configuration template). */
-struct rte_table_action_meter_profile {
- /** Traffic metering algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- union {
- /** Only valid when *alg* is set to srTCM - IETF RFC 2697. */
- struct rte_meter_srtcm_params srtcm;
-
- /** Only valid when *alg* is set to trTCM - IETF RFC 2698. */
- struct rte_meter_trtcm_params trtcm;
- };
-};
-
-/** Policer actions. */
-enum rte_table_action_policer {
- /** Recolor the packet as green. */
- RTE_TABLE_ACTION_POLICER_COLOR_GREEN = 0,
-
- /** Recolor the packet as yellow. */
- RTE_TABLE_ACTION_POLICER_COLOR_YELLOW,
-
- /** Recolor the packet as red. */
- RTE_TABLE_ACTION_POLICER_COLOR_RED,
-
- /** Drop the packet. */
- RTE_TABLE_ACTION_POLICER_DROP,
-
- /** Number of policer actions. */
- RTE_TABLE_ACTION_POLICER_MAX
-};
-
-/** Meter action configuration per traffic class. */
-struct rte_table_action_mtr_tc_params {
- /** Meter profile ID. */
- uint32_t meter_profile_id;
-
- /** Policer actions. */
- enum rte_table_action_policer policer[RTE_COLORS];
-};
-
-/** Meter action statistics counters per traffic class. */
-struct rte_table_action_mtr_counters_tc {
- /** Number of packets per color at the output of the traffic metering
- * and before the policer actions are executed. Only valid when
- * *n_packets_valid* is non-zero.
- */
- uint64_t n_packets[RTE_COLORS];
-
- /** Number of packet bytes per color at the output of the traffic
- * metering and before the policer actions are executed. Only valid when
- * *n_bytes_valid* is non-zero.
- */
- uint64_t n_bytes[RTE_COLORS];
-
- /** When non-zero, the *n_packets* field is valid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid. */
- int n_bytes_valid;
-};
-
-/** Meter action configuration (per table action profile). */
-struct rte_table_action_mtr_config {
- /** Meter algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- /** Number of traffic classes. Each traffic class has its own traffic
- * meter and policer instances. Needs to be equal to either 1 or to
- * *RTE_TABLE_ACTION_TC_MAX*.
- */
- uint32_t n_tc;
-
- /** When non-zero, the *n_packets* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_bytes_enabled;
-};
-
-/** Meter action parameters (per table rule). */
-struct rte_table_action_mtr_params {
- /** Traffic meter and policer parameters for each of the *tc_mask*
- * traffic classes.
- */
- struct rte_table_action_mtr_tc_params mtr[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/** Meter action statistics counters (per table rule). */
-struct rte_table_action_mtr_counters {
- /** Stats counters for each of the *tc_mask* traffic classes. */
- struct rte_table_action_mtr_counters_tc stats[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-/** Traffic management action configuration (per table action profile). */
-struct rte_table_action_tm_config {
- /** Number of subports per port. */
- uint32_t n_subports_per_port;
-
- /** Number of pipes per subport. */
- uint32_t n_pipes_per_subport;
-};
-
-/** Traffic management action parameters (per table rule). */
-struct rte_table_action_tm_params {
- /** Subport ID. */
- uint32_t subport_id;
-
- /** Pipe ID. */
- uint32_t pipe_id;
-};
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-/** Supported packet encapsulation types. */
-enum rte_table_action_encap_type {
- /** IP -> { Ether | IP } */
- RTE_TABLE_ACTION_ENCAP_ETHER = 0,
-
- /** IP -> { Ether | VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_VLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ,
-
- /** IP -> { Ether | MPLS | IP } */
- RTE_TABLE_ACTION_ENCAP_MPLS,
-
- /** IP -> { Ether | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_PPPOE,
-
- /** Ether -> { Ether | IP | UDP | VXLAN | Ether }
- * Ether -> { Ether | VLAN | IP | UDP | VXLAN | Ether }
- */
- RTE_TABLE_ACTION_ENCAP_VXLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE,
-};
-
-/** Pre-computed Ethernet header fields for encapsulation action. */
-struct rte_table_action_ether_hdr {
- struct rte_ether_addr da; /**< Destination address. */
- struct rte_ether_addr sa; /**< Source address. */
-};
-
-/** Pre-computed VLAN header fields for encapsulation action. */
-struct rte_table_action_vlan_hdr {
- uint8_t pcp; /**< Priority Code Point (PCP). */
- uint8_t dei; /**< Drop Eligibility Indicator (DEI). */
- uint16_t vid; /**< VLAN Identifier (VID). */
-};
-
-/** Pre-computed MPLS header fields for encapsulation action. */
-struct rte_table_action_mpls_hdr {
- uint32_t label; /**< Label. */
- uint8_t tc; /**< Traffic Class (TC). */
- uint8_t ttl; /**< Time to Live (TTL). */
-};
-
-/** Pre-computed PPPoE header fields for encapsulation action. */
-struct rte_table_action_pppoe_hdr {
- uint16_t session_id; /**< Session ID. */
-};
-
-/** Pre-computed IPv4 header fields for encapsulation action. */
-struct rte_table_action_ipv4_header {
- uint32_t sa; /**< Source address. */
- uint32_t da; /**< Destination address. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t ttl; /**< Time To Live (TTL). */
-};
-
-/** Pre-computed IPv6 header fields for encapsulation action. */
-struct rte_table_action_ipv6_header {
- struct rte_ipv6_addr sa; /**< Source address. */
- struct rte_ipv6_addr da; /**< Destination address. */
- uint32_t flow_label; /**< Flow label. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t hop_limit; /**< Hop Limit (HL). */
-};
-
-/** Pre-computed UDP header fields for encapsulation action. */
-struct rte_table_action_udp_header {
- uint16_t sp; /**< Source port. */
- uint16_t dp; /**< Destination port. */
-};
-
-/** Pre-computed VXLAN header fields for encapsulation action. */
-struct rte_table_action_vxlan_hdr {
- uint32_t vni; /**< VXLAN Network Identifier (VNI). */
-};
-
-/** Ether encap parameters. */
-struct rte_table_action_encap_ether_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
-};
-
-/** VLAN encap parameters. */
-struct rte_table_action_encap_vlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-};
-
-/** QinQ encap parameters. */
-struct rte_table_action_encap_qinq_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
-};
-
-/** Max number of MPLS labels per output packet for MPLS encapsulation. */
-#ifndef RTE_TABLE_ACTION_MPLS_LABELS_MAX
-#define RTE_TABLE_ACTION_MPLS_LABELS_MAX 4
-#endif
-
-/** MPLS encap parameters. */
-struct rte_table_action_encap_mpls_params {
- /** Ethernet header. */
- struct rte_table_action_ether_hdr ether;
-
- /** MPLS header. */
- struct rte_table_action_mpls_hdr mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
-
- /** Number of MPLS labels in MPLS header. */
- uint32_t mpls_count;
-
- /** Non-zero for MPLS unicast, zero for MPLS multicast. */
- int unicast;
-};
-
-/** PPPoE encap parameters. */
-struct rte_table_action_encap_pppoe_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** VXLAN encap parameters. */
-struct rte_table_action_encap_vxlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-
- union {
- struct rte_table_action_ipv4_header ipv4; /**< IPv4 header. */
- struct rte_table_action_ipv6_header ipv6; /**< IPv6 header. */
- };
-
- struct rte_table_action_udp_header udp; /**< UDP header. */
- struct rte_table_action_vxlan_hdr vxlan; /**< VXLAN header. */
-};
-
-/** Encap action configuration (per table action profile). */
-struct rte_table_action_encap_config {
- /** Bit mask defining the set of packet encapsulations enabled for the
- * current table action profile. If bit (1 << N) is set in *encap_mask*,
- * then packet encapsulation N is enabled, otherwise it is disabled.
- *
- * @see enum rte_table_action_encap_type
- */
- uint64_t encap_mask;
-
- /** Encapsulation type specific configuration. */
- union {
- struct {
- /** Input packet to be encapsulated: offset within the
- * input packet buffer to the start of the Ethernet
- * frame to be encapsulated. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- /** Encapsulation header: non-zero when encapsulation
- * header includes a VLAN tag, zero otherwise.
- */
- int vlan;
-
- /** Encapsulation header: IP version of the IP header
- * within the encapsulation header. Non-zero for IPv4,
- * zero for IPv6.
- */
- int ip_version;
- } vxlan; /**< VXLAN specific configuration. */
- };
-};
-
-/** QinQ_PPPoE encap parameters. */
-struct rte_table_encap_ether_qinq_pppoe {
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_ether_hdr ether;
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** Encap action parameters (per table rule). */
-struct rte_table_action_encap_params {
- /** Encapsulation type. */
- enum rte_table_action_encap_type type;
-
- union {
- /** Only valid when *type* is set to Ether. */
- struct rte_table_action_encap_ether_params ether;
-
- /** Only valid when *type* is set to VLAN. */
- struct rte_table_action_encap_vlan_params vlan;
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_encap_qinq_params qinq;
-
- /** Only valid when *type* is set to MPLS. */
- struct rte_table_action_encap_mpls_params mpls;
-
- /** Only valid when *type* is set to PPPoE. */
- struct rte_table_action_encap_pppoe_params pppoe;
-
- /** Only valid when *type* is set to VXLAN. */
- struct rte_table_action_encap_vxlan_params vxlan;
-
- /** Only valid when *type* is set to QinQ_PPPoE. */
- struct rte_table_encap_ether_qinq_pppoe qinq_pppoe;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-/** NAT action configuration (per table action profile). */
-struct rte_table_action_nat_config {
- /** When non-zero, the IP source address and L4 protocol source port are
- * translated. When zero, the IP destination address and L4 protocol
- * destination port are translated.
- */
- int source_nat;
-
- /** Layer 4 protocol, for example TCP (0x06) or UDP (0x11). The checksum
- * field is computed differently and placed at different header offset
- * by each layer 4 protocol.
- */
- uint8_t proto;
-};
-
-/** NAT action parameters (per table rule). */
-struct rte_table_action_nat_params {
- /** IP version for *addr*: non-zero for IPv4, zero for IPv6. */
- int ip_version;
-
- /** IP address. */
- union {
- /** IPv4 address; only valid when *ip_version* is non-zero. */
- uint32_t ipv4;
-
- /** IPv6 address; only valid when *ip_version* is set to 0. */
- struct rte_ipv6_addr ipv6;
- } addr;
-
- /** Port. */
- uint16_t port;
-};
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-/** TTL action configuration (per table action profile). */
-struct rte_table_action_ttl_config {
- /** When non-zero, the input packets whose updated IPv4 Time to Live
- * (TTL) field or IPv6 Hop Limit (HL) field is zero are dropped.
- * When zero, the input packets whose updated IPv4 TTL field or IPv6 HL
- * field is zero are forwarded as usual (typically for debugging
- * purpose).
- */
- int drop;
-
- /** When non-zero, the *n_packets* stats counter for TTL action is
- * enabled, otherwise disabled.
- *
- * @see struct rte_table_action_ttl_counters
- */
- int n_packets_enabled;
-};
-
-/** TTL action parameters (per table rule). */
-struct rte_table_action_ttl_params {
- /** When non-zero, decrement the IPv4 TTL field and update the checksum
- * field, or decrement the IPv6 HL field. When zero, the IPv4 TTL field
- * or the IPv6 HL field is not changed.
- */
- int decrement;
-};
-
-/** TTL action statistics packets (per table rule). */
-struct rte_table_action_ttl_counters {
- /** Number of IPv4 packets whose updated TTL field is zero or IPv6
- * packets whose updated HL field is zero.
- */
- uint64_t n_packets;
-};
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-/** Stats action configuration (per table action profile). */
-struct rte_table_action_stats_config {
- /** When non-zero, the *n_packets* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_bytes_enabled;
-};
-
-/** Stats action parameters (per table rule). */
-struct rte_table_action_stats_params {
- /** Initial value for the *n_packets* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_packets;
-
- /** Initial value for the *n_bytes* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_bytes;
-};
-
-/** Stats action counters (per table rule). */
-struct rte_table_action_stats_counters {
- /** Number of packets. Valid only when *n_packets_valid* is non-zero. */
- uint64_t n_packets;
-
- /** Number of bytes. Valid only when *n_bytes_valid* is non-zero. */
- uint64_t n_bytes;
-
- /** When non-zero, the *n_packets* field is valid, otherwise invalid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid, otherwise invalid. */
- int n_bytes_valid;
-};
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-/** Timestamp action parameters (per table rule). */
-struct rte_table_action_time_params {
- /** Initial timestamp value. Typically set to current time. */
- uint64_t time;
-};
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET \
- (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
-#endif
-
-/** Common action structure to store the data's value, length, and offset */
-struct rte_table_action_vlo {
- uint8_t *val;
- uint32_t length;
- uint32_t offset;
-};
-
-/** Symmetric crypto action configuration (per table action profile). */
-struct rte_table_action_sym_crypto_config {
- /** Target Cryptodev ID. */
- uint8_t cryptodev_id;
-
- /**
- * Offset to rte_crypto_op structure within the input packet buffer.
- * Offset 0 points to the first byte of the MBUF structure.
- */
- uint32_t op_offset;
-
- /** The mempool for creating cryptodev sessions. */
- struct rte_mempool *mp_create;
-
- /** The mempool for initializing cryptodev sessions. */
- struct rte_mempool *mp_init;
-};
-
-/** Symmetric Crypto action parameters (per table rule). */
-struct rte_table_action_sym_crypto_params {
-
- /** Xform pointer contains all relevant information */
- struct rte_crypto_sym_xform *xform;
-
- /**
- * Offset within the input packet buffer to the first byte of data
- * to be processed by the crypto unit. Offset 0 points to the first
- * byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- union {
- struct {
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv;
-
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv_update;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv_update;
-
- } cipher_auth;
-
- struct {
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv;
-
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad_update;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv_update;
-
- } aead;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-/** Tag action parameters (per table rule). */
-struct rte_table_action_tag_params {
- /** Tag to be attached to the input packet. */
- uint32_t tag;
-};
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-/** Decap action parameters (per table rule). */
-struct rte_table_action_decap_params {
- /** Number of bytes to be removed from the start of the packet. */
- uint16_t n;
-};
-
-/**
- * Table action profile.
- */
-struct rte_table_action_profile;
-
-/**
- * Table action profile create.
- *
- * @param[in] common
- * Common action configuration.
- * @return
- * Table action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common);
-
-/**
- * Table action profile free.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile);
-
-/**
- * Table action profile action register.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @param[in] type
- * Specific table action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_table_action_*type*_config is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config);
-
-/**
- * Table action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * table action objects.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile);
-
-/**
- * Table action.
- */
-struct rte_table_action;
-
-/**
- * Table action create.
- *
- * Instantiates the given table action profile to create a table action object.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new table
- * action object should be allocated.
- * @return
- * Handle to table action object on success, NULL on error.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Table action free.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_free(struct rte_table_action *action);
-
-/**
- * Table action table params get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[inout] params
- * Pipeline table parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params);
-
-/**
- * Table action apply.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) to apply action *type* on.
- * @param[in] type
- * Specific table action previously registered for the table action profile of
- * the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_table_action_*type*_params is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params);
-
-/**
- * Table action DSCP table update.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] dscp_mask
- * 64-bit mask defining the DSCP table entries to be updated. If bit N is set
- * in this bit mask, then DSCP table entry N is to be updated, otherwise not.
- * @param[in] table
- * DSCP table.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table);
-
-/**
- * Table action meter profile add.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID to be used for the *profile* once it is successfully added
- * to the *action* object (needs to be unused by the set of meter profiles
- * currently registered for the *action* object).
- * @param[in] profile
- * Meter profile to be added.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-/**
- * Table action meter profile delete.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID of the meter profile to be deleted from the *action*
- * object (needs to be valid for the *action* object).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id);
-
-/**
- * Table action meter read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with meter action previously
- * applied on it.
- * @param[in] tc_mask
- * Bit mask defining which traffic classes should have the meter stats
- * counters read from *data* and stored into *stats*. If bit N is set in this
- * bit mask, then traffic class N is part of this operation, otherwise it is
- * not. If bit N is set in this bit mask, then traffic class N must be one of
- * the traffic classes that are enabled for the meter action in the table
- * action profile used by the *action* object.
- * @param[inout] stats
- * When non-NULL, it points to the area where the meter stats counters read
- * from *data* are saved. Only the meter stats counters for the *tc_mask*
- * traffic classes are read and stored to *stats*.
- * @param[in] clear
- * When non-zero, the meter stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-/**
- * Table action TTL read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with TTL action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the TTL stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the TTL stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-/**
- * Table action stats read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with stats action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the stats counters are cleared (i.e. set to zero), otherwise
- * the counters are not modified. When the read operation is enabled (*stats*
- * is non-NULL), the clear operation is performed after the read operation is
- * completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-/**
- * Table action timestamp read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with timestamp action
- * previously applied on it.
- * @param[inout] timestamp
- * Pre-allocated memory where the timestamp read from *data* is saved (has to
- * be non-NULL).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp);
-
-/**
- * Table action cryptodev symmetric session get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with sym crypto action.
- * @return
- * The pointer to the session on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_TABLE_ACTION_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [RFC v2 6/6] port: remove legacy API
2026-07-27 23:11 ` [RFC v2 0/6] remove legacy packet framework Stephen Hemminger
` (3 preceding siblings ...)
2026-07-27 23:11 ` [RFC v2 4/6] pipeline: remove legacy API Stephen Hemminger
@ 2026-07-27 23:11 ` Stephen Hemminger
4 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-27 23:11 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy port library API (rte_port_*) as announced for
removal in the 24.11 release. The SWX port API remains.
The sched, ip_frag, cryptodev and eventdev dependencies were only
used by the legacy port types, so drop them. The pcap dependency
is kept for the SWX source/sink port.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 7 -
doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
doc/guides/prog_guide/packet_framework.rst | 132 +---
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 3 +
lib/port/meson.build | 22 +-
lib/port/port_log.c | 7 -
lib/port/port_log.h | 11 -
lib/port/rte_port.h | 223 ------
lib/port/rte_port_ethdev.c | 530 --------------
lib/port/rte_port_ethdev.h | 75 --
lib/port/rte_port_eventdev.c | 590 ---------------
lib/port/rte_port_eventdev.h | 94 ---
lib/port/rte_port_fd.c | 524 --------------
lib/port/rte_port_fd.h | 74 --
lib/port/rte_port_frag.c | 280 --------
lib/port/rte_port_frag.h | 70 --
lib/port/rte_port_ras.c | 336 ---------
lib/port/rte_port_ras.h | 58 --
lib/port/rte_port_ring.c | 796 ---------------------
lib/port/rte_port_ring.h | 91 ---
lib/port/rte_port_sched.c | 298 --------
lib/port/rte_port_sched.h | 52 --
lib/port/rte_port_source_sink.c | 616 ----------------
lib/port/rte_port_source_sink.h | 57 --
lib/port/rte_port_sym_crypto.c | 558 ---------------
lib/port/rte_port_sym_crypto.h | 92 ---
27 files changed, 10 insertions(+), 5591 deletions(-)
delete mode 100644 doc/guides/prog_guide/img/figure32.png
delete mode 100644 lib/port/port_log.c
delete mode 100644 lib/port/port_log.h
delete mode 100644 lib/port/rte_port.h
delete mode 100644 lib/port/rte_port_ethdev.c
delete mode 100644 lib/port/rte_port_ethdev.h
delete mode 100644 lib/port/rte_port_eventdev.c
delete mode 100644 lib/port/rte_port_eventdev.h
delete mode 100644 lib/port/rte_port_fd.c
delete mode 100644 lib/port/rte_port_fd.h
delete mode 100644 lib/port/rte_port_frag.c
delete mode 100644 lib/port/rte_port_frag.h
delete mode 100644 lib/port/rte_port_ras.c
delete mode 100644 lib/port/rte_port_ras.h
delete mode 100644 lib/port/rte_port_ring.c
delete mode 100644 lib/port/rte_port_ring.h
delete mode 100644 lib/port/rte_port_sched.c
delete mode 100644 lib/port/rte_port_sched.h
delete mode 100644 lib/port/rte_port_source_sink.c
delete mode 100644 lib/port/rte_port_source_sink.h
delete mode 100644 lib/port/rte_port_sym_crypto.c
delete mode 100644 lib/port/rte_port_sym_crypto.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 760b770d6f..16827a602b 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -182,13 +182,6 @@ The public API headers are grouped by topics:
[bitmap](@ref rte_bitmap.h)
- **packet framework**:
- * [port](@ref rte_port.h):
- [ethdev](@ref rte_port_ethdev.h),
- [ring](@ref rte_port_ring.h),
- [frag](@ref rte_port_frag.h),
- [reass](@ref rte_port_ras.h),
- [sched](@ref rte_port_sched.h),
- [src/sink](@ref rte_port_source_sink.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/img/figure32.png b/doc/guides/prog_guide/img/figure32.png
deleted file mode 100644
index 5215113fd9d533ff56526e21e1832bc7a6cabd04..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 11603
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
XpF?WbPu~YeLUe8#Xq8>R7xljYKq0l$
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index 98cf3be109..3b5ede7dc2 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -4,132 +4,12 @@
Packet Framework Library
========================
-Design Objectives
------------------
-
-The main design objectives for the DPDK Packet Framework are:
-
-* Provide standard methodology to build complex packet processing pipelines.
- Provide reusable and extensible templates for the commonly used pipeline functional blocks;
-
-* Provide capability to switch between pure software and hardware-accelerated implementations for the same pipeline functional block;
-
-* Provide the best trade-off between flexibility and performance.
- Hardcoded pipelines usually provide the best performance, but are not flexible,
- while developing flexible frameworks is never a problem, but performance is usually low;
-
-* Provide a framework that is logically similar to Open Flow.
-
-Overview
---------
-
-Packet processing applications are frequently structured as pipelines of multiple stages,
-with the logic of each stage glued around a lookup table.
-For each incoming packet, the table defines the set of actions to be applied to the packet,
-as well as the next stage to send the packet to.
-
-The DPDK Packet Framework minimizes the development effort required to build packet processing pipelines
-by defining a standard methodology for pipeline development,
-as well as providing libraries of reusable templates for the commonly used pipeline blocks.
-
-The pipeline is constructed by connecting the set of input ports with the set of output ports
-through the set of tables in a tree-like topology.
-As a result of lookup operation for the current packet in the current table,
-one of the table entries (on lookup hit) or the default table entry (on lookup miss)
-provides the set of actions to be applied on the current packet,
-as well as the next hop for the packet, which can be either another table, an output port or packet drop.
-
-An example of packet processing pipeline is presented in :numref:`packet_framework_figure_32`:
-
-.. _packet_framework_figure_32:
-
-.. figure:: img/figure32.*
-
- Example of Packet Processing Pipeline where Input Ports 0 and 1
- are Connected with Output Ports 0, 1 and 2 through Tables 0 and 1
-
-
-Port Library Design
--------------------
-
-Port Types
-~~~~~~~~~~
-
-:numref:`packet_framework_table_qos_19` is a non-exhaustive list of ports
-that can be implemented with the Packet Framework.
-
-.. _packet_framework_table_qos_19:
-
-.. table:: Port Types
-
- +---+------------------+---------------------------------------------------------------------------------------+
- | # | Port type | Description |
- | | | |
- +===+==================+=======================================================================================+
- | 1 | SW ring | SW circular buffer used for message passing between the application threads. Uses |
- | | | the DPDK rte_ring primitive. Expected to be the most commonly used type of |
- | | | port. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 2 | HW ring | Queue of buffer descriptors used to interact with NIC, switch or accelerator ports. |
- | | | For NIC ports, it uses the DPDK rte_eth_rx_queue or rte_eth_tx_queue |
- | | | primitives. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 3 | IP reassembly | Input packets are either IP fragments or complete IP datagrams. Output packets are |
- | | | complete IP datagrams. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 4 | IP fragmentation | Input packets are jumbo (IP datagrams with length bigger than MTU) or non-jumbo |
- | | | packets. Output packets are non-jumbo packets. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 5 | Traffic manager | Traffic manager attached to a specific NIC output port, performing congestion |
- | | | management and hierarchical scheduling according to pre-defined SLAs. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 6 | Source | Input port used as packet generator. Similar to Linux kernel /dev/zero character |
- | | | device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 7 | Sink | Output port used to drop all input packets. Similar to Linux kernel /dev/null |
- | | | character device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 8 | Sym_crypto | Output port used to extract DPDK Cryptodev operations from a fixed offset of the |
- | | | packet and then enqueue to the Cryptodev PMD. Input port used to dequeue the |
- | | | Cryptodev operations from the Cryptodev PMD and then retrieve the packets from them. |
- +---+------------------+---------------------------------------------------------------------------------------+
-
-Port Interface
-~~~~~~~~~~~~~~
-
-Each port is unidirectional, i.e. either input port or output port.
-Each input/output port is required to implement an abstract interface that
-defines the initialization and run-time operation of the port.
-The port abstract interface is described below.
-
-.. table:: 20 Port Abstract Interface
-
- +---+----------------+-----------------------------------------------------------------------------------------+
- | # | Port Operation | Description |
- | | | |
- +===+================+=========================================================================================+
- | 1 | Create | Create the low-level port object (e.g. queue). Can internally allocate memory. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 2 | Free | Free the resources (e.g. memory) used by the low-level port object. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 3 | RX | Read a burst of input packets. Non-blocking operation. Only defined for input ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 4 | TX | Write a burst of input packets. Non-blocking operation. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 5 | Flush | Flush the output buffer. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
+The Packet Framework is a set of libraries (port, table and pipeline)
+for building flexible packet processing pipelines:
+the pipeline is constructed by connecting a set of input ports
+with a set of output ports through a set of match-action tables.
+The current framework API is the Software Switch (SWX) pipeline
+described below.
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9dcf86098f..75b56b0e10 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* port: The port library legacy API (functions rte_port_*)
- will be deprecated and subsequently removed in DPDK 24.11 release.
- Before this, the new port library API (functions rte_swx_port_*)
- will gradually transition from experimental to stable status.
-
* bus/vmbus: Starting DPDK 25.11, all the vmbus API defined in
``drivers/bus/vmbus/rte_bus_vmbus.h`` will become internal to DPDK.
Those API functions are used internally by DPDK core and netvsc PMD.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 50b0d3ac06..31b075b3cc 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -91,6 +91,9 @@ Removed Items
* Removed the legacy table library API (``rte_table_*`` functions).
The SWX table API (``rte_swx_table_*``) remains.
+* Removed the legacy port library API (``rte_port_*`` functions).
+ The SWX port API (``rte_swx_port_*``) remains.
+
API Changes
-----------
diff --git a/lib/port/meson.build b/lib/port/meson.build
index b597772872..ef88b917a3 100644
--- a/lib/port/meson.build
+++ b/lib/port/meson.build
@@ -8,39 +8,19 @@ if is_windows
endif
sources = files(
- 'port_log.c',
- 'rte_port_ethdev.c',
- 'rte_port_fd.c',
- 'rte_port_frag.c',
- 'rte_port_ras.c',
- 'rte_port_ring.c',
- 'rte_port_sched.c',
- 'rte_port_source_sink.c',
- 'rte_port_sym_crypto.c',
- 'rte_port_eventdev.c',
'rte_swx_port_ethdev.c',
'rte_swx_port_fd.c',
'rte_swx_port_ring.c',
'rte_swx_port_source_sink.c',
)
headers = files(
- 'rte_port_ethdev.h',
- 'rte_port_fd.h',
- 'rte_port_frag.h',
- 'rte_port_ras.h',
- 'rte_port.h',
- 'rte_port_ring.h',
- 'rte_port_sched.h',
- 'rte_port_source_sink.h',
- 'rte_port_sym_crypto.h',
- 'rte_port_eventdev.h',
'rte_swx_port.h',
'rte_swx_port_ethdev.h',
'rte_swx_port_fd.h',
'rte_swx_port_ring.h',
'rte_swx_port_source_sink.h',
)
-deps += ['ethdev', 'sched', 'ip_frag', 'cryptodev', 'eventdev']
+deps += ['ethdev']
if dpdk_conf.has('RTE_HAS_LIBPCAP')
dpdk_conf.set('RTE_PORT_PCAP', 1)
diff --git a/lib/port/port_log.c b/lib/port/port_log.c
deleted file mode 100644
index e7a10d80ef..0000000000
--- a/lib/port/port_log.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2024 Stephen Hemminger <stephen@networkplumber.org>
- */
-
-#include <rte_log.h>
-
-RTE_LOG_REGISTER_DEFAULT(port_logtype, INFO);
diff --git a/lib/port/port_log.h b/lib/port/port_log.h
deleted file mode 100644
index 28d75ee48b..0000000000
--- a/lib/port/port_log.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2023 Red Hat, Inc.
- */
-
-#include <rte_log.h>
-
-extern int port_logtype;
-#define RTE_LOGTYPE_PORT port_logtype
-
-#define PORT_LOG(level, ...) \
- RTE_LOG_LINE(level, PORT, "" __VA_ARGS__)
diff --git a/lib/port/rte_port.h b/lib/port/rte_port.h
deleted file mode 100644
index 81f57c41a5..0000000000
--- a/lib/port/rte_port.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_H__
-#define __INCLUDE_RTE_PORT_H__
-
-/**
- * @file
- * RTE Port
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard interface to implement different types of packet ports.
- */
-
-#include <stdint.h>
-#include <rte_mbuf.h>
-
-/**@{
- * Macros to allow accessing metadata stored in the mbuf headroom
- * just beyond the end of the mbuf data structure returned by a port
- */
-#define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset) \
- (&((uint8_t *)(mbuf))[offset])
-#define RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset) \
- ((uint16_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset) \
- ((uint32_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset) \
- ((uint64_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-
-#define RTE_MBUF_METADATA_UINT8(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT16(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset))
-/**@}*/
-
-/*
- * Port IN
- */
-/** Maximum number of packets read from any input port in a single burst.
-Cannot be changed. */
-#define RTE_PORT_IN_BURST_SIZE_MAX 64
-
-/** Input port statistics */
-struct rte_port_in_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Input port create
- *
- * @param params
- * Parameters for input port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to input port instance
- */
-typedef void* (*rte_port_in_op_create)(void *params, int socket_id);
-
-/**
- * Input port free
- *
- * @param port
- * Handle to input port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_free)(void *port);
-
-/**
- * Input port packet burst RX
- *
- * @param port
- * Handle to input port instance
- * @param pkts
- * Burst of input packets
- * @param n_pkts
- * Number of packets in the input burst
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_rx)(
- void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts);
-
-/**
- * Input port stats get
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_in stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_in_op_stats_read)(
- void *port,
- struct rte_port_in_stats *stats,
- int clear);
-
-/** Input port interface defining the input port operation */
-struct rte_port_in_ops {
- rte_port_in_op_create f_create; /**< Create */
- rte_port_in_op_free f_free; /**< Free */
- rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
- rte_port_in_op_stats_read f_stats; /**< Stats */
-};
-
-/*
- * Port OUT
- */
-/** Output port statistics */
-struct rte_port_out_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Output port create
- *
- * @param params
- * Parameters for output port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to output port instance
- */
-typedef void* (*rte_port_out_op_create)(void *params, int socket_id);
-
-/**
- * Output port free
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_free)(void *port);
-
-/**
- * Output port single packet TX
- *
- * @param port
- * Handle to output port instance
- * @param pkt
- * Input packet
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx)(
- void *port,
- struct rte_mbuf *pkt);
-
-/**
- * Output port packet burst TX
- *
- * @param port
- * Handle to output port instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx_bulk)(
- void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask);
-
-/**
- * Output port flush
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_flush)(void *port);
-
-/**
- * Output port stats read
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_out stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_out_op_stats_read)(
- void *port,
- struct rte_port_out_stats *stats,
- int clear);
-
-/** Output port interface defining the output port operation */
-struct rte_port_out_ops {
- rte_port_out_op_create f_create; /**< Create */
- rte_port_out_op_free f_free; /**< Free */
- rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
- rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
- rte_port_out_op_flush f_flush; /**< Flush */
- rte_port_out_op_stats_read f_stats; /**< Stats */
-};
-
-#endif
diff --git a/lib/port/rte_port_ethdev.c b/lib/port/rte_port_ethdev.c
deleted file mode 100644
index bdab2fbf6c..0000000000
--- a/lib/port/rte_port_ethdev.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ethdev.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ethdev.h"
-
-#include "port_log.h"
-
-/*
- * Port ETHDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_reader {
- struct rte_port_in_stats stats;
-
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_reader_params *conf =
- params;
- struct rte_port_ethdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
-
- return port;
-}
-
-static int
-rte_port_ethdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ethdev_reader *p =
- port;
- uint16_t rx_pkt_cnt;
-
- rx_pkt_cnt = rte_eth_rx_burst(p->port_id, p->queue_id, pkts, n_pkts);
- RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(p, rx_pkt_cnt);
- return rx_pkt_cnt;
-}
-
-static int
-rte_port_ethdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ethdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_params *conf =
- params;
- struct rte_port_ethdev_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_ethdev_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst(p);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_flush(void *port)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_nodrop_params *conf =
- params;
- struct rte_port_ethdev_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ethdev_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id, p->tx_buf,
- p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf + nb_tx, p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to send all packets in single burst,
- * move remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ethdev_reader_ops)
-struct rte_port_in_ops rte_port_ethdev_reader_ops = {
- .f_create = rte_port_ethdev_reader_create,
- .f_free = rte_port_ethdev_reader_free,
- .f_rx = rte_port_ethdev_reader_rx,
- .f_stats = rte_port_ethdev_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_ops = {
- .f_create = rte_port_ethdev_writer_create,
- .f_free = rte_port_ethdev_writer_free,
- .f_tx = rte_port_ethdev_writer_tx,
- .f_tx_bulk = rte_port_ethdev_writer_tx_bulk,
- .f_flush = rte_port_ethdev_writer_flush,
- .f_stats = rte_port_ethdev_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops = {
- .f_create = rte_port_ethdev_writer_nodrop_create,
- .f_free = rte_port_ethdev_writer_nodrop_free,
- .f_tx = rte_port_ethdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ethdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ethdev_writer_nodrop_flush,
- .f_stats = rte_port_ethdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ethdev.h b/lib/port/rte_port_ethdev.h
deleted file mode 100644
index 7729ff0da3..0000000000
--- a/lib/port/rte_port_ethdev.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_ETHDEV_H__
-#define __INCLUDE_RTE_PORT_ETHDEV_H__
-
-/**
- * @file
- * RTE Port Ethernet Device
- *
- * ethdev_reader: input port built on top of pre-initialized NIC RX queue
- * ethdev_writer: output port built on top of pre-initialized NIC TX queue
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ethdev_reader port parameters */
-struct rte_port_ethdev_reader_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-};
-
-/** ethdev_reader port operations */
-extern struct rte_port_in_ops rte_port_ethdev_reader_ops;
-
-/** ethdev_writer port parameters */
-struct rte_port_ethdev_writer_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ethdev_writer port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_ops;
-
-/** ethdev_writer_nodrop port parameters */
-struct rte_port_ethdev_writer_nodrop_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ethdev_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_eventdev.c b/lib/port/rte_port_eventdev.c
deleted file mode 100644
index c3a287b834..0000000000
--- a/lib/port/rte_port_eventdev.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_eventdev.h"
-
-#include "port_log.h"
-
-/*
- * Port EVENTDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_reader {
- struct rte_port_in_stats stats;
-
- uint8_t eventdev_id;
- uint16_t port_id;
-
- struct rte_event ev[RTE_PORT_IN_BURST_SIZE_MAX];
-};
-
-static void *
-rte_port_eventdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_reader_params *conf =
- params;
- struct rte_port_eventdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
-
- return port;
-}
-
-static int
-rte_port_eventdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_eventdev_reader *p = port;
- uint16_t rx_evts_cnt, i;
-
- rx_evts_cnt = rte_event_dequeue_burst(p->eventdev_id, p->port_id,
- p->ev, n_pkts, 0);
-
- for (i = 0; i < rx_evts_cnt; i++)
- pkts[i] = p->ev[i].mbuf;
-
- RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(p, rx_evts_cnt);
-
- return rx_evts_cnt;
-}
-
-static int
-rte_port_eventdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_eventdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
-
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-static void *
-rte_port_eventdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_params *conf =
- params;
- struct rte_port_eventdev_writer *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_eventdev_writer *p)
-{
- uint32_t nb_enq;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->enq_buf_count -
- nb_enq);
-
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst(p);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[2 * RTE_PORT_IN_BURST_SIZE_MAX] = {};
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p,
- n_pkts - n_enq_ok);
- for (; n_enq_ok < n_pkts; n_enq_ok++)
- rte_pktmbuf_free(pkts[n_enq_ok]);
-
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_flush(void *port)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-
-static void *
-rte_port_eventdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_nodrop_params *conf =
- params;
- struct rte_port_eventdev_writer_nodrop *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
- /*
- * When n_retries is 0 it means that we should wait for every event to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_eventdev_writer_nodrop *p)
-{
- uint32_t nb_enq, i;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_enq += rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev + nb_enq,
- p->enq_buf_count - nb_enq);
-
- /* We sent all the events in more than one try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
- }
- /* We didn't send the events in maximum allowed attempts */
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->enq_buf_count - nb_enq);
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer_nodrop *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[RTE_PORT_IN_BURST_SIZE_MAX] = {};
-
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- if (n_enq_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to enqueue all events in single burst,
- * move remaining events to the buffer and call send burst.
- */
- for (; n_enq_ok < n_pkts; n_enq_ok++) {
- struct rte_mbuf *pkt = pkts[n_enq_ok];
- p->ev[p->enq_buf_count++].mbuf = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_reader_ops, 19.11)
-struct rte_port_in_ops rte_port_eventdev_reader_ops = {
- .f_create = rte_port_eventdev_reader_create,
- .f_free = rte_port_eventdev_reader_free,
- .f_rx = rte_port_eventdev_reader_rx,
- .f_stats = rte_port_eventdev_reader_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_ops = {
- .f_create = rte_port_eventdev_writer_create,
- .f_free = rte_port_eventdev_writer_free,
- .f_tx = rte_port_eventdev_writer_tx,
- .f_tx_bulk = rte_port_eventdev_writer_tx_bulk,
- .f_flush = rte_port_eventdev_writer_flush,
- .f_stats = rte_port_eventdev_writer_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_nodrop_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops = {
- .f_create = rte_port_eventdev_writer_nodrop_create,
- .f_free = rte_port_eventdev_writer_nodrop_free,
- .f_tx = rte_port_eventdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_eventdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_eventdev_writer_nodrop_flush,
- .f_stats = rte_port_eventdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_eventdev.h b/lib/port/rte_port_eventdev.h
deleted file mode 100644
index d9eccf07d4..0000000000
--- a/lib/port/rte_port_eventdev.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_EVENTDEV_H__
-#define __INCLUDE_RTE_PORT_EVENTDEV_H__
-
-/**
- * @file
- * RTE Port Eventdev Interface
- *
- * eventdev_reader: input port built on top of pre-initialized eventdev
- * interface
- * eventdev_writer: output port built on top of pre-initialized eventdev
- * interface
- */
-
-#include <stdint.h>
-#include <rte_eventdev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Eventdev_reader port parameters */
-struct rte_port_eventdev_reader_params {
- /** Eventdev Device ID */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID */
- uint8_t port_id;
-};
-
-/** Eventdev_reader port operations. */
-extern struct rte_port_in_ops rte_port_eventdev_reader_ops;
-
-/** Eventdev_writer port parameters. */
-struct rte_port_eventdev_writer_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint8_t port_id;
-
- /** Eventdev Queue ID. */
- uint8_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-};
-
-/** Eventdev_writer port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_ops;
-
-/** Event_writer_nodrop port parameters. */
-struct rte_port_eventdev_writer_nodrop_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint16_t port_id;
-
- /** Eventdev Queue ID. */
- uint16_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Eventdev_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_fd.c b/lib/port/rte_port_fd.c
deleted file mode 100644
index dbc9efef1b..0000000000
--- a/lib/port/rte_port_fd.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_fd.h"
-
-#include "port_log.h"
-
-/*
- * Port FD Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_reader {
- struct rte_port_in_stats stats;
- int fd;
- uint32_t mtu;
- struct rte_mempool *mempool;
-};
-
-static void *
-rte_port_fd_reader_create(void *params, int socket_id)
-{
- struct rte_port_fd_reader_params *conf =
- params;
- struct rte_port_fd_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
- if (conf->fd < 0) {
- PORT_LOG(ERR, "%s: Invalid file descriptor", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Invalid MTU", __func__);
- return NULL;
- }
- if (conf->mempool == NULL) {
- PORT_LOG(ERR, "%s: Invalid mempool", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->mtu = conf->mtu;
- port->mempool = conf->mempool;
-
- return port;
-}
-
-static int
-rte_port_fd_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_fd_reader *p = port;
- uint32_t i, j;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void *);
- ssize_t n_bytes;
-
- n_bytes = read(p->fd, pkt_data, (size_t) p->mtu);
- if (n_bytes <= 0)
- break;
-
- pkt->data_len = n_bytes;
- pkt->pkt_len = n_bytes;
- }
-
- for (j = i; j < n_pkts; j++)
- rte_pktmbuf_free(pkts[j]);
-
- RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(p, i);
-
- return i;
-}
-
-static int
-rte_port_fd_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_fd_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_params *conf =
- params;
- struct rte_port_fd_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_fd_writer *p)
-{
- uint32_t i;
-
- for (i = 0; i < p->tx_buf_count; i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret < 0)
- break;
- }
-
- RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_flush(void *port)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t n_retries;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_nodrop_params *conf =
- params;
- struct rte_port_fd_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->fd < 0) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_fd_writer_nodrop *p)
-{
- uint64_t n_retries;
- uint32_t i;
-
- n_retries = 0;
- for (i = 0; (i < p->tx_buf_count) && (n_retries < p->n_retries); i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
-
- for ( ; n_retries < p->n_retries; n_retries++) {
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret)
- break;
- }
- }
-
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_flush(void *port)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_nodrop_flush(port);
- rte_free(port);
-
-return 0;
-}
-
-static int rte_port_fd_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_fd_reader_ops)
-struct rte_port_in_ops rte_port_fd_reader_ops = {
- .f_create = rte_port_fd_reader_create,
- .f_free = rte_port_fd_reader_free,
- .f_rx = rte_port_fd_reader_rx,
- .f_stats = rte_port_fd_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_ops)
-struct rte_port_out_ops rte_port_fd_writer_ops = {
- .f_create = rte_port_fd_writer_create,
- .f_free = rte_port_fd_writer_free,
- .f_tx = rte_port_fd_writer_tx,
- .f_tx_bulk = rte_port_fd_writer_tx_bulk,
- .f_flush = rte_port_fd_writer_flush,
- .f_stats = rte_port_fd_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_fd_writer_nodrop_ops = {
- .f_create = rte_port_fd_writer_nodrop_create,
- .f_free = rte_port_fd_writer_nodrop_free,
- .f_tx = rte_port_fd_writer_nodrop_tx,
- .f_tx_bulk = rte_port_fd_writer_nodrop_tx_bulk,
- .f_flush = rte_port_fd_writer_nodrop_flush,
- .f_stats = rte_port_fd_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_fd.h b/lib/port/rte_port_fd.h
deleted file mode 100644
index 40a5e4a426..0000000000
--- a/lib/port/rte_port_fd.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_FD_H__
-#define __INCLUDE_RTE_PORT_FD_H__
-
-/**
- * @file
- * RTE Port FD Device
- *
- * fd_reader: input port built on top of valid non-blocking file descriptor
- * fd_writer: output port built on top of valid non-blocking file descriptor
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** fd_reader port parameters */
-struct rte_port_fd_reader_params {
- /** File descriptor */
- int fd;
-
- /** Maximum Transfer Unit (MTU) */
- uint32_t mtu;
-
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-};
-
-/** fd_reader port operations */
-extern struct rte_port_in_ops rte_port_fd_reader_ops;
-
-/** fd_writer port parameters */
-struct rte_port_fd_writer_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-};
-
-/** fd_writer port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_ops;
-
-/** fd_writer_nodrop port parameters */
-struct rte_port_fd_writer_nodrop_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** fd_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_frag.c b/lib/port/rte_port_frag.c
deleted file mode 100644
index 9444f5939c..0000000000
--- a/lib/port/rte_port_frag.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-
-#include "rte_port_frag.h"
-
-#include "port_log.h"
-
-/* Max number of fragments per packet allowed */
-#define RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET 0x80
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-typedef int32_t
- (*frag_op)(struct rte_mbuf *pkt_in,
- struct rte_mbuf **pkts_out,
- uint16_t nb_pkts_out,
- uint16_t mtu_size,
- struct rte_mempool *pool_direct,
- struct rte_mempool *pool_indirect);
-
-struct __rte_cache_aligned rte_port_ring_reader_frag {
- struct rte_port_in_stats stats;
-
- /* Input parameters */
- struct rte_ring *ring;
- uint32_t mtu;
- uint32_t metadata_size;
- struct rte_mempool *pool_direct;
- struct rte_mempool *pool_indirect;
-
- /* Internal buffers */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *frags[RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET];
- uint32_t n_pkts;
- uint32_t pos_pkts;
- uint32_t n_frags;
- uint32_t pos_frags;
-
- frag_op f_frag;
-};
-
-static void *
-rte_port_ring_reader_frag_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_reader_frag_params *conf =
- params;
- struct rte_port_ring_reader_frag *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Parameter mtu is invalid", __func__);
- return NULL;
- }
- if (conf->pool_direct == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_direct is NULL",
- __func__);
- return NULL;
- }
- if (conf->pool_indirect == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_indirect is NULL",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port), RTE_CACHE_LINE_SIZE,
- socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->mtu = conf->mtu;
- port->metadata_size = conf->metadata_size;
- port->pool_direct = conf->pool_direct;
- port->pool_indirect = conf->pool_indirect;
-
- port->n_pkts = 0;
- port->pos_pkts = 0;
- port->n_frags = 0;
- port->pos_frags = 0;
-
- port->f_frag = (is_ipv4) ?
- rte_ipv4_fragment_packet : rte_ipv6_fragment_packet;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_ipv4_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_reader_ipv6_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 0);
-}
-
-static int
-rte_port_ring_reader_frag_rx(void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader_frag *p =
- port;
- uint32_t n_pkts_out;
-
- n_pkts_out = 0;
-
- /* Get packets from the "frag" buffer */
- if (p->n_frags >= n_pkts) {
- memcpy(pkts, &p->frags[p->pos_frags], n_pkts * sizeof(void *));
- p->pos_frags += n_pkts;
- p->n_frags -= n_pkts;
-
- return n_pkts;
- }
-
- memcpy(pkts, &p->frags[p->pos_frags], p->n_frags * sizeof(void *));
- n_pkts_out = p->n_frags;
- p->n_frags = 0;
-
- /* Look to "pkts" buffer to get more packets */
- for ( ; ; ) {
- struct rte_mbuf *pkt;
- uint32_t n_pkts_to_provide, i;
- int status;
-
- /* If "pkts" buffer is empty, read packet burst from ring */
- if (p->n_pkts == 0) {
- p->n_pkts = rte_ring_sc_dequeue_burst(p->ring,
- (void **) p->pkts, RTE_PORT_IN_BURST_SIZE_MAX,
- NULL);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(p, p->n_pkts);
- if (p->n_pkts == 0)
- return n_pkts_out;
- p->pos_pkts = 0;
- }
-
- /* Read next packet from "pkts" buffer */
- pkt = p->pkts[p->pos_pkts++];
- p->n_pkts--;
-
- /* If not jumbo, pass current packet to output */
- if (pkt->pkt_len <= p->mtu) {
- pkts[n_pkts_out++] = pkt;
-
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (n_pkts_to_provide == 0)
- return n_pkts;
-
- continue;
- }
-
- /* Fragment current packet into the "frags" buffer */
- status = p->f_frag(
- pkt,
- p->frags,
- RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET,
- p->mtu,
- p->pool_direct,
- p->pool_indirect
- );
-
- if (status < 0) {
- rte_pktmbuf_free(pkt);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(p, 1);
- continue;
- }
-
- p->n_frags = (uint32_t) status;
- p->pos_frags = 0;
-
- /* Copy meta-data from input jumbo packet to its fragments */
- for (i = 0; i < p->n_frags; i++) {
- uint8_t *src =
- RTE_MBUF_METADATA_UINT8_PTR(pkt, sizeof(struct rte_mbuf));
- uint8_t *dst =
- RTE_MBUF_METADATA_UINT8_PTR(p->frags[i], sizeof(struct rte_mbuf));
-
- memcpy(dst, src, p->metadata_size);
- }
-
- /* Free input jumbo packet */
- rte_pktmbuf_free(pkt);
-
- /* Get packets from "frag" buffer */
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (p->n_frags >= n_pkts_to_provide) {
- memcpy(&pkts[n_pkts_out], p->frags,
- n_pkts_to_provide * sizeof(void *));
- p->n_frags -= n_pkts_to_provide;
- p->pos_frags += n_pkts_to_provide;
-
- return n_pkts;
- }
-
- memcpy(&pkts[n_pkts_out], p->frags,
- p->n_frags * sizeof(void *));
- n_pkts_out += p->n_frags;
- p->n_frags = 0;
- }
-}
-
-static int
-rte_port_ring_reader_frag_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_frag_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader_frag *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv4_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops = {
- .f_create = rte_port_ring_reader_ipv4_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv6_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops = {
- .f_create = rte_port_ring_reader_ipv6_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
diff --git a/lib/port/rte_port_frag.h b/lib/port/rte_port_frag.h
deleted file mode 100644
index 9a10f10523..0000000000
--- a/lib/port/rte_port_frag.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IP_FRAG_H__
-#define __INCLUDE_RTE_PORT_IP_FRAG_H__
-
-/**
- * @file
- * RTE Port for IPv4 Fragmentation
- *
- * This port is built on top of pre-initialized single consumer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP fragmentation functionality is executed on ring read operation,
- * hence this port is implemented as an input port. A regular ring_writer port
- * can be created to write to the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or jumbo
- * frames (i.e. IP packets with length bigger than provided MTU value). The
- * packets read from the ring are all non-jumbo frames. The complete IP
- * datagrams written to the ring are not changed. The jumbo frames are
- * fragmented into several IP packets with length less or equal to MTU.
- */
-
-#include <stdint.h>
-
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader_ipv4_frag port parameters */
-struct rte_port_ring_reader_frag_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Maximum Transfer Unit (MTU). Maximum IP packet size (in bytes). */
- uint32_t mtu;
-
- /** Size of application dependent meta-data stored per each input packet
- that has to be copied to each of the fragments originating from the
- same input IP datagram. */
- uint32_t metadata_size;
-
- /** Pre-initialized buffer pool used for allocating direct buffers for
- the output fragments. */
- struct rte_mempool *pool_direct;
-
- /** Pre-initialized buffer pool used for allocating indirect buffers for
- the output fragments. */
- struct rte_mempool *pool_indirect;
-};
-
-#define rte_port_ring_reader_ipv4_frag_params rte_port_ring_reader_frag_params
-
-#define rte_port_ring_reader_ipv6_frag_params rte_port_ring_reader_frag_params
-
-/** ring_reader_ipv4_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops;
-
-/** ring_reader_ipv6_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ras.c b/lib/port/rte_port_ras.c
deleted file mode 100644
index 58ab7a1c5b..0000000000
--- a/lib/port/rte_port_ras.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-#include <rte_cycles.h>
-#include <rte_log.h>
-
-#include "rte_port_ras.h"
-
-#include "port_log.h"
-
-#ifndef RTE_PORT_RAS_N_BUCKETS
-#define RTE_PORT_RAS_N_BUCKETS 4094
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES_PER_BUCKET
-#define RTE_PORT_RAS_N_ENTRIES_PER_BUCKET 8
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES
-#define RTE_PORT_RAS_N_ENTRIES (RTE_PORT_RAS_N_BUCKETS * RTE_PORT_RAS_N_ENTRIES_PER_BUCKET)
-#endif
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_ras;
-
-typedef void (*ras_op)(
- struct rte_port_ring_writer_ras *p,
- struct rte_mbuf *pkt);
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-
-struct rte_port_ring_writer_ras {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- struct rte_ip_frag_tbl *frag_tbl;
- struct rte_ip_frag_death_row death_row;
-
- ras_op f_ras;
-};
-
-static void *
-rte_port_ring_writer_ras_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_writer_ras_params *conf =
- params;
- struct rte_port_ring_writer_ras *port;
- uint64_t frag_cycles;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if ((conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Parameter tx_burst_sz is invalid",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate socket", __func__);
- return NULL;
- }
-
- /* Create fragmentation table */
- frag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * MS_PER_S;
- frag_cycles *= 100;
-
- port->frag_tbl = rte_ip_frag_table_create(
- RTE_PORT_RAS_N_BUCKETS,
- RTE_PORT_RAS_N_ENTRIES_PER_BUCKET,
- RTE_PORT_RAS_N_ENTRIES,
- frag_cycles,
- socket_id);
-
- if (port->frag_tbl == NULL) {
- PORT_LOG(ERR, "%s: rte_ip_frag_table_create failed",
- __func__);
- rte_free(port);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- port->f_ras = (is_ipv4 == 1) ? process_ipv4 : process_ipv6;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_ipv4_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_writer_ipv6_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 0);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer_ras *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv4_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv4_hdr *);
-
- /* Get "More fragments" flag and fragment offset */
- uint16_t frag_field = rte_be_to_cpu_16(pkt_hdr->fragment_offset);
- uint16_t frag_offset = (uint16_t)(frag_field & RTE_IPV4_HDR_OFFSET_MASK);
- uint16_t frag_flag = (uint16_t)(frag_field & RTE_IPV4_HDR_MF_FLAG);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_flag == 0) && (frag_offset == 0))
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr);
-
- /* Process this fragment */
- mo = rte_ipv4_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(),
- pkt_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv6_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv6_hdr *);
-
- struct rte_ipv6_fragment_ext *frag_hdr;
- uint16_t frag_data = 0;
- frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt_hdr);
- if (frag_hdr != NULL)
- frag_data = rte_be_to_cpu_16(frag_hdr->frag_data);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_data & RTE_IPV6_FRAG_USED_MASK) == 0)
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr) + sizeof(*frag_hdr);
-
- /* Process this fragment */
- mo = rte_ipv6_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(), pkt_hdr,
- frag_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static int
-rte_port_ring_writer_ras_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_flush(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_free(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_port_ring_writer_ras_flush(port);
- rte_ip_frag_table_destroy(p->frag_tbl);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ras_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv4_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops = {
- .f_create = rte_port_ring_writer_ipv4_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv6_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops = {
- .f_create = rte_port_ring_writer_ipv6_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
diff --git a/lib/port/rte_port_ras.h b/lib/port/rte_port_ras.h
deleted file mode 100644
index 86e36f5362..0000000000
--- a/lib/port/rte_port_ras.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RAS_H__
-#define __INCLUDE_RTE_PORT_RAS_H__
-
-/**
- * @file
- * RTE Port for IPv4 Reassembly
- *
- * This port is built on top of pre-initialized single producer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP reassembly functionality is executed on ring write operation,
- * hence this port is implemented as an output port. A regular ring_reader port
- * can be created to read from the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or IP
- * fragments. The packets read from the ring are all complete IP datagrams,
- * either jumbo frames (i.e. IP packets with length bigger than MTU) or not.
- * The complete IP datagrams written to the ring are not changed. The IP
- * fragments written to the ring are first reassembled and into complete IP
- * datagrams or dropped on error or IP reassembly time-out.
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_writer_ipv4_ras port parameters */
-struct rte_port_ring_writer_ras_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be bigger
- or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-#define rte_port_ring_writer_ipv4_ras_params rte_port_ring_writer_ras_params
-
-#define rte_port_ring_writer_ipv6_ras_params rte_port_ring_writer_ras_params
-
-/** ring_writer_ipv4_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops;
-
-/** ring_writer_ipv6_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ring.c b/lib/port/rte_port_ring.c
deleted file mode 100644
index 307a576d65..0000000000
--- a/lib/port/rte_port_ring.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ring.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ring.h"
-
-#include "port_log.h"
-
-/*
- * Port RING Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_reader {
- struct rte_port_in_stats stats;
-
- struct rte_ring *ring;
-};
-
-static void *
-rte_port_ring_reader_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_reader_params *conf =
- params;
- struct rte_port_ring_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_cons_single(conf->ring) && is_multi) ||
- (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 1);
-}
-
-static int
-rte_port_ring_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_sc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_multi_reader_rx(void *port, struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_mc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_params *conf =
- params;
- struct rte_port_ring_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
-
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok = rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok = rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_free(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_flush(port);
- else
- rte_port_ring_writer_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop_params *conf =
- params;
- struct rte_port_ring_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_sp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_mp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_nodrop_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
-
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok =
- rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok =
- rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we didn't manage to send all packets in single burst, move
- * remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_free(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_nodrop_flush(port);
- else
- rte_port_ring_writer_nodrop_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ops)
-struct rte_port_in_ops rte_port_ring_reader_ops = {
- .f_create = rte_port_ring_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ops)
-struct rte_port_out_ops rte_port_ring_writer_ops = {
- .f_create = rte_port_ring_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_writer_tx,
- .f_tx_bulk = rte_port_ring_writer_tx_bulk,
- .f_flush = rte_port_ring_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_writer_nodrop_ops = {
- .f_create = rte_port_ring_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_reader_ops)
-struct rte_port_in_ops rte_port_ring_multi_reader_ops = {
- .f_create = rte_port_ring_multi_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_multi_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_ops = {
- .f_create = rte_port_ring_multi_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_multi_writer_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops = {
- .f_create = rte_port_ring_multi_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_multi_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ring.h b/lib/port/rte_port_ring.h
deleted file mode 100644
index 2089d0889b..0000000000
--- a/lib/port/rte_port_ring.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RING_H__
-#define __INCLUDE_RTE_PORT_RING_H__
-
-/**
- * @file
- * RTE Port Ring
- *
- * ring_reader:
- * input port built on top of pre-initialized single consumer ring
- * ring_writer:
- * output port built on top of pre-initialized single producer ring
- * ring_multi_reader:
- * input port built on top of pre-initialized multi consumers ring
- * ring_multi_writer:
- * output port built on top of pre-initialized multi producers ring
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader port parameters */
-struct rte_port_ring_reader_params {
- /** Underlying consumer ring that has to be pre-initialized */
- struct rte_ring *ring;
-};
-
-/** ring_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ops;
-
-/** ring_writer port parameters */
-struct rte_port_ring_writer_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ring_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ops;
-
-/** ring_writer_nodrop port parameters */
-struct rte_port_ring_writer_nodrop_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ring_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_nodrop_ops;
-
-/** ring_multi_reader port parameters */
-#define rte_port_ring_multi_reader_params rte_port_ring_reader_params
-
-/** ring_multi_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_multi_reader_ops;
-
-/** ring_multi_writer port parameters */
-#define rte_port_ring_multi_writer_params rte_port_ring_writer_params
-
-/** ring_multi_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_ops;
-
-/** ring_multi_writer_nodrop port parameters */
-#define rte_port_ring_multi_writer_nodrop_params \
- rte_port_ring_writer_nodrop_params
-
-/** ring_multi_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sched.c b/lib/port/rte_port_sched.c
deleted file mode 100644
index 3091078aa1..0000000000
--- a/lib/port/rte_port_sched.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sched.h"
-
-#include "port_log.h"
-
-/*
- * Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_reader {
- struct rte_port_in_stats stats;
-
- struct rte_sched_port *sched;
-};
-
-static void *
-rte_port_sched_reader_create(void *params, int socket_id)
-{
- struct rte_port_sched_reader_params *conf =
- params;
- struct rte_port_sched_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
-
- return port;
-}
-
-static int
-rte_port_sched_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sched_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_sched_port_dequeue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_READER_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_sched_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sched_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_sched_port *sched;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-};
-
-static void *
-rte_port_sched_writer_create(void *params, int socket_id)
-{
- struct rte_port_sched_writer_params *conf =
- params;
- struct rte_port_sched_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static int
-rte_port_sched_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- __rte_unused uint32_t nb_tx;
- uint64_t n_pkts = rte_popcount64(pkts_mask);
-
- if (tx_buf_count) {
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- nb_tx = rte_sched_port_enqueue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - nb_tx);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
- p->tx_buf_count = tx_buf_count;
-
- if (tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_flush(void *port)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- if (p->tx_buf_count) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sched_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sched_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sched_reader_ops)
-struct rte_port_in_ops rte_port_sched_reader_ops = {
- .f_create = rte_port_sched_reader_create,
- .f_free = rte_port_sched_reader_free,
- .f_rx = rte_port_sched_reader_rx,
- .f_stats = rte_port_sched_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sched_writer_ops)
-struct rte_port_out_ops rte_port_sched_writer_ops = {
- .f_create = rte_port_sched_writer_create,
- .f_free = rte_port_sched_writer_free,
- .f_tx = rte_port_sched_writer_tx,
- .f_tx_bulk = rte_port_sched_writer_tx_bulk,
- .f_flush = rte_port_sched_writer_flush,
- .f_stats = rte_port_sched_writer_stats_read,
-};
diff --git a/lib/port/rte_port_sched.h b/lib/port/rte_port_sched.h
deleted file mode 100644
index 1bf08ae6a9..0000000000
--- a/lib/port/rte_port_sched.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SCHED_H__
-#define __INCLUDE_RTE_PORT_SCHED_H__
-
-/**
- * @file
- * RTE Port Hierarchical Scheduler
- *
- * sched_reader: input port built on top of pre-initialized rte_sched_port
- * sched_writer: output port built on top of pre-initialized rte_sched_port
- */
-
-#include <stdint.h>
-
-#include <rte_sched.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** sched_reader port parameters */
-struct rte_port_sched_reader_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-};
-
-/** sched_reader port operations */
-extern struct rte_port_in_ops rte_port_sched_reader_ops;
-
-/** sched_writer port parameters */
-struct rte_port_sched_writer_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-
- /** Recommended burst size. The actual burst size can be bigger or
- smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** sched_writer port operations */
-extern struct rte_port_out_ops rte_port_sched_writer_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_source_sink.c b/lib/port/rte_port_source_sink.c
deleted file mode 100644
index 0557e12506..0000000000
--- a/lib/port/rte_port_source_sink.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-#include <stdint.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-
-#ifdef RTE_PORT_PCAP
-#include <rte_ether.h>
-#include <pcap.h>
-#endif
-
-#include "rte_port_source_sink.h"
-
-#include "port_log.h"
-
-/*
- * Port SOURCE
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_source {
- struct rte_port_in_stats stats;
-
- struct rte_mempool *mempool;
-
- /* PCAP buffers and indices */
- uint8_t **pkts;
- uint8_t *pkt_buff;
- uint32_t *pkt_len;
- uint32_t n_pkts;
- uint32_t pkt_index;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_source_load(struct rte_port_source *port,
- const char *file_name,
- uint32_t n_bytes_per_pkt,
- int socket_id)
-{
- uint32_t n_pkts = 0;
- uint32_t i;
- uint32_t *pkt_len_aligns = NULL;
- size_t total_buff_len = 0;
- pcap_t *pcap_handle;
- char pcap_errbuf[PCAP_ERRBUF_SIZE];
- uint32_t max_len;
- struct pcap_pkthdr pcap_hdr;
- const uint8_t *pkt;
- uint8_t *buff = NULL;
- uint32_t pktmbuf_maxlen = (uint32_t)
- (rte_pktmbuf_data_room_size(port->mempool) -
- RTE_PKTMBUF_HEADROOM);
-
- if (n_bytes_per_pkt == 0)
- max_len = pktmbuf_maxlen;
- else
- max_len = RTE_MIN(n_bytes_per_pkt, pktmbuf_maxlen);
-
- /* first time open, get packet number */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- while ((pkt = pcap_next(pcap_handle, &pcap_hdr)) != NULL)
- n_pkts++;
-
- pcap_close(pcap_handle);
-
- port->pkt_len = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkt_len) * n_pkts), 0, socket_id);
- if (port->pkt_len == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- pkt_len_aligns = rte_malloc("PCAP",
- (sizeof(*pkt_len_aligns) * n_pkts), 0);
- if (pkt_len_aligns == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkts = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkts) * n_pkts), 0, socket_id);
- if (port->pkts == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- /* open 2nd time, get pkt_len */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pcap_next(pcap_handle, &pcap_hdr);
- port->pkt_len[i] = RTE_MIN(max_len, pcap_hdr.len);
- pkt_len_aligns[i] = RTE_CACHE_LINE_ROUNDUP(
- port->pkt_len[i]);
- total_buff_len += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- /* allocate a big trunk of data for pcap file load */
- buff = rte_zmalloc_socket("PCAP",
- total_buff_len, 0, socket_id);
- if (buff == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkt_buff = buff;
-
- /* open file one last time to copy the pkt content */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pkt = pcap_next(pcap_handle, &pcap_hdr);
- rte_memcpy(buff, pkt, port->pkt_len[i]);
- port->pkts[i] = buff;
- buff += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- port->n_pkts = n_pkts;
-
- rte_free(pkt_len_aligns);
-
- PORT_LOG(INFO, "Successfully load pcap file "
- "'%s' with %u pkts",
- file_name, port->n_pkts);
-
- return 0;
-
-error_exit:
- rte_free(pkt_len_aligns);
- rte_free(port->pkt_len);
- rte_free(port->pkts);
- rte_free(port->pkt_buff);
-
- return -1;
-}
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
- pcap_source_load(port, file_name, n_bytes, socket_id)
-
-#else /* RTE_PORT_PCAP */
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Source port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#endif /* RTE_PORT_PCAP */
-
-static void *
-rte_port_source_create(void *params, int socket_id)
-{
- struct rte_port_source_params *p =
- params;
- struct rte_port_source *port;
-
- /* Check input arguments*/
- if ((p == NULL) || (p->mempool == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->mempool = (struct rte_mempool *) p->mempool;
-
- if (p->file_name) {
- int status = PCAP_SOURCE_LOAD(port, p->file_name,
- p->n_bytes_per_pkt, socket_id);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_source_free(void *port)
-{
- struct rte_port_source *p =
- port;
-
- /* Check input parameters */
- if (p == NULL)
- return 0;
-
- rte_free(p->pkt_len);
- rte_free(p->pkts);
- rte_free(p->pkt_buff);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_source_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_source *p = port;
- uint32_t i;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- if (p->pkt_buff != NULL) {
- for (i = 0; i < n_pkts; i++) {
- uint8_t *pkt_data = rte_pktmbuf_mtod(pkts[i],
- uint8_t *);
-
- rte_memcpy(pkt_data, p->pkts[p->pkt_index],
- p->pkt_len[p->pkt_index]);
- pkts[i]->data_len = p->pkt_len[p->pkt_index];
- pkts[i]->pkt_len = pkts[i]->data_len;
-
- p->pkt_index++;
- if (p->pkt_index >= p->n_pkts)
- p->pkt_index = 0;
- }
- }
-
- RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(p, n_pkts);
-
- return n_pkts;
-}
-
-static int
-rte_port_source_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_source *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port SINK
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val) \
- (port->stats.n_pkts_in += val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val) \
- (port->stats.n_pkts_drop += val)
-
-#else
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sink {
- struct rte_port_out_stats stats;
-
- /* PCAP dumper handle and pkts number */
- void *dumper;
- uint32_t max_pkts;
- uint32_t pkt_index;
- uint32_t dump_finish;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_sink_open(struct rte_port_sink *port,
- const char *file_name,
- uint32_t max_n_pkts)
-{
- pcap_t *tx_pcap;
- pcap_dumper_t *pcap_dumper;
-
- /** Open a dead pcap handler for opening dumper file */
- tx_pcap = pcap_open_dead(DLT_EN10MB, 65535);
- if (tx_pcap == NULL) {
- PORT_LOG(ERR, "Cannot open pcap dead handler");
- return -1;
- }
-
- /* The dumper is created using the previous pcap_t reference */
- pcap_dumper = pcap_dump_open(tx_pcap, file_name);
- if (pcap_dumper == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "\"%s\" for writing", file_name);
- return -1;
- }
-
- port->dumper = pcap_dumper;
- port->max_pkts = max_n_pkts;
- port->pkt_index = 0;
- port->dump_finish = 0;
-
- PORT_LOG(INFO, "Ready to dump packets to file \"%s\"",
- file_name);
-
- return 0;
-}
-
-static void
-pcap_sink_write_pkt(struct rte_port_sink *port, struct rte_mbuf *mbuf)
-{
- uint8_t *pcap_dumper = (port->dumper);
- struct pcap_pkthdr pcap_hdr;
- uint8_t jumbo_pkt_buf[RTE_ETHER_MAX_JUMBO_FRAME_LEN];
- uint8_t *pkt;
-
- /* Maximum num packets already reached */
- if (port->dump_finish)
- return;
-
- pkt = rte_pktmbuf_mtod(mbuf, uint8_t *);
-
- pcap_hdr.len = mbuf->pkt_len;
- pcap_hdr.caplen = pcap_hdr.len;
- gettimeofday(&(pcap_hdr.ts), NULL);
-
- if (mbuf->nb_segs > 1) {
- struct rte_mbuf *jumbo_mbuf;
- uint32_t pkt_index = 0;
-
- /* if packet size longer than RTE_ETHER_MAX_JUMBO_FRAME_LEN,
- * ignore it.
- */
- if (mbuf->pkt_len > RTE_ETHER_MAX_JUMBO_FRAME_LEN)
- return;
-
- for (jumbo_mbuf = mbuf; jumbo_mbuf != NULL;
- jumbo_mbuf = jumbo_mbuf->next) {
- rte_memcpy(&jumbo_pkt_buf[pkt_index],
- rte_pktmbuf_mtod(jumbo_mbuf, uint8_t *),
- jumbo_mbuf->data_len);
- pkt_index += jumbo_mbuf->data_len;
- }
-
- jumbo_pkt_buf[pkt_index] = '\0';
-
- pkt = jumbo_pkt_buf;
- }
-
- pcap_dump(pcap_dumper, &pcap_hdr, pkt);
-
- port->pkt_index++;
-
- if ((port->max_pkts != 0) && (port->pkt_index >= port->max_pkts)) {
- port->dump_finish = 1;
- PORT_LOG(INFO, "Dumped %u packets to file",
- port->pkt_index);
- }
-
-}
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
- pcap_sink_open(port, file_name, max_n_pkts)
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) \
- pcap_sink_write_pkt(port, mbuf)
-
-#define PCAP_SINK_FLUSH_PKT(dumper) \
-do { \
- if (dumper) \
- pcap_dump_flush((pcap_dumper_t *)dumper); \
-} while (0)
-
-#define PCAP_SINK_CLOSE(dumper) \
-do { \
- if (dumper) \
- pcap_dump_close((pcap_dumper_t *)dumper); \
-} while (0)
-
-#else
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Sink port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) {}
-
-#define PCAP_SINK_FLUSH_PKT(dumper)
-
-#define PCAP_SINK_CLOSE(dumper)
-
-#endif
-
-static void *
-rte_port_sink_create(void *params, int socket_id)
-{
- struct rte_port_sink *port;
- struct rte_port_sink_params *p = params;
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- if (!p)
- return port;
-
- if (p->file_name) {
- int status = PCAP_SINK_OPEN(port, p->file_name,
- p->max_n_pkts);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_sink_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sink *p = port;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- if (p->dumper != NULL)
- PCAP_SINK_WRITE_PKT(p, pkt);
- rte_pktmbuf_free(pkt);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
-
- return 0;
-}
-
-static int
-rte_port_sink_tx_bulk(void *port, struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sink *p = port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, n_pkts);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, n_pkts);
-
- if (p->dumper) {
- for (i = 0; i < n_pkts; i++)
- PCAP_SINK_WRITE_PKT(p, pkts[i]);
- }
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- rte_pktmbuf_free(pkt);
- }
-
- } else {
- if (p->dumper) {
- uint64_t dump_pkts_mask = pkts_mask;
- uint32_t pkt_index;
-
- for ( ; dump_pkts_mask; ) {
- pkt_index = rte_ctz64(
- dump_pkts_mask);
- PCAP_SINK_WRITE_PKT(p, pkts[pkt_index]);
- dump_pkts_mask &= ~(1LLU << pkt_index);
- }
- }
-
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
- rte_pktmbuf_free(pkt);
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sink_flush(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_FLUSH_PKT(p->dumper);
-
- return 0;
-}
-
-static int
-rte_port_sink_free(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_CLOSE(p->dumper);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_sink_stats_read(void *port, struct rte_port_out_stats *stats,
- int clear)
-{
- struct rte_port_sink *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_source_ops)
-struct rte_port_in_ops rte_port_source_ops = {
- .f_create = rte_port_source_create,
- .f_free = rte_port_source_free,
- .f_rx = rte_port_source_rx,
- .f_stats = rte_port_source_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sink_ops)
-struct rte_port_out_ops rte_port_sink_ops = {
- .f_create = rte_port_sink_create,
- .f_free = rte_port_sink_free,
- .f_tx = rte_port_sink_tx,
- .f_tx_bulk = rte_port_sink_tx_bulk,
- .f_flush = rte_port_sink_flush,
- .f_stats = rte_port_sink_stats_read,
-};
diff --git a/lib/port/rte_port_source_sink.h b/lib/port/rte_port_source_sink.h
deleted file mode 100644
index 3122dd5038..0000000000
--- a/lib/port/rte_port_source_sink.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-#define __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-
-/**
- * @file
- * RTE Port Source/Sink
- *
- * source: input port that can be used to generate packets
- * sink: output port that drops all packets written to it
- */
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** source port parameters */
-struct rte_port_source_params {
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-
- /** The full path of the pcap file to read packets from */
- const char *file_name;
- /** The number of bytes to be read from each packet in the
- * pcap file. If this value is 0, the whole packet is read;
- * if it is bigger than packet size, the generated packets
- * will contain the whole packet */
- uint32_t n_bytes_per_pkt;
-};
-
-/** source port operations */
-extern struct rte_port_in_ops rte_port_source_ops;
-
-/** sink port parameters */
-struct rte_port_sink_params {
- /** The full path of the pcap file to write the packets to */
- const char *file_name;
- /** The maximum number of packets write to the pcap file.
- * If this value is 0, the "infinite" write will be carried
- * out.
- */
- uint32_t max_n_pkts;
-};
-
-/** sink port operations */
-extern struct rte_port_out_ops rte_port_sink_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sym_crypto.c b/lib/port/rte_port_sym_crypto.c
deleted file mode 100644
index 30c9d1283e..0000000000
--- a/lib/port/rte_port_sym_crypto.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sym_crypto.h"
-
-#include "port_log.h"
-
-/*
- * Port Crypto Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_reader {
- struct rte_port_in_stats stats;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- struct rte_crypto_op *ops[RTE_PORT_IN_BURST_SIZE_MAX];
- rte_port_sym_crypto_reader_callback_fn f_callback;
- void *arg_callback;
-};
-
-static void *
-rte_port_sym_crypto_reader_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_reader_params *conf =
- params;
- struct rte_port_sym_crypto_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->f_callback = conf->f_callback;
- port->arg_callback = conf->arg_callback;
-
- return port;
-}
-
-static int
-rte_port_sym_crypto_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
- uint16_t rx_ops_cnt, i, n = 0;
-
- rx_ops_cnt = rte_cryptodev_dequeue_burst(p->cryptodev_id, p->queue_id,
- p->ops, n_pkts);
-
- for (i = 0; i < rx_ops_cnt; i++) {
- struct rte_crypto_op *op = p->ops[i];
-
- /** Drop failed pkts */
- if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)) {
- rte_pktmbuf_free(op->sym->m_src);
- continue;
- }
-
- pkts[n++] = op->sym->m_src;
- }
-
- if (p->f_callback)
- (*p->f_callback)(pkts, n, p->arg_callback);
-
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(p, n);
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(p, rx_ops_cnt - n);
-
- return n;
-}
-
-static int
-rte_port_sym_crypto_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_params *conf =
- params;
- struct rte_port_sym_crypto_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_sym_crypto_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count -
- nb_tx);
- for (; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_flush(void *port)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_nodrop_params *conf =
- params;
- struct rte_port_sym_crypto_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_sym_crypto_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_cryptodev_enqueue_burst(p->cryptodev_id,
- p->queue_id, p->tx_buf + nb_tx,
- p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p,
- 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_flush(void *port)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_reader_ops)
-struct rte_port_in_ops rte_port_sym_crypto_reader_ops = {
- .f_create = rte_port_sym_crypto_reader_create,
- .f_free = rte_port_sym_crypto_reader_free,
- .f_rx = rte_port_sym_crypto_reader_rx,
- .f_stats = rte_port_sym_crypto_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_ops = {
- .f_create = rte_port_sym_crypto_writer_create,
- .f_free = rte_port_sym_crypto_writer_free,
- .f_tx = rte_port_sym_crypto_writer_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_flush,
- .f_stats = rte_port_sym_crypto_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops = {
- .f_create = rte_port_sym_crypto_writer_nodrop_create,
- .f_free = rte_port_sym_crypto_writer_nodrop_free,
- .f_tx = rte_port_sym_crypto_writer_nodrop_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_nodrop_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_nodrop_flush,
- .f_stats = rte_port_sym_crypto_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_sym_crypto.h b/lib/port/rte_port_sym_crypto.h
deleted file mode 100644
index d03cdc1e8b..0000000000
--- a/lib/port/rte_port_sym_crypto.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-#define __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-
-/**
- * @file
- * RTE Port sym crypto Interface
- *
- * crypto_reader: input port built on top of pre-initialized crypto interface
- * crypto_writer: output port built on top of pre-initialized crypto interface
- */
-
-#include <stdint.h>
-
-#include <rte_cryptodev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Function prototype for reader post action. */
-typedef void (*rte_port_sym_crypto_reader_callback_fn)(struct rte_mbuf **pkts,
- uint16_t n_pkts, void *arg);
-
-/** Crypto_reader port parameters */
-struct rte_port_sym_crypto_reader_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** Crypto reader post callback function. */
- rte_port_sym_crypto_reader_callback_fn f_callback;
-
- /** Crypto reader post callback function arguments. */
- void *arg_callback;
-};
-
-/** Crypto_reader port operations. */
-extern struct rte_port_in_ops rte_port_sym_crypto_reader_ops;
-
-
-/** Crypto_writer port parameters. */
-struct rte_port_sym_crypto_writer_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-};
-
-/** Crypto_writer port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_ops;
-
-/** Crypto_writer_nodrop port parameters. */
-struct rte_port_sym_crypto_writer_nodrop_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev queue pair id. */
- uint16_t queue_id;
-
- /** Offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Crypto_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH v3 0/6] remove legacy packet framework
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (6 preceding siblings ...)
2026-07-27 23:11 ` [RFC v2 0/6] remove legacy packet framework Stephen Hemminger
@ 2026-07-28 14:20 ` Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 1/6] app/test: remove packet framework tests Stephen Hemminger
` (5 more replies)
2026-07-28 16:35 ` [PATCH v4 0/7] remove deprecated " Stephen Hemminger
` (7 subsequent siblings)
15 siblings, 6 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 14:20 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
Remove the legacy packet framework examples and libraries.
This was announced in 24.11 but never completed.
v3 - also cleanup cocci scripts
Stephen Hemminger (6):
app/test: remove packet framework tests
app/test-pipeline: remove application
examples/ip_pipeline: remove example
pipeline: remove legacy API
table: remove legacy API
port: remove legacy API
MAINTAINERS | 5 -
app/meson.build | 1 -
app/test-pipeline/config.c | 230 -
app/test-pipeline/init.c | 273 -
app/test-pipeline/main.c | 188 -
app/test-pipeline/main.h | 132 -
app/test-pipeline/meson.build | 21 -
app/test-pipeline/pipeline_acl.c | 251 -
app/test-pipeline/pipeline_hash.c | 471 --
app/test-pipeline/pipeline_lpm.c | 175 -
app/test-pipeline/pipeline_lpm_ipv6.c | 168 -
app/test-pipeline/pipeline_stub.c | 137 -
app/test-pipeline/runtime.c | 160 -
app/test/meson.build | 6 -
app/test/test_table.c | 209 -
app/test/test_table.h | 184 -
app/test/test_table_acl.c | 728 --
app/test/test_table_acl.h | 6 -
app/test/test_table_combined.c | 846 --
app/test/test_table_combined.h | 27 -
app/test/test_table_pipeline.c | 575 --
app/test/test_table_pipeline.h | 6 -
app/test/test_table_ports.c | 195 -
app/test/test_table_ports.h | 13 -
app/test/test_table_tables.c | 1058 ---
app/test/test_table_tables.h | 22 -
devtools/cocci/nullfree.cocci | 12 -
doc/api/doxy-api-index.md | 17 -
doc/guides/nics/softnic.rst | 3 +-
doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
doc/guides/prog_guide/img/figure33.png | Bin 65216 -> 0 bytes
doc/guides/prog_guide/img/figure34.png | Bin 11581 -> 0 bytes
doc/guides/prog_guide/img/figure35.png | Bin 75012 -> 0 bytes
doc/guides/prog_guide/img/figure37.png | Bin 6934 -> 0 bytes
doc/guides/prog_guide/img/figure38.png | Bin 7372 -> 0 bytes
doc/guides/prog_guide/img/figure39.png | Bin 55986 -> 0 bytes
doc/guides/prog_guide/packet_framework.rst | 1146 +--
doc/guides/rel_notes/deprecation.rst | 15 -
doc/guides/rel_notes/release_26_11.rst | 17 +
.../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
doc/guides/sample_app_ug/index.rst | 2 -
doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
doc/guides/sample_app_ug/test_pipeline.rst | 237 -
examples/ip_pipeline/Makefile | 60 -
examples/ip_pipeline/action.c | 391 -
examples/ip_pipeline/action.h | 78 -
examples/ip_pipeline/cli.c | 6791 -----------------
examples/ip_pipeline/cli.h | 18 -
examples/ip_pipeline/common.h | 12 -
examples/ip_pipeline/conn.c | 330 -
examples/ip_pipeline/conn.h | 47 -
examples/ip_pipeline/cryptodev.c | 160 -
examples/ip_pipeline/cryptodev.h | 46 -
examples/ip_pipeline/examples/firewall.cli | 59 -
examples/ip_pipeline/examples/flow.cli | 60 -
examples/ip_pipeline/examples/flow_crypto.cli | 57 -
examples/ip_pipeline/examples/l2fwd.cli | 51 -
examples/ip_pipeline/examples/route.cli | 60 -
examples/ip_pipeline/examples/route_ecmp.cli | 57 -
examples/ip_pipeline/examples/rss.cli | 112 -
examples/ip_pipeline/examples/tap.cli | 66 -
examples/ip_pipeline/link.c | 270 -
examples/ip_pipeline/link.h | 66 -
examples/ip_pipeline/main.c | 260 -
examples/ip_pipeline/mempool.c | 82 -
examples/ip_pipeline/mempool.h | 40 -
examples/ip_pipeline/meson.build | 30 -
examples/ip_pipeline/parser.c | 506 --
examples/ip_pipeline/parser.h | 56 -
examples/ip_pipeline/pipeline.c | 1078 ---
examples/ip_pipeline/pipeline.h | 425 --
examples/ip_pipeline/swq.c | 76 -
examples/ip_pipeline/swq.h | 37 -
examples/ip_pipeline/tap.c | 102 -
examples/ip_pipeline/tap.h | 29 -
examples/ip_pipeline/thread.c | 3137 --------
examples/ip_pipeline/thread.h | 24 -
examples/ip_pipeline/tmgr.c | 248 -
examples/ip_pipeline/tmgr.h | 74 -
examples/meson.build | 1 -
lib/pipeline/meson.build | 8 +-
lib/pipeline/rte_pipeline.c | 1640 ----
lib/pipeline/rte_pipeline.h | 840 --
lib/pipeline/rte_port_in_action.c | 539 --
lib/pipeline/rte_port_in_action.h | 311 -
lib/pipeline/rte_table_action.c | 3483 ---------
lib/pipeline/rte_table_action.h | 1137 ---
lib/port/meson.build | 22 +-
lib/port/port_log.c | 7 -
lib/port/port_log.h | 11 -
lib/port/rte_port.h | 223 -
lib/port/rte_port_ethdev.c | 530 --
lib/port/rte_port_ethdev.h | 75 -
lib/port/rte_port_eventdev.c | 590 --
lib/port/rte_port_eventdev.h | 94 -
lib/port/rte_port_fd.c | 524 --
lib/port/rte_port_fd.h | 74 -
lib/port/rte_port_frag.c | 280 -
lib/port/rte_port_frag.h | 70 -
lib/port/rte_port_ras.c | 336 -
lib/port/rte_port_ras.h | 58 -
lib/port/rte_port_ring.c | 796 --
lib/port/rte_port_ring.h | 91 -
lib/port/rte_port_sched.c | 298 -
lib/port/rte_port_sched.h | 52 -
lib/port/rte_port_source_sink.c | 616 --
lib/port/rte_port_source_sink.h | 57 -
lib/port/rte_port_sym_crypto.c | 558 --
lib/port/rte_port_sym_crypto.h | 92 -
lib/table/meson.build | 30 +-
lib/table/rte_lru.h | 85 -
lib/table/rte_lru_arm64.h | 61 -
lib/table/rte_lru_x86.h | 96 -
lib/table/rte_table.h | 263 -
lib/table/rte_table_acl.c | 795 --
lib/table/rte_table_acl.h | 65 -
lib/table/rte_table_array.c | 210 -
lib/table/rte_table_array.h | 46 -
lib/table/rte_table_hash.h | 106 -
lib/table/rte_table_hash_cuckoo.c | 327 -
lib/table/rte_table_hash_cuckoo.h | 57 -
lib/table/rte_table_hash_ext.c | 1011 ---
lib/table/rte_table_hash_func.h | 263 -
lib/table/rte_table_hash_func_arm64.h | 21 -
lib/table/rte_table_hash_key16.c | 1190 ---
lib/table/rte_table_hash_key32.c | 1223 ---
lib/table/rte_table_hash_key8.c | 1157 ---
lib/table/rte_table_hash_lru.c | 959 ---
lib/table/rte_table_lpm.c | 369 -
lib/table/rte_table_lpm.h | 94 -
lib/table/rte_table_lpm_ipv6.c | 370 -
lib/table/rte_table_lpm_ipv6.h | 92 -
lib/table/rte_table_stub.c | 95 -
lib/table/rte_table_stub.h | 30 -
lib/table/table_log.c | 7 -
lib/table/table_log.h | 11 -
136 files changed, 27 insertions(+), 45481 deletions(-)
delete mode 100644 app/test-pipeline/config.c
delete mode 100644 app/test-pipeline/init.c
delete mode 100644 app/test-pipeline/main.c
delete mode 100644 app/test-pipeline/main.h
delete mode 100644 app/test-pipeline/meson.build
delete mode 100644 app/test-pipeline/pipeline_acl.c
delete mode 100644 app/test-pipeline/pipeline_hash.c
delete mode 100644 app/test-pipeline/pipeline_lpm.c
delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
delete mode 100644 app/test-pipeline/pipeline_stub.c
delete mode 100644 app/test-pipeline/runtime.c
delete mode 100644 app/test/test_table.c
delete mode 100644 app/test/test_table.h
delete mode 100644 app/test/test_table_acl.c
delete mode 100644 app/test/test_table_acl.h
delete mode 100644 app/test/test_table_combined.c
delete mode 100644 app/test/test_table_combined.h
delete mode 100644 app/test/test_table_pipeline.c
delete mode 100644 app/test/test_table_pipeline.h
delete mode 100644 app/test/test_table_ports.c
delete mode 100644 app/test/test_table_ports.h
delete mode 100644 app/test/test_table_tables.c
delete mode 100644 app/test/test_table_tables.h
delete mode 100644 doc/guides/prog_guide/img/figure32.png
delete mode 100644 doc/guides/prog_guide/img/figure33.png
delete mode 100644 doc/guides/prog_guide/img/figure34.png
delete mode 100644 doc/guides/prog_guide/img/figure35.png
delete mode 100644 doc/guides/prog_guide/img/figure37.png
delete mode 100644 doc/guides/prog_guide/img/figure38.png
delete mode 100644 doc/guides/prog_guide/img/figure39.png
delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
delete mode 100644 examples/ip_pipeline/Makefile
delete mode 100644 examples/ip_pipeline/action.c
delete mode 100644 examples/ip_pipeline/action.h
delete mode 100644 examples/ip_pipeline/cli.c
delete mode 100644 examples/ip_pipeline/cli.h
delete mode 100644 examples/ip_pipeline/common.h
delete mode 100644 examples/ip_pipeline/conn.c
delete mode 100644 examples/ip_pipeline/conn.h
delete mode 100644 examples/ip_pipeline/cryptodev.c
delete mode 100644 examples/ip_pipeline/cryptodev.h
delete mode 100644 examples/ip_pipeline/examples/firewall.cli
delete mode 100644 examples/ip_pipeline/examples/flow.cli
delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
delete mode 100644 examples/ip_pipeline/examples/route.cli
delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
delete mode 100644 examples/ip_pipeline/examples/rss.cli
delete mode 100644 examples/ip_pipeline/examples/tap.cli
delete mode 100644 examples/ip_pipeline/link.c
delete mode 100644 examples/ip_pipeline/link.h
delete mode 100644 examples/ip_pipeline/main.c
delete mode 100644 examples/ip_pipeline/mempool.c
delete mode 100644 examples/ip_pipeline/mempool.h
delete mode 100644 examples/ip_pipeline/meson.build
delete mode 100644 examples/ip_pipeline/parser.c
delete mode 100644 examples/ip_pipeline/parser.h
delete mode 100644 examples/ip_pipeline/pipeline.c
delete mode 100644 examples/ip_pipeline/pipeline.h
delete mode 100644 examples/ip_pipeline/swq.c
delete mode 100644 examples/ip_pipeline/swq.h
delete mode 100644 examples/ip_pipeline/tap.c
delete mode 100644 examples/ip_pipeline/tap.h
delete mode 100644 examples/ip_pipeline/thread.c
delete mode 100644 examples/ip_pipeline/thread.h
delete mode 100644 examples/ip_pipeline/tmgr.c
delete mode 100644 examples/ip_pipeline/tmgr.h
delete mode 100644 lib/pipeline/rte_pipeline.c
delete mode 100644 lib/pipeline/rte_pipeline.h
delete mode 100644 lib/pipeline/rte_port_in_action.c
delete mode 100644 lib/pipeline/rte_port_in_action.h
delete mode 100644 lib/pipeline/rte_table_action.c
delete mode 100644 lib/pipeline/rte_table_action.h
delete mode 100644 lib/port/port_log.c
delete mode 100644 lib/port/port_log.h
delete mode 100644 lib/port/rte_port.h
delete mode 100644 lib/port/rte_port_ethdev.c
delete mode 100644 lib/port/rte_port_ethdev.h
delete mode 100644 lib/port/rte_port_eventdev.c
delete mode 100644 lib/port/rte_port_eventdev.h
delete mode 100644 lib/port/rte_port_fd.c
delete mode 100644 lib/port/rte_port_fd.h
delete mode 100644 lib/port/rte_port_frag.c
delete mode 100644 lib/port/rte_port_frag.h
delete mode 100644 lib/port/rte_port_ras.c
delete mode 100644 lib/port/rte_port_ras.h
delete mode 100644 lib/port/rte_port_ring.c
delete mode 100644 lib/port/rte_port_ring.h
delete mode 100644 lib/port/rte_port_sched.c
delete mode 100644 lib/port/rte_port_sched.h
delete mode 100644 lib/port/rte_port_source_sink.c
delete mode 100644 lib/port/rte_port_source_sink.h
delete mode 100644 lib/port/rte_port_sym_crypto.c
delete mode 100644 lib/port/rte_port_sym_crypto.h
delete mode 100644 lib/table/rte_lru.h
delete mode 100644 lib/table/rte_lru_arm64.h
delete mode 100644 lib/table/rte_lru_x86.h
delete mode 100644 lib/table/rte_table.h
delete mode 100644 lib/table/rte_table_acl.c
delete mode 100644 lib/table/rte_table_acl.h
delete mode 100644 lib/table/rte_table_array.c
delete mode 100644 lib/table/rte_table_array.h
delete mode 100644 lib/table/rte_table_hash.h
delete mode 100644 lib/table/rte_table_hash_cuckoo.c
delete mode 100644 lib/table/rte_table_hash_cuckoo.h
delete mode 100644 lib/table/rte_table_hash_ext.c
delete mode 100644 lib/table/rte_table_hash_func.h
delete mode 100644 lib/table/rte_table_hash_func_arm64.h
delete mode 100644 lib/table/rte_table_hash_key16.c
delete mode 100644 lib/table/rte_table_hash_key32.c
delete mode 100644 lib/table/rte_table_hash_key8.c
delete mode 100644 lib/table/rte_table_hash_lru.c
delete mode 100644 lib/table/rte_table_lpm.c
delete mode 100644 lib/table/rte_table_lpm.h
delete mode 100644 lib/table/rte_table_lpm_ipv6.c
delete mode 100644 lib/table/rte_table_lpm_ipv6.h
delete mode 100644 lib/table/rte_table_stub.c
delete mode 100644 lib/table/rte_table_stub.h
delete mode 100644 lib/table/table_log.c
delete mode 100644 lib/table/table_log.h
--
2.53.0
^ permalink raw reply [flat|nested] 29+ messages in thread* [PATCH v3 1/6] app/test: remove packet framework tests
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
@ 2026-07-28 14:20 ` Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 2/6] app/test-pipeline: remove application Stephen Hemminger
` (4 subsequent siblings)
5 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 14:20 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The legacy packet framework libraries (port, table, pipeline) are
being removed, so remove the unit tests exercising them.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 1 -
app/test/meson.build | 6 -
app/test/test_table.c | 209 -------
app/test/test_table.h | 184 ------
app/test/test_table_acl.c | 728 ----------------------
app/test/test_table_acl.h | 6 -
app/test/test_table_combined.c | 846 -------------------------
app/test/test_table_combined.h | 27 -
app/test/test_table_pipeline.c | 575 -----------------
app/test/test_table_pipeline.h | 6 -
app/test/test_table_ports.c | 195 ------
app/test/test_table_ports.h | 13 -
app/test/test_table_tables.c | 1058 --------------------------------
app/test/test_table_tables.h | 22 -
14 files changed, 3876 deletions(-)
delete mode 100644 app/test/test_table.c
delete mode 100644 app/test/test_table.h
delete mode 100644 app/test/test_table_acl.c
delete mode 100644 app/test/test_table_acl.h
delete mode 100644 app/test/test_table_combined.c
delete mode 100644 app/test/test_table_combined.h
delete mode 100644 app/test/test_table_pipeline.c
delete mode 100644 app/test/test_table_pipeline.h
delete mode 100644 app/test/test_table_ports.c
delete mode 100644 app/test/test_table_ports.h
delete mode 100644 app/test/test_table_tables.c
delete mode 100644 app/test/test_table_tables.h
diff --git a/MAINTAINERS b/MAINTAINERS
index e99a65d197..77a41b3fcf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,7 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test/test_table*
F: app/test-pipeline/
F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
diff --git a/app/test/meson.build b/app/test/meson.build
index 51abeeb732..4fcd755940 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -195,12 +195,6 @@ source_file_deps = {
'test_stack.c': ['stack'],
'test_stack_perf.c': ['stack'],
'test_string_fns.c': [],
- 'test_table.c': ['table', 'pipeline', 'port'],
- 'test_table_acl.c': ['net', 'table', 'pipeline', 'port'],
- 'test_table_combined.c': ['table', 'pipeline', 'port'],
- 'test_table_pipeline.c': ['pipeline', 'table', 'port'],
- 'test_table_ports.c': ['table', 'pipeline', 'port'],
- 'test_table_tables.c': ['table', 'pipeline', 'port'],
'test_tailq.c': [],
'test_telemetry_data.c': ['telemetry'],
'test_telemetry_json.c': ['telemetry'],
diff --git a/app/test/test_table.c b/app/test/test_table.c
deleted file mode 100644
index 20623b8735..0000000000
--- a/app/test/test_table.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_byteorder.h>
-#include <rte_hexdump.h>
-#include <rte_string_fns.h>
-#include <string.h>
-#include "test.h"
-
-#ifdef RTE_EXEC_ENV_WINDOWS
-static int
-test_table(void)
-{
- printf("table not supported on Windows, skipping test\n");
- return TEST_SKIPPED;
-}
-#else
-
-#include "test_table.h"
-#include "test_table_pipeline.h"
-#include "test_table_ports.h"
-#include "test_table_tables.h"
-#include "test_table_combined.h"
-#include "test_table_acl.h"
-
-/* Global variables */
-struct rte_pipeline *p;
-struct rte_ring *rings_rx[N_PORTS];
-struct rte_ring *rings_tx[N_PORTS];
-struct rte_mempool *pool = NULL;
-
-uint32_t port_in_id[N_PORTS];
-uint32_t port_out_id[N_PORTS];
-uint32_t port_out_id_type[3];
-uint32_t table_id[N_PORTS*2];
-uint64_t override_hit_mask = 0xFFFFFFFF;
-uint64_t override_miss_mask = 0xFFFFFFFF;
-uint64_t non_reserved_actions_hit = 0;
-uint64_t non_reserved_actions_miss = 0;
-uint8_t connect_miss_action_to_port_out = 0;
-uint8_t connect_miss_action_to_table = 0;
-uint32_t table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
-uint32_t table_entry_hit_action = RTE_PIPELINE_ACTION_PORT;
-uint32_t table_entry_miss_action = RTE_PIPELINE_ACTION_DROP;
-rte_pipeline_port_in_action_handler port_in_action = NULL;
-rte_pipeline_port_out_action_handler port_out_action = NULL;
-rte_pipeline_table_action_handler_hit action_handler_hit = NULL;
-rte_pipeline_table_action_handler_miss action_handler_miss = NULL;
-
-/* Function prototypes */
-static void app_init_rings(void);
-static void app_init_mbuf_pools(void);
-
-uint64_t pipeline_test_hash(void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = ip_dst;
-
- return signature;
-}
-
-uint32_t pipeline_test_hash_cuckoo(const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = ip_dst;
-
- return signature;
-}
-
-static void
-app_free_resources(void) {
- int i;
- for (i = 0; i < N_PORTS; i++)
- rte_ring_free(rings_rx[i]);
- rte_mempool_free(pool);
-}
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- printf("Getting/Creating the mempool ...\n");
- pool = rte_mempool_lookup("mempool");
- if (!pool) {
- pool = rte_pktmbuf_pool_create(
- "mempool",
- POOL_SIZE,
- POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE,
- 0);
- if (pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
- }
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
- rings_rx[i] = rte_ring_lookup(name);
- if (rings_rx[i] == NULL) {
- rings_rx[i] = rte_ring_create(
- name,
- RING_RX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
- rings_tx[i] = rte_ring_lookup(name);
- if (rings_tx[i] == NULL) {
- rings_tx[i] = rte_ring_create(
- name,
- RING_TX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static int
-test_table(void)
-{
- int status, ret;
- unsigned i;
-
- ret = TEST_SUCCESS;
-
- app_init_rings();
- app_init_mbuf_pools();
-
- printf("\n\n\n\n************Pipeline tests************\n");
-
- if (test_table_pipeline() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-
- printf("\n\n\n\n************Port tests************\n");
- for (i = 0; i < n_port_tests; i++) {
- status = port_tests[i]();
- if (status < 0) {
- printf("\nPort test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests; i++) {
- status = table_tests[i]();
- if (status < 0) {
- printf("\nTable test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests_combined; i++) {
- status = table_tests_combined[i]();
- if (status < 0) {
- printf("\nCombined table test number %d failed with "
- "reason number %d.\n", i, status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
-#ifdef RTE_LIB_ACL
- printf("\n\n\n\n************ACL tests************\n");
- if (test_table_acl() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-#endif
-
-end:
- app_free_resources();
-
- return ret;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
-
-REGISTER_FAST_TEST(table_autotest, NOHUGE_OK, ASAN_OK, test_table);
diff --git a/app/test/test_table.h b/app/test/test_table.h
deleted file mode 100644
index 209bdbff2c..0000000000
--- a/app/test/test_table.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_table_stub.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_table_array.h>
-#include <rte_pipeline.h>
-
-#ifdef RTE_LIB_ACL
-#include <rte_table_acl.h>
-#endif
-
-#include <rte_port_ring.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_source_sink.h>
-
-#ifndef TEST_TABLE_H_
-#define TEST_TABLE_H_
-
-#define RING_SIZE 4096
-#define MAX_BULK 32
-#define N 65536
-#define TIME_S 5
-#define TEST_RING_FULL_EMTPY_ITER 8
-#define N_PORTS 2
-#define N_PKTS 2
-#define N_PKTS_EXT 6
-#define RING_RX rings_rx[0]
-#define RING_RX_2 rings_rx[1]
-#define RING_TX rings_tx[0]
-#define RING_TX_2 rings_tx[1]
-#define PORT_RX_RING_SIZE 128
-#define PORT_TX_RING_SIZE 512
-#define RING_RX_SIZE 128
-#define RING_TX_SIZE 128
-#define POOL_BUFFER_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
-#define POOL_SIZE (32 * 1024)
-#define POOL_CACHE_SIZE 256
-#define BURST_SIZE 8
-#define WORKER_TYPE 1
-#define MAX_DUMMY_PORTS 2
-#define MP_NAME "dummy_port_mempool"
-#define MBUF_COUNT (8000 * MAX_DUMMY_PORTS)
-#define MP_CACHE_SZ 256
-#define MP_SOCKET 0
-#define MP_FLAGS 0
-
-/* Macros */
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#define RING_ENQUEUE(ring, value) do { \
- struct rte_mbuf *m; \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- \
- m = rte_pktmbuf_alloc(pool); \
- if (m == NULL) \
- return -1; \
- signature = RTE_MBUF_METADATA_UINT32_PTR(m, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(m, \
- APP_METADATA_OFFSET(32)); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
- rte_ring_enqueue((ring), m); \
-} while (0)
-
-#define RUN_PIPELINE(pipeline) do { \
- rte_pipeline_run((pipeline)); \
- rte_pipeline_flush((pipeline)); \
-} while (0)
-
-#define VERIFY(var, value) do { \
- if ((var) != -(value)) \
- return var; \
-} while (0)
-
-#define VERIFY_TRAFFIC(ring, sent, expected) do { \
- unsigned i, n = 0; \
- void *mbuf = NULL; \
- \
- for (i = 0; i < (sent); i++) { \
- if (!rte_ring_dequeue((ring), &mbuf)) { \
- if (mbuf == NULL) \
- continue; \
- n++; \
- rte_pktmbuf_free((struct rte_mbuf *)mbuf); \
- } \
- else \
- break; \
- } \
- printf("Expected %d, got %d\n", expected, n); \
- if (n != (expected)) { \
- return -21; \
- } \
-} while (0)
-
-/* Function definitions */
-uint64_t pipeline_test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed);
-
-uint32_t pipeline_test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed);
-
-/* Extern variables */
-extern struct rte_pipeline *p;
-extern struct rte_ring *rings_rx[N_PORTS];
-extern struct rte_ring *rings_tx[N_PORTS];
-extern struct rte_mempool *pool;
-extern uint32_t port_in_id[N_PORTS];
-extern uint32_t port_out_id[N_PORTS];
-extern uint32_t port_out_id_type[3];
-extern uint32_t table_id[N_PORTS*2];
-extern uint64_t override_hit_mask;
-extern uint64_t override_miss_mask;
-extern uint64_t non_reserved_actions_hit;
-extern uint64_t non_reserved_actions_miss;
-extern uint8_t connect_miss_action_to_port_out;
-extern uint8_t connect_miss_action_to_table;
-extern uint32_t table_entry_default_action;
-extern uint32_t table_entry_hit_action;
-extern uint32_t table_entry_miss_action;
-extern rte_pipeline_port_in_action_handler port_in_action;
-extern rte_pipeline_port_out_action_handler port_out_action;
-extern rte_pipeline_table_action_handler_hit action_handler_hit;
-extern rte_pipeline_table_action_handler_miss action_handler_miss;
-
-/* Global data types */
-struct manage_ops {
- uint32_t op_id;
- void *op_data;
- int expected_result;
-};
-
-/* Internal pipeline structures */
-struct rte_port_in {
- struct rte_port_in_ops ops;
- uint32_t burst_size;
- uint32_t table_id;
- void *h_port;
-};
-
-struct rte_port_out {
- struct rte_port_out_ops ops;
- void *h_port;
-};
-
-struct rte_table {
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action;
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
- uint8_t actions_lookup_miss[RTE_CACHE_LINE_SIZE];
- uint32_t action_data_size;
- void *h_table;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct rte_pipeline {
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- uint32_t socket_id;
- struct rte_port_in ports_in[16];
- struct rte_port_out ports_out[16];
- struct rte_table tables[64];
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_table_entry *actions[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t mask_action[64];
- uint32_t mask_actions;
-};
-#endif
diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c
deleted file mode 100644
index 4fdf731596..0000000000
--- a/app/test/test_table_acl.c
+++ /dev/null
@@ -1,728 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <rte_ip.h>
-#include <rte_string_fns.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_acl.h"
-
-/*
- * Rule and trace formats definitions.
- **/
-
-struct ipv4_5tuple {
- uint8_t proto;
- uint32_t ip_src;
- uint32_t ip_dst;
- uint16_t port_src;
- uint16_t port_dst;
-};
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, proto),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_dst),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_dst),
- },
-};
-
-struct rte_table_acl_rule_add_params table_acl_IPv4_rule;
-
-typedef int (*parse_5tuple)(char *text,
- struct rte_table_acl_rule_add_params *rule);
-
-/*
-* The order of the fields in the rule string after the initial '@'
-*/
-enum {
- CB_FLD_SRC_ADDR,
- CB_FLD_DST_ADDR,
- CB_FLD_SRC_PORT_RANGE,
- CB_FLD_DST_PORT_RANGE,
- CB_FLD_PROTO,
- CB_FLD_NUM,
-};
-
-
-#define GET_CB_FIELD(in, fd, base, lim, dlm) \
-do { \
- unsigned long val; \
- char *end; \
- \
- errno = 0; \
- val = strtoul((in), &end, (base)); \
- if (errno != 0 || end[0] != (dlm) || val > (lim)) \
- return -EINVAL; \
- (fd) = (typeof(fd)) val; \
- (in) = end + 1; \
-} while (0)
-
-
-
-
-static int
-parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len)
-{
- uint8_t a, b, c, d, m;
-
- GET_CB_FIELD(in, a, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, b, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, c, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, d, 0, UINT8_MAX, '/');
- GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0);
-
- addr[0] = RTE_IPV4(a, b, c, d);
- mask_len[0] = m;
-
- return 0;
-}
-
-static int
-parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high)
-{
- uint16_t a, b;
-
- GET_CB_FIELD(in, a, 0, UINT16_MAX, ':');
- GET_CB_FIELD(in, b, 0, UINT16_MAX, 0);
-
- port_low[0] = a;
- port_high[0] = b;
-
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-setup_acl_pipeline(void)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
- uint32_t n;
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_acl_rule_delete_params *delete_params;
- parse_5tuple parser;
- char acl_name[64];
-
- /*
- * The format for these rules DO NOT need the port ranges to be
- * separated by ' : ', just ':'. It's a lot more readable and
- * cleaner, IMO.
- */
- static const char * const lines[] = {
- "@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */
- "@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP check */
- "@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */
- "@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */
- "@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */
- };
- char line[LINE_MAX];
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = port_in_action;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params;
-
- /* Set up defaults for stub */
- table_params.ops = &rte_table_stub_ops;
- table_params.arg_create = NULL;
- table_params.f_action_hit = action_handler_hit;
- table_params.f_action_miss = NULL;
- table_params.action_data_size = 0;
-
- printf("miss_action=%x\n",
- table_entry_miss_action);
-
- printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs),
- RTE_ACL_RULE_SZ(DIM(ipv4_defs)));
-
- struct rte_table_acl_params acl_params;
-
- acl_params.n_rules = 1 << 5;
- acl_params.n_rule_fields = DIM(ipv4_defs);
- snprintf(acl_name, sizeof(acl_name), "ACL%d", i);
- acl_params.name = acl_name;
- memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
-
- table_params.ops = &rte_table_acl_ops;
- table_params.arg_create = &acl_params;
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table) {
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
- }
-
- for (i = 0; i < N_PORTS; i++) {
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n",
- port_in_id[i], table_id[i]);
- goto fail;
- }
- }
-
- /* Add bulk entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_add_params keys[5];
- struct rte_pipeline_table_entry entries[5];
- struct rte_table_acl_rule_add_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
- struct rte_pipeline_table_entry *table_entries_ptr[5];
- struct rte_pipeline_table_entry entries_ptr[5];
-
- parser = parse_cb_ipv4_rule;
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1;
-
- entries[n].action = RTE_PIPELINE_ACTION_PORT;
- entries[n].port_id = port_out_id[i^1];
- table_entries[n] = &entries[n];
- table_entries_ptr[n] = &entries_ptr[n];
- }
-
- ret = rte_pipeline_table_entry_add_bulk(p, table_id[i],
- (void **)key_array, table_entries, 5, key_found, table_entries_ptr);
- if (ret < 0) {
- rte_panic("Add entry bulk to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* Delete bulk entries from tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_delete_params keys[5];
- struct rte_table_acl_rule_delete_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
-
- memset(table_entries, 0, sizeof(table_entries));
-
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parse_cb_ipv4_rule_del(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
- }
-
- ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i],
- (void **)key_array, 5, key_found, table_entries);
- if (ret < 0) {
- rte_panic("Delete bulk entries from table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Bulk deleted rules.\n");
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- int key_found;
- struct rte_pipeline_table_entry *entry_ptr;
-
- memset(&rule_params, 0, sizeof(rule_params));
- parser = parse_cb_ipv4_rule;
-
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* delete a few rules */
- for (n = 2; n <= 3; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- delete_params = (struct
- rte_pipeline_table_acl_rule_delete_params *)
- &(rule_params.field_value[0]);
- ret = rte_pipeline_table_entry_delete(p, table_id[i],
- delete_params, &key_found, NULL);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Deleted Rule.\n");
- }
-
-
- /* Try to add duplicates */
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- }
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int expected_count)
-{
- int i, j, ret, tx_count;
- struct ipv4_5tuple five_tuple;
-
- /* Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++) {
- for (j = 0; j < 8; j++) {
- struct rte_mbuf *mbuf;
-
- mbuf = rte_pktmbuf_alloc(pool);
- if (mbuf == NULL)
- /* this will cause test failure after cleanup
- * of already enqueued mbufs, as the mbuf
- * counts won't match */
- break;
- memset(rte_pktmbuf_mtod(mbuf, char *), 0x00,
- sizeof(struct ipv4_5tuple));
-
- five_tuple.proto = j;
- five_tuple.ip_src = rte_bswap32(RTE_IPV4(192, 168, j, 1));
- five_tuple.ip_dst = rte_bswap32(RTE_IPV4(10, 4, j, 1));
- five_tuple.port_src = rte_bswap16(100 + j);
- five_tuple.port_dst = rte_bswap16(200 + j);
-
- memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple,
- sizeof(struct ipv4_5tuple));
- printf("%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], mbuf);
- }
- }
-
- /* Run pipeline once */
- for (i = 0; i< N_PORTS; i++)
- rte_pipeline_run(p);
-
- rte_pipeline_flush(p);
-
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0) {
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- } else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "mbuf",
- rte_pktmbuf_mtod(mbuf, char *), 64);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets for ACL test, expected %d, got %d\n",
- __func__, expected_count, tx_count);
- goto fail;
- }
-
- rte_pipeline_free(p);
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_acl(void)
-{
-
-
- override_hit_mask = 0xFF; /* All packets are a hit */
-
- setup_acl_pipeline();
- if (test_pipeline_single_filter(10) < 0)
- return -1;
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_acl.h b/app/test/test_table_acl.h
deleted file mode 100644
index a6ae7d2838..0000000000
--- a/app/test/test_table_acl.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_acl(void);
diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
deleted file mode 100644
index 04503baa51..0000000000
--- a/app/test/test_table_combined.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include "test_table_combined.h"
-#include "test_table.h"
-#include <rte_table_lpm_ipv6.h>
-
-#define MAX_TEST_KEYS 128
-#define N_PACKETS 50
-
-enum check_table_result {
- CHECK_TABLE_OK,
- CHECK_TABLE_PORT_CONFIG,
- CHECK_TABLE_PORT_ENABLE,
- CHECK_TABLE_TABLE_CONFIG,
- CHECK_TABLE_ENTRY_ADD,
- CHECK_TABLE_DEFAULT_ENTRY_ADD,
- CHECK_TABLE_CONNECT,
- CHECK_TABLE_MANAGE_ERROR,
- CHECK_TABLE_CONSISTENCY,
- CHECK_TABLE_NO_TRAFFIC,
- CHECK_TABLE_INVALID_PARAMETER,
-};
-
-struct table_packets {
- uint32_t hit_packet[MAX_TEST_KEYS];
- uint32_t miss_packet[MAX_TEST_KEYS];
- uint32_t n_hit_packets;
- uint32_t n_miss_packets;
-};
-
-combined_table_test table_tests_combined[] = {
- test_table_lpm_combined,
- test_table_lpm_ipv6_combined,
- test_table_hash8lru,
- test_table_hash8ext,
- test_table_hash16lru,
- test_table_hash16ext,
- test_table_hash32lru,
- test_table_hash32ext,
- test_table_hash_cuckoo_combined,
-};
-
-unsigned n_table_tests_combined = RTE_DIM(table_tests_combined);
-
-/* Generic port tester function */
-static int
-test_table_type(struct rte_table_ops *table_ops, void *table_args,
- void *key, struct table_packets *table_packets,
- struct manage_ops *manage_ops, unsigned n_ops)
-{
- uint32_t ring_in_id, table_id, ring_out_id, ring_out_2_id;
- unsigned i;
-
- RTE_SET_USED(manage_ops);
- RTE_SET_USED(n_ops);
- /* Create pipeline */
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = 0,
- };
-
- struct rte_pipeline *pipeline = rte_pipeline_create(&pipeline_params);
-
- /* Create input ring */
- struct rte_port_ring_reader_params ring_params_rx = {
- .ring = RING_RX,
- };
-
- struct rte_port_ring_writer_params ring_params_tx = {
- .ring = RING_RX,
- .tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- struct rte_pipeline_port_in_params ring_in_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *)&ring_params_rx,
- .f_action = NULL,
- .burst_size = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- if (rte_pipeline_port_in_create(pipeline, &ring_in_params,
- &ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Create table */
- struct rte_pipeline_table_params table_params = {
- .ops = table_ops,
- .arg_create = table_args,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(pipeline, &table_params,
- &table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_TABLE_CONFIG;
- }
-
- /* Create output ports */
- ring_params_tx.ring = RING_TX;
-
- struct rte_pipeline_port_out_params ring_out_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *)&ring_params_tx,
- .f_action = NULL,
- };
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- ring_params_tx.ring = RING_TX_2;
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_2_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Add entry to the table */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_DROP,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry *default_entry_ptr, *entry_ptr;
-
- int key_found;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_DEFAULT_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Create connections and check consistency */
- if (rte_pipeline_port_in_connect_to_table(pipeline, ring_in_id,
- table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONNECT;
- }
-
- if (rte_pipeline_port_in_enable(pipeline, ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_ENABLE;
- }
-
- if (rte_pipeline_check(pipeline) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONSISTENCY;
- }
-
-
-
- /* Flow test - All hits */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- /* Flow test - All misses */
- if (table_packets->n_miss_packets) {
- for (i = 0; i < table_packets->n_miss_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
- /* Flow test - Half hits, half misses */
- if (table_packets->n_hit_packets && table_packets->n_miss_packets) {
- for (i = 0; i < (table_packets->n_hit_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- for (i = 0; i < (table_packets->n_miss_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets / 2);
- }
-
- /* Flow test - Single packet */
- if (table_packets->n_hit_packets) {
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 1);
- }
- if (table_packets->n_miss_packets) {
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
-
- /* Change table entry action */
- printf("Change entry action\n");
- table_entry.table_id = ring_out_2_id;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Check that traffic destination has changed */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 0);
- VERIFY_TRAFFIC(RING_TX_2, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- printf("delete entry\n");
- /* Delete table entry */
- rte_pipeline_table_entry_delete(pipeline, table_id,
- key ? key : &table_entry, &key_found, NULL);
-
- rte_pipeline_free(pipeline);
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub_combined(void)
-{
- int status, i;
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = i;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = 0;
-
- status = test_table_type(&rte_table_stub_ops, NULL, NULL,
- &table_packets, NULL, 1);
- VERIFY(status, CHECK_TABLE_OK);
-
- return 0;
-}
-
-int
-test_table_lpm_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(0),
- };
-
- struct rte_table_lpm_key lpm_key = {
- .ip = 0xadadadad,
- .depth = 16,
- };
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_params.n_rules = 1 << 24;
- lpm_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_key.depth = 33;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_ipv6_params lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 13,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_table_lpm_ipv6_key lpm_ipv6_key = {
- .depth = 16,
- };
- memset(&lpm_ipv6_key.ip, 0xad, 16);
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xadadadab;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_ipv6_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_ipv6_params.n_rules = 1 << 24;
- lpm_ipv6_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_ipv6_key.depth = 129;
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_hash8lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8lru_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8lru[8];
- uint32_t *k8lru = (uint32_t *) key8lru;
-
- memset(key8lru, 0, sizeof(key8lru));
- k8lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8lru_params.n_keys = 1<<16;
- key8lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16lru_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16lru[16];
- uint32_t *k16lru = (uint32_t *) key16lru;
-
- memset(key16lru, 0, sizeof(key16lru));
- k16lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16lru_params.n_keys = 1<<16;
- key16lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32lru_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32lru[32];
- uint32_t *k32lru = (uint32_t *) key32lru;
-
- memset(key32lru, 0, sizeof(key32lru));
- k32lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32lru_params.n_keys = 1<<16;
- key32lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash8ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8ext_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8ext[8];
- uint32_t *k8ext = (uint32_t *) key8ext;
-
- memset(key8ext, 0, sizeof(key8ext));
- k8ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8ext_params.n_keys = 1<<16;
- key8ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16ext_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16ext[16];
- uint32_t *k16ext = (uint32_t *) key16ext;
-
- memset(key16ext, 0, sizeof(key16ext));
- k16ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16ext_params.n_keys = 1<<16;
- key16ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32ext_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32ext[32];
- uint32_t *k32ext = (uint32_t *) key32ext;
-
- memset(key32ext, 0, sizeof(key32ext));
- k32ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32ext_params.n_keys = 1<<16;
- key32ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash_cuckoo_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) key_cuckoo;
-
- memset(key_cuckoo, 0, sizeof(key_cuckoo));
- kcuckoo[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- cuckoo_params.key_size = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.n_keys = 1<<16;
- cuckoo_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_combined.h b/app/test/test_table_combined.h
deleted file mode 100644
index fb94dbb94d..0000000000
--- a/app/test/test_table_combined.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_stub_combined(void);
-int test_table_lpm_combined(void);
-int test_table_lpm_ipv6_combined(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash8unoptimized(void);
-int test_table_hash8lru(void);
-int test_table_hash8ext(void);
-int test_table_hash16unoptimized(void);
-int test_table_hash16lru(void);
-int test_table_hash16ext(void);
-int test_table_hash32unoptimized(void);
-int test_table_hash32lru(void);
-int test_table_hash32ext(void);
-int test_table_hash_cuckoo_combined(void);
-
-/* Extern variables */
-typedef int (*combined_table_test)(void);
-
-extern combined_table_test table_tests_combined[];
-extern unsigned n_table_tests_combined;
diff --git a/app/test/test_table_pipeline.c b/app/test/test_table_pipeline.c
deleted file mode 100644
index 960f730cf2..0000000000
--- a/app/test/test_table_pipeline.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_pipeline.h>
-#include <inttypes.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_pipeline.h"
-
-#if 0
-
-static rte_pipeline_port_out_action_handler port_action_0x00
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_0xFF
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_stub
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-
-
-rte_pipeline_port_out_action_handler port_action_0x00(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0x00\n");
- *pkts_mask = 0x00;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_0xFF(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0xFF\n");
- *pkts_mask = 0xFF;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(pkts_mask);
- RTE_SET_USED(arg);
- printf("Port Action stub\n");
- return 0;
-}
-
-#endif
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-static int
-table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry *entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("Table Action, setting pkts_mask to 0x00\n");
- pkts_mask = ~0x00;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Hit - doing nothing\n");
- printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n",
- override_hit_mask);
- pkts_mask = (~override_hit_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-static int
-table_action_stub_miss(struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry *entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n",
- override_miss_mask);
- pkts_mask = (~override_miss_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-enum e_test_type {
- e_TEST_STUB = 0,
- e_TEST_LPM,
- e_TEST_LPM6,
- e_TEST_HASH_LRU_8,
- e_TEST_HASH_LRU_16,
- e_TEST_HASH_LRU_32,
- e_TEST_HASH_EXT_8,
- e_TEST_HASH_EXT_16,
- e_TEST_HASH_EXT_32
-};
-
-char pipeline_test_names[][64] = {
- "Stub",
- "LPM",
- "LPMv6",
- "8-bit LRU Hash",
- "16-bit LRU Hash",
- "32-bit LRU Hash",
- "16-bit Ext Hash",
- "8-bit Ext Hash",
- "32-bit Ext Hash",
- ""
-};
-
-
-static int
-cleanup_pipeline(void)
-{
-
- rte_pipeline_free(p);
-
- return 0;
-}
-
-
-static int check_pipeline_invalid_params(void);
-
-static int
-check_pipeline_invalid_params(void)
-{
- struct rte_pipeline_params pipeline_params_1 = {
- .name = NULL,
- .socket_id = 0,
- };
- struct rte_pipeline_params pipeline_params_2 = {
- .name = "PIPELINE",
- .socket_id = -1,
- };
- struct rte_pipeline_params pipeline_params_3 = {
- .name = "PIPELINE",
- .socket_id = 127,
- };
-
- p = rte_pipeline_create(NULL);
- if (p != NULL) {
- fprintf(stderr,
- "%s: configured pipeline with null params\n",
- __func__);
- goto fail;
- }
- p = rte_pipeline_create(&pipeline_params_1);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with NULL name\n", __func__);
- goto fail;
- }
-
- p = rte_pipeline_create(&pipeline_params_2);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n", __func__);
- goto fail;
- }
-
- if (rte_eal_has_hugepages()) {
- p = rte_pipeline_create(&pipeline_params_3);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n",
- __func__);
- goto fail;
- }
- }
-
- /* Check pipeline consistency */
- if (!rte_pipeline_check(p)) {
- rte_panic("Pipeline consistency reported as OK\n");
- goto fail;
- }
-
-
- return 0;
-fail:
- return -1;
-}
-
-
-static int
-setup_pipeline(int test_type)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
-
- fprintf(stderr, "%s: **** Setting up %s test\n",
- __func__, pipeline_test_names[test_type]);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- ret = rte_pipeline_free(p);
- if (ret != 0) {
- fprintf(stderr, "%s: Failed to free pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = NULL;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (i)
- port_params.f_action = port_out_action;
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = action_handler_hit,
- .f_action_miss = action_handler_miss,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table)
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
-
- for (i = 0; i < N_PORTS; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
- goto fail;
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry default_entry = {
- .action = (enum rte_pipeline_action)
- table_entry_default_action,
- {.port_id = port_out_id[i^1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (connect_miss_action_to_table) {
- printf("Setting first table to output to next table\n");
- default_entry.action = RTE_PIPELINE_ACTION_TABLE;
- default_entry.table_id = table_id[i+2];
- }
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p, table_id[i],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to table %u "
- "code %d\n", table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d with "
- "action %x\n",
- table_id[i], default_entry.action);
-
- if (connect_miss_action_to_table) {
- /* We create a second table so the first can pass
- traffic into it */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- printf("Setting second table to output to port\n");
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p,
- table_id[i+2],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to "
- "table %u code %d\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d "
- "with action %x\n",
- table_id[i], default_entry.action);
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- } else
- printf("Pipeline Consistency OK!\n");
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int test_type, int expected_count)
-{
- int i;
- int j;
- int ret;
- int tx_count;
-
- fprintf(stderr, "%s: **** Running %s test\n",
- __func__, pipeline_test_names[test_type]);
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
-
- ret = rte_pipeline_flush(NULL);
- if (ret != -EINVAL) {
- fprintf(stderr,
- "%s: No pipeline flush error NULL pipeline (%d)\n",
- __func__, ret);
- goto fail;
- }
-
- /*
- * Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++)
- for (j = 0; j < N_PORTS; j++) {
- struct rte_mbuf *m;
- uint8_t *key;
- uint32_t *k32;
-
- m = rte_pktmbuf_alloc(pool);
- if (m == NULL) {
- rte_panic("Failed to alloc mbuf from pool\n");
- return -1;
- }
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- k32 = (uint32_t *) key;
- k32[0] = 0xadadadad >> (j % 2);
-
- fprintf(stderr, "%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], m);
- }
-
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
- /*
- * need to flush the pipeline, as there may be less hits than the burst
- size and they will not have been flushed to the tx rings. */
- rte_pipeline_flush(p);
-
- /*
- * Now we'll see what we got back on the tx rings. We should see whatever
- * packets we had hits on that were destined for the output ports.
- */
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0)
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "Object:",
- rte_pktmbuf_mtod(mbuf, char *),
- mbuf->data_len);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets out for %s test, expected %d, got %d\n",
- __func__, pipeline_test_names[test_type],
- expected_count, tx_count);
- goto fail;
- }
-
- cleanup_pipeline();
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_pipeline(void)
-{
- /* TEST - All packets dropped */
- action_handler_hit = NULL;
- action_handler_miss = NULL;
- table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 0) < 0)
- return -1;
-
- /* TEST - All packets passed through */
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /* TEST - one packet per port */
- action_handler_hit = NULL;
- action_handler_miss = table_action_stub_miss;
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- override_miss_mask = 0x01; /* one packet per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - one packet per port */
- override_miss_mask = 0x02; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - all packets per port */
- override_miss_mask = 0x03; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /*
- * This test will set up two tables in the pipeline. the first table
- * will forward to another table on miss, and the second table will
- * forward to port.
- */
- connect_miss_action_to_table = 1;
- table_entry_default_action = RTE_PIPELINE_ACTION_TABLE;
- action_handler_hit = NULL; /* not for stub, hitmask always zero */
- action_handler_miss = NULL;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- printf("TEST - two tables, hitmask override to 0x01\n");
- connect_miss_action_to_table = 1;
- action_handler_miss = table_action_stub_miss;
- override_miss_mask = 0x01;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- if (check_pipeline_invalid_params()) {
- fprintf(stderr, "%s: Check pipeline invalid params failed.\n",
- __func__);
- return -1;
- }
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_pipeline.h b/app/test/test_table_pipeline.h
deleted file mode 100644
index d66d09d6f1..0000000000
--- a/app/test/test_table_pipeline.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_pipeline(void);
diff --git a/app/test/test_table_ports.c b/app/test/test_table_ports.c
deleted file mode 100644
index 282ec2a3d2..0000000000
--- a/app/test/test_table_ports.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include "test_table_ports.h"
-#include "test_table.h"
-
-port_test port_tests[] = {
- test_port_ring_reader,
- test_port_ring_writer,
-};
-
-unsigned n_port_tests = RTE_DIM(port_tests);
-
-/* Port tests */
-int
-test_port_ring_reader(void)
-{
- int status, i;
- struct rte_port_ring_reader_params port_ring_reader_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_reader_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- /* Create and free */
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
- if (port == NULL)
- return -3;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status != 0)
- return -4;
-
- /* -- Traffic RX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- void *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
-
- /* Single packet */
- mbuf[0] = (void *)rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- mbuf, 1, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, 1);
-
- if (received_pkts < expected_pkts)
- return -5;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- (void * const *) mbuf, RTE_PORT_IN_BURST_SIZE_MAX, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf,
- RTE_PORT_IN_BURST_SIZE_MAX);
-
- if (received_pkts < expected_pkts)
- return -6;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-int
-test_port_ring_writer(void)
-{
- int status, i;
- struct rte_port_ring_writer_params port_ring_writer_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_writer_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- port_ring_writer_params.ring = NULL;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -3;
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX + 1;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -4;
-
- /* Create and free */
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port == NULL)
- return -5;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status != 0)
- return -6;
-
- /* -- Traffic TX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
-
- /* Single packet */
- mbuf[0] = rte_pktmbuf_alloc(pool);
-
- rte_port_ring_writer_ops.f_tx(port, mbuf[0]);
- rte_port_ring_writer_ops.f_flush(port);
- expected_pkts = 1;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -7;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx(port, mbuf[i]);
- }
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- /* TX Bulk */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-1);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-3);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)2);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -9;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_ports.h b/app/test/test_table_ports.h
deleted file mode 100644
index dfa6119319..0000000000
--- a/app/test/test_table_ports.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_port_ring_reader(void);
-int test_port_ring_writer(void);
-
-/* Extern variables */
-typedef int (*port_test)(void);
-
-extern port_test port_tests[];
-extern unsigned n_port_tests;
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
deleted file mode 100644
index 920aa555cb..0000000000
--- a/app/test/test_table_tables.c
+++ /dev/null
@@ -1,1058 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_byteorder.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_lru.h>
-#include <rte_cycles.h>
-#include "test_table_tables.h"
-#include "test_table.h"
-
-table_test table_tests[] = {
- test_table_stub,
- test_table_array,
- test_table_lpm,
- test_table_lpm_ipv6,
- test_table_hash_lru,
- test_table_hash_ext,
- test_table_hash_cuckoo,
-};
-
-#define PREPARE_PACKET(mbuf, value) do { \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- mbuf = rte_pktmbuf_alloc(pool); \
- signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \
- APP_METADATA_OFFSET(32)); \
- if (mbuf->priv_size + mbuf->buf_len >= 64) \
- memset(key, 0, 32); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
-} while (0)
-
-unsigned n_table_tests = RTE_DIM(table_tests);
-
-/* Function prototypes */
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size);
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size);
-
-struct rte_bucket_4_8 {
- /* Cache line 0 */
- uint64_t signature;
- uint64_t lru_list;
- struct rte_bucket_4_8 *next;
- uint64_t next_valid;
- uint64_t key[4];
- /* Cache line 1 */
- uint8_t data[];
-};
-
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
-uint64_t shuffles = 0xfffffffdfffbfff9ULL;
-#else
-uint64_t shuffles = 0x0003000200010000ULL;
-#endif
-
-static int test_lru_update(void)
-{
- struct rte_bucket_4_8 b;
- struct rte_bucket_4_8 *bucket;
- uint32_t i;
- uint64_t pos;
- uint64_t iterations;
- uint64_t j;
- int poss;
-
- printf("---------------------------\n");
- printf("Testing lru_update macro...\n");
- printf("---------------------------\n");
- bucket = &b;
- iterations = 10;
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
- bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL;
-#else
- bucket->lru_list = 0x0000000100020003ULL;
-#endif
- poss = 0;
- for (j = 0; j < iterations; j++)
- for (i = 0; i < 9; i++) {
- uint32_t idx = i >> 1;
- lru_update(bucket, idx);
- pos = lru_pos(bucket);
- poss += pos;
- printf("%s: %d lru_list=%016"PRIx64", upd=%d, "
- "pos=%"PRIx64"\n",
- __func__, i, bucket->lru_list, i>>1, pos);
- }
-
- if (bucket->lru_list != shuffles) {
- printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016"
- PRIx64"\n",
- __func__, i, bucket->lru_list, shuffles);
- return -1;
- }
- printf("%s: output checksum of results =%d\n",
- __func__, poss);
-#if 0
- if (poss != 126) {
- printf("%s: ERROR output checksum of results =%d expected %d\n",
- __func__, poss, 126);
- return -1;
- }
-#endif
-
- fflush(stdout);
-
- uint64_t sc_start = rte_rdtsc();
- iterations = 100000000;
- poss = 0;
- for (j = 0; j < iterations; j++) {
- for (i = 0; i < 4; i++) {
- lru_update(bucket, i);
- pos |= bucket->lru_list;
- }
- }
- uint64_t sc_end = rte_rdtsc();
-
- printf("%s: output checksum of results =%llu\n",
- __func__, (long long unsigned int)pos);
- printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n",
- __func__, sc_start, sc_end);
- printf("\nlru_update: %lu cycles per loop iteration.\n\n",
- (long unsigned int)((sc_end-sc_start)/(iterations*4)));
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub(void)
-{
- int i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
-
- /* Create */
- table = rte_table_stub_ops.f_create(NULL, 0, 1);
- if (table == NULL)
- return -1;
-
- /* Traffic flow */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- expected_mask = 0;
- rte_table_stub_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -2;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- return 0;
-}
-
-int
-test_table_array(void)
-{
- int status, i;
- uint64_t result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry1, entry2;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_array_params array_params = {
- .n_entries = 7,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_array_ops.f_create(NULL, 0, 1);
- if (table != NULL)
- return -1;
-
- array_params.n_entries = 0;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -2;
-
- array_params.n_entries = 7;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -3;
-
- array_params.n_entries = 1 << 24;
- array_params.offset = APP_METADATA_OFFSET(1);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -4;
-
- array_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = rte_table_array_ops.f_free(table);
- if (status < 0)
- return -6;
-
- status = rte_table_array_ops.f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- struct rte_table_array_key array_key_1 = {
- .pos = 10,
- };
- struct rte_table_array_key array_key_2 = {
- .pos = 20,
- };
- entry1 = 'A';
- entry2 = 'B';
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -8;
-
- status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1,
- &key_found, &entry_ptr);
- if (status == 0)
- return -9;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL,
- &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1,
- &entry1, &key_found, &entry_ptr);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- status = rte_table_array_ops.f_add(table, (void *) &array_key_2,
- &entry2, &key_found, &entry_ptr);
- if (status != 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 10);
- else
- PREPARE_PACKET(mbufs[i], 20);
-
- rte_table_array_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0 && *entries[i] != 'A')
- return -13;
- else
- if (i % 2 == 1 && *entries[i] != 'B')
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_array_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_lpm_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.offset = APP_METADATA_OFFSET(32);
- lpm_params.entry_unique_size = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.entry_unique_size = entry_size + 1;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_lpm_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_lpm_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- struct rte_table_lpm_key lpm_key;
- lpm_key.ip = 0xadadadad;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -9;
-
- status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status != 0)
- return -15;
-
- /* Delete */
- status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -17;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -20;
-
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -21;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -22;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -23;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_ipv6_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 18,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(32)
- };
-
- table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.number_tbl8s = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.number_tbl8s = 1 << 18;
- lpm_params.entry_unique_size = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size + 1;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -6;
-
- lpm_params.entry_unique_size = entry_size;
- lpm_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -7;
-
- /* Free */
- status = rte_table_lpm_ipv6_ops.f_free(table);
- if (status < 0)
- return -8;
-
- status = rte_table_lpm_ipv6_ops.f_free(NULL);
- if (status == 0)
- return -9;
-
- /* Add */
- struct rte_table_lpm_ipv6_key lpm_key;
-
- lpm_key.ip.a[0] = 0xad;
- lpm_key.ip.a[1] = 0xad;
- lpm_key.ip.a[2] = 0xad;
- lpm_key.ip.a[3] = 0xad;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -10;
-
- status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -15;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status != 0)
- return -16;
-
- /* Delete */
- status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -17;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -20;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -21;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -22;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- return -23;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -24;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ipv6_ops.f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- int key_found;
- void *entry_ptr;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.key_offset = APP_METADATA_OFFSET(1);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -3;
-
- hash_params.key_offset = APP_METADATA_OFFSET(32);
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-int
-test_table_hash_lru(void)
-{
- int status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key8_lru_ops,
- 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key16_lru_ops,
- 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key32_lru_ops,
- 32);
- if (status < 0)
- return status;
-
- status = test_lru_update();
- if (status < 0)
- return status;
-
- return 0;
-}
-
-int
-test_table_hash_ext(void)
-{
- int status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops, 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32);
- if (status < 0)
- return status;
-
- return 0;
-}
-
-
-int
-test_table_hash_cuckoo(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = 1;
-
- /* Initialize params and create tables */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- cuckoo_params.key_size = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -2;
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -3;
-
- cuckoo_params.n_keys = 1 << 24;
- cuckoo_params.f_hash = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -4;
-
- cuckoo_params.f_hash = pipeline_test_hash_cuckoo;
- cuckoo_params.name = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -5;
-
- cuckoo_params.name = "CUCKOO";
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_hash_cuckoo_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_hash_cuckoo_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) &key_cuckoo;
-
- memset(key_cuckoo, 0, 32);
- kcuckoo[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 0, 1);
- if (table == NULL)
- return -9;
-
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- NULL, &key_found, &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -13;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -14;
-
- /* Delete */
- status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo,
- &key_found, NULL);
- if (status == 0)
- return -15;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, NULL,
- &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != 0)
- return -17;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != -ENOENT)
- return -18;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -19;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_hash_cuckoo_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -20;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_hash_cuckoo_ops.f_free(table);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_tables.h b/app/test/test_table_tables.h
deleted file mode 100644
index 530633a013..0000000000
--- a/app/test/test_table_tables.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_hash_cuckoo(void);
-int test_table_lpm(void);
-int test_table_lpm_ipv6(void);
-int test_table_array(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash_unoptimized(void);
-int test_table_hash_lru(void);
-int test_table_hash_ext(void);
-int test_table_stub(void);
-
-/* Extern variables */
-typedef int (*table_test)(void);
-
-extern table_test table_tests[];
-extern unsigned n_table_tests;
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v3 2/6] app/test-pipeline: remove application
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 1/6] app/test: remove packet framework tests Stephen Hemminger
@ 2026-07-28 14:20 ` Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 3/6] examples/ip_pipeline: remove example Stephen Hemminger
` (3 subsequent siblings)
5 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 14:20 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The test-pipeline application is built on the legacy pipeline
library API (rte_pipeline_*), which was announced for removal
in the 24.11 release. Remove it before removing the library.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
app/meson.build | 1 -
app/test-pipeline/config.c | 230 ---------
app/test-pipeline/init.c | 273 ----------
app/test-pipeline/main.c | 188 -------
app/test-pipeline/main.h | 132 -----
app/test-pipeline/meson.build | 21 -
app/test-pipeline/pipeline_acl.c | 251 ----------
app/test-pipeline/pipeline_hash.c | 471 ------------------
app/test-pipeline/pipeline_lpm.c | 175 -------
app/test-pipeline/pipeline_lpm_ipv6.c | 168 -------
app/test-pipeline/pipeline_stub.c | 137 -----
app/test-pipeline/runtime.c | 160 ------
doc/guides/rel_notes/release_26_11.rst | 3 +
.../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/test_pipeline.rst | 237 ---------
17 files changed, 3 insertions(+), 2447 deletions(-)
delete mode 100644 app/test-pipeline/config.c
delete mode 100644 app/test-pipeline/init.c
delete mode 100644 app/test-pipeline/main.c
delete mode 100644 app/test-pipeline/main.h
delete mode 100644 app/test-pipeline/meson.build
delete mode 100644 app/test-pipeline/pipeline_acl.c
delete mode 100644 app/test-pipeline/pipeline_hash.c
delete mode 100644 app/test-pipeline/pipeline_lpm.c
delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
delete mode 100644 app/test-pipeline/pipeline_stub.c
delete mode 100644 app/test-pipeline/runtime.c
delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 77a41b3fcf..4c06f85706 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,8 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test-pipeline/
-F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
F: examples/pipeline/
F: doc/guides/sample_app_ug/ip_pipeline.rst
diff --git a/app/meson.build b/app/meson.build
index 1798db3ae4..4515688471 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -28,7 +28,6 @@ apps = [
'test-flow-perf',
'test-gpudev',
'test-mldev',
- 'test-pipeline',
'test-pmd',
'test-regex',
'test-sad',
diff --git a/app/test-pipeline/config.c b/app/test-pipeline/config.c
deleted file mode 100644
index daf838948b..0000000000
--- a/app/test-pipeline/config.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_string_fns.h>
-
-#include "main.h"
-
-static const char usage[] = "\n";
-
-void
-app_print_usage(void)
-{
- printf(usage);
-}
-
-static int
-app_parse_port_mask(const char *arg)
-{
- char *end = NULL;
- uint64_t port_mask;
- uint32_t i;
-
- if (arg[0] == '\0')
- return -1;
-
- port_mask = strtoul(arg, &end, 16);
- if ((end == NULL) || (*end != '\0'))
- return -2;
-
- if (port_mask == 0)
- return -3;
-
- app.n_ports = 0;
- for (i = 0; i < 64; i++) {
- if ((port_mask & (1LLU << i)) == 0)
- continue;
-
- if (app.n_ports >= APP_MAX_PORTS)
- return -4;
-
- app.ports[app.n_ports] = i;
- app.n_ports++;
- }
-
- if (!rte_is_power_of_2(app.n_ports))
- return -5;
-
- return 0;
-}
-
-struct {
- const char *name;
- uint32_t value;
-} app_args_table[] = {
- {"none", e_APP_PIPELINE_NONE},
- {"stub", e_APP_PIPELINE_STUB},
- {"hash-8-ext", e_APP_PIPELINE_HASH_KEY8_EXT},
- {"hash-8-lru", e_APP_PIPELINE_HASH_KEY8_LRU},
- {"hash-16-ext", e_APP_PIPELINE_HASH_KEY16_EXT},
- {"hash-16-lru", e_APP_PIPELINE_HASH_KEY16_LRU},
- {"hash-32-ext", e_APP_PIPELINE_HASH_KEY32_EXT},
- {"hash-32-lru", e_APP_PIPELINE_HASH_KEY32_LRU},
- {"hash-spec-8-ext", e_APP_PIPELINE_HASH_SPEC_KEY8_EXT},
- {"hash-spec-8-lru", e_APP_PIPELINE_HASH_SPEC_KEY8_LRU},
- {"hash-spec-16-ext", e_APP_PIPELINE_HASH_SPEC_KEY16_EXT},
- {"hash-spec-16-lru", e_APP_PIPELINE_HASH_SPEC_KEY16_LRU},
- {"hash-spec-32-ext", e_APP_PIPELINE_HASH_SPEC_KEY32_EXT},
- {"hash-spec-32-lru", e_APP_PIPELINE_HASH_SPEC_KEY32_LRU},
- {"acl", e_APP_PIPELINE_ACL},
- {"lpm", e_APP_PIPELINE_LPM},
- {"lpm-ipv6", e_APP_PIPELINE_LPM_IPV6},
- {"hash-cuckoo-8", e_APP_PIPELINE_HASH_CUCKOO_KEY8},
- {"hash-cuckoo-16", e_APP_PIPELINE_HASH_CUCKOO_KEY16},
- {"hash-cuckoo-32", e_APP_PIPELINE_HASH_CUCKOO_KEY32},
- {"hash-cuckoo-48", e_APP_PIPELINE_HASH_CUCKOO_KEY48},
- {"hash-cuckoo-64", e_APP_PIPELINE_HASH_CUCKOO_KEY64},
- {"hash-cuckoo-80", e_APP_PIPELINE_HASH_CUCKOO_KEY80},
- {"hash-cuckoo-96", e_APP_PIPELINE_HASH_CUCKOO_KEY96},
- {"hash-cuckoo-112", e_APP_PIPELINE_HASH_CUCKOO_KEY112},
- {"hash-cuckoo-128", e_APP_PIPELINE_HASH_CUCKOO_KEY128},
-};
-
-int
-app_parse_args(int argc, char **argv)
-{
- int opt, ret;
- char **argvopt;
- int option_index;
- char *prgname = argv[0];
- static struct option lgopts[] = {
- {"none", 0, 0, 0},
- {"stub", 0, 0, 0},
- {"hash-8-ext", 0, 0, 0},
- {"hash-8-lru", 0, 0, 0},
- {"hash-16-ext", 0, 0, 0},
- {"hash-16-lru", 0, 0, 0},
- {"hash-32-ext", 0, 0, 0},
- {"hash-32-lru", 0, 0, 0},
- {"hash-spec-8-ext", 0, 0, 0},
- {"hash-spec-8-lru", 0, 0, 0},
- {"hash-spec-16-ext", 0, 0, 0},
- {"hash-spec-16-lru", 0, 0, 0},
- {"hash-spec-32-ext", 0, 0, 0},
- {"hash-spec-32-lru", 0, 0, 0},
- {"acl", 0, 0, 0},
- {"lpm", 0, 0, 0},
- {"lpm-ipv6", 0, 0, 0},
- {"hash-cuckoo-8", 0, 0, 0},
- {"hash-cuckoo-16", 0, 0, 0},
- {"hash-cuckoo-32", 0, 0, 0},
- {"hash-cuckoo-48", 0, 0, 0},
- {"hash-cuckoo-64", 0, 0, 0},
- {"hash-cuckoo-80", 0, 0, 0},
- {"hash-cuckoo-96", 0, 0, 0},
- {"hash-cuckoo-112", 0, 0, 0},
- {"hash-cuckoo-128", 0, 0, 0},
- {NULL, 0, 0, 0}
- };
- uint32_t lcores[3], n_lcores, lcore_id, pipeline_type_provided;
-
- /* EAL args */
- n_lcores = 0;
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
- if (rte_lcore_is_enabled(lcore_id) == 0)
- continue;
-
- if (n_lcores >= 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- lcores[n_lcores] = lcore_id;
- n_lcores++;
- }
-
- if (n_lcores != 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- app.core_rx = lcores[0];
- app.core_worker = lcores[1];
- app.core_tx = lcores[2];
-
- /* Non-EAL args */
- argvopt = argv;
-
- app.pipeline_type = e_APP_PIPELINE_HASH_KEY16_LRU;
- pipeline_type_provided = 0;
-
- while ((opt = getopt_long(argc, argvopt, "p:",
- lgopts, &option_index)) != EOF) {
- switch (opt) {
- case 'p':
- if (app_parse_port_mask(optarg) < 0) {
- app_print_usage();
- return -1;
- }
- break;
-
- case 0: /* long options */
- if (!pipeline_type_provided) {
- uint32_t i;
-
- for (i = 0; i < e_APP_PIPELINES; i++) {
- if (!strcmp(lgopts[option_index].name,
- app_args_table[i].name)) {
- app.pipeline_type =
- app_args_table[i].value;
- pipeline_type_provided = 1;
- break;
- }
- }
-
- break;
- }
-
- app_print_usage();
- return -1;
-
- default:
- return -1;
- }
- }
-
- if (optind >= 0)
- argv[optind - 1] = prgname;
-
- ret = optind - 1;
- optind = 1; /* reset getopt lib */
- return ret;
-}
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
deleted file mode 100644
index 558f0e428d..0000000000
--- a/app/test-pipeline/init.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-struct app_params app = {
- /* Ports*/
- .n_ports = APP_MAX_PORTS,
- .port_rx_ring_size = 128,
- .port_tx_ring_size = 512,
-
- /* Rings */
- .ring_rx_size = 128,
- .ring_tx_size = 128,
-
- /* Buffer pool */
- .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
- .pool_size = 32 * 1024,
- .pool_cache_size = 256,
-
- /* Burst sizes */
- .burst_size_rx_read = 64,
- .burst_size_rx_write = 64,
- .burst_size_worker_read = 64,
- .burst_size_worker_write = 64,
- .burst_size_tx_read = 64,
- .burst_size_tx_write = 64,
-};
-
-static struct rte_eth_conf port_conf = {
- .rxmode = {
- .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM,
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_hf = RTE_ETH_RSS_IP,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
-};
-
-static struct rte_eth_rxconf rx_conf = {
- .rx_thresh = {
- .pthresh = 8,
- .hthresh = 8,
- .wthresh = 4,
- },
- .rx_free_thresh = 64,
- .rx_drop_en = 0,
-};
-
-static struct rte_eth_txconf tx_conf = {
- .tx_thresh = {
- .pthresh = 36,
- .hthresh = 0,
- .wthresh = 0,
- },
- .tx_free_thresh = 0,
- .tx_rs_thresh = 0,
-};
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
- app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
- app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
- if (app.pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
-
- app.rings_rx[i] = rte_ring_create(
- name,
- app.ring_rx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
-
- app.rings_tx[i] = rte_ring_create(
- name,
- app.ring_tx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static void
-app_ports_check_link(void)
-{
- uint32_t all_ports_up, i;
- char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
- all_ports_up = 1;
-
- for (i = 0; i < app.n_ports; i++) {
- struct rte_eth_link link;
- uint16_t port;
- int ret;
-
- port = app.ports[i];
- memset(&link, 0, sizeof(link));
- ret = rte_eth_link_get_nowait(port, &link);
- if (ret < 0) {
- RTE_LOG(INFO, USER1,
- "Failed to get port %u link status: %s\n",
- port, rte_strerror(-ret));
- all_ports_up = 0;
- continue;
- }
- rte_eth_link_to_str(link_status_text, sizeof(link_status_text),
- &link);
- RTE_LOG(INFO, USER1, "Port %u %s\n",
- port,
- link_status_text);
- if (link.link_status == RTE_ETH_LINK_DOWN)
- all_ports_up = 0;
- }
-
- if (all_ports_up == 0)
- rte_panic("Some NIC ports are DOWN\n");
-}
-
-static void
-app_init_ports(void)
-{
- uint32_t i;
- struct rte_eth_dev_info dev_info;
-
- /* Init NIC ports, then start the ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
- int ret;
- struct rte_eth_conf local_port_conf = port_conf;
-
- port = app.ports[i];
- RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port);
-
- ret = rte_eth_dev_info_get(port, &dev_info);
- if (ret != 0)
- rte_panic("Error during getting device (port %u) info: %s\n",
- port, rte_strerror(-ret));
-
- /* Init port */
- local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
- dev_info.flow_type_rss_offloads;
- if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
- port_conf.rx_adv_conf.rss_conf.rss_hf) {
- printf("Warning:"
- "Port %u modified RSS hash function based on hardware support,"
- "requested:%#"PRIx64" configured:%#"PRIx64"\n",
- port,
- port_conf.rx_adv_conf.rss_conf.rss_hf,
- local_port_conf.rx_adv_conf.rss_conf.rss_hf);
- }
-
- ret = rte_eth_dev_configure(
- port,
- 1,
- 1,
- &local_port_conf);
- if (ret < 0)
- rte_panic("Cannot init NIC port %u (%d)\n", port, ret);
-
- ret = rte_eth_promiscuous_enable(port);
- if (ret != 0)
- rte_panic("Cannot enable promiscuous mode for port %u: %s\n",
- port, rte_strerror(-ret));
-
- /* Init RX queues */
- ret = rte_eth_rx_queue_setup(
- port,
- 0,
- app.port_rx_ring_size,
- rte_eth_dev_socket_id(port),
- &rx_conf,
- app.pool);
- if (ret < 0)
- rte_panic("Cannot init RX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Init TX queues */
- ret = rte_eth_tx_queue_setup(
- port,
- 0,
- app.port_tx_ring_size,
- rte_eth_dev_socket_id(port),
- &tx_conf);
- if (ret < 0)
- rte_panic("Cannot init TX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Start port */
- ret = rte_eth_dev_start(port);
- if (ret < 0)
- rte_panic("Cannot start port %u (%d)\n", port, ret);
- }
-
- app_ports_check_link();
-}
-
-void
-app_init(void)
-{
- app_init_mbuf_pools();
- app_init_rings();
- app_init_ports();
-
- RTE_LOG(INFO, USER1, "Initialization completed\n");
-}
diff --git a/app/test-pipeline/main.c b/app/test-pipeline/main.c
deleted file mode 100644
index e5efafdf28..0000000000
--- a/app/test-pipeline/main.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <errno.h>
-#include <getopt.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-bool force_quit;
-
-static void
-signal_handler(int signum)
-{
- if (signum == SIGINT || signum == SIGTERM)
- force_quit = true;
-}
-
-int
-main(int argc, char **argv)
-{
- uint32_t lcore;
- uint32_t i;
- int ret;
-
- /* Init EAL */
- ret = rte_eal_init(argc, argv);
- if (ret < 0)
- return -1;
- argc -= ret;
- argv += ret;
-
- force_quit = false;
- signal(SIGINT, signal_handler);
- signal(SIGTERM, signal_handler);
-
- /* Parse application arguments (after the EAL ones) */
- ret = app_parse_args(argc, argv);
- if (ret < 0) {
- app_print_usage();
- return -1;
- }
-
- /* Init */
- app_init();
-
- /* Launch per-lcore init on every lcore */
- rte_eal_mp_remote_launch(app_lcore_main_loop, NULL, CALL_MAIN);
- RTE_LCORE_FOREACH_WORKER(lcore) {
- if (rte_eal_wait_lcore(lcore) < 0)
- return -1;
- }
-
- /* Close ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
-
- port = app.ports[i];
- printf("Closing port %d...", port);
- ret = rte_eth_dev_stop(port);
- if (ret != 0)
- printf("rte_eth_dev_stop: err=%d, port=%u\n",
- ret, port);
- rte_eth_dev_close(port);
- printf("Done\n");
- }
-
- /* Clean up the EAL */
- rte_eal_cleanup();
-
- return 0;
-}
-
-int
-app_lcore_main_loop(__rte_unused void *arg)
-{
- unsigned lcore;
-
- lcore = rte_lcore_id();
-
- if (lcore == app.core_rx) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_ACL:
- app_main_loop_rx();
- return 0;
-
- default:
- app_main_loop_rx_metadata();
- return 0;
- }
- }
-
- if (lcore == app.core_worker) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_STUB:
- app_main_loop_worker_pipeline_stub();
- return 0;
-
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- /* cases for cuckoo hash table types */
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- app_main_loop_worker_pipeline_hash();
- return 0;
-
- case e_APP_PIPELINE_ACL:
-#ifndef RTE_LIB_ACL
- rte_exit(EXIT_FAILURE, "ACL not present in build\n");
-#else
- app_main_loop_worker_pipeline_acl();
- return 0;
-#endif
-
- case e_APP_PIPELINE_LPM:
- app_main_loop_worker_pipeline_lpm();
- return 0;
-
- case e_APP_PIPELINE_LPM_IPV6:
- app_main_loop_worker_pipeline_lpm_ipv6();
- return 0;
-
- case e_APP_PIPELINE_NONE:
- default:
- app_main_loop_worker();
- return 0;
- }
- }
-
- if (lcore == app.core_tx) {
- app_main_loop_tx();
- return 0;
- }
-
- return 0;
-}
diff --git a/app/test-pipeline/main.h b/app/test-pipeline/main.h
deleted file mode 100644
index ee9c58ac4c..0000000000
--- a/app/test-pipeline/main.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-#ifndef APP_MBUF_ARRAY_SIZE
-#define APP_MBUF_ARRAY_SIZE 256
-#endif
-
-struct app_mbuf_array {
- struct rte_mbuf *array[APP_MBUF_ARRAY_SIZE];
- uint16_t n_mbufs;
-};
-
-#ifndef APP_MAX_PORTS
-#define APP_MAX_PORTS 4
-#endif
-
-struct __rte_cache_aligned app_params {
- /* CPU cores */
- uint32_t core_rx;
- uint32_t core_worker;
- uint32_t core_tx;
-
- /* Ports*/
- uint32_t ports[APP_MAX_PORTS];
- uint32_t n_ports;
- uint32_t port_rx_ring_size;
- uint32_t port_tx_ring_size;
-
- /* Rings */
- struct rte_ring *rings_rx[APP_MAX_PORTS];
- struct rte_ring *rings_tx[APP_MAX_PORTS];
- uint32_t ring_rx_size;
- uint32_t ring_tx_size;
-
- /* Internal buffers */
- struct app_mbuf_array mbuf_rx;
- struct app_mbuf_array mbuf_tx[APP_MAX_PORTS];
-
- /* Buffer pool */
- struct rte_mempool *pool;
- uint32_t pool_buffer_size;
- uint32_t pool_size;
- uint32_t pool_cache_size;
-
- /* Burst sizes */
- uint32_t burst_size_rx_read;
- uint32_t burst_size_rx_write;
- uint32_t burst_size_worker_read;
- uint32_t burst_size_worker_write;
- uint32_t burst_size_tx_read;
- uint32_t burst_size_tx_write;
-
- /* App behavior */
- uint32_t pipeline_type;
-};
-
-extern struct app_params app;
-
-extern bool force_quit;
-
-int app_parse_args(int argc, char **argv);
-void app_print_usage(void);
-void app_init(void);
-int app_lcore_main_loop(void *arg);
-
-/* Pipeline */
-enum {
- e_APP_PIPELINE_NONE = 0,
- e_APP_PIPELINE_STUB,
-
- e_APP_PIPELINE_HASH_KEY8_EXT,
- e_APP_PIPELINE_HASH_KEY8_LRU,
- e_APP_PIPELINE_HASH_KEY16_EXT,
- e_APP_PIPELINE_HASH_KEY16_LRU,
- e_APP_PIPELINE_HASH_KEY32_EXT,
- e_APP_PIPELINE_HASH_KEY32_LRU,
-
- e_APP_PIPELINE_HASH_SPEC_KEY8_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY8_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY16_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY16_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY32_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY32_LRU,
-
- e_APP_PIPELINE_ACL,
- e_APP_PIPELINE_LPM,
- e_APP_PIPELINE_LPM_IPV6,
-
- e_APP_PIPELINE_HASH_CUCKOO_KEY8,
- e_APP_PIPELINE_HASH_CUCKOO_KEY16,
- e_APP_PIPELINE_HASH_CUCKOO_KEY32,
- e_APP_PIPELINE_HASH_CUCKOO_KEY48,
- e_APP_PIPELINE_HASH_CUCKOO_KEY64,
- e_APP_PIPELINE_HASH_CUCKOO_KEY80,
- e_APP_PIPELINE_HASH_CUCKOO_KEY96,
- e_APP_PIPELINE_HASH_CUCKOO_KEY112,
- e_APP_PIPELINE_HASH_CUCKOO_KEY128,
- e_APP_PIPELINES
-};
-
-void app_main_loop_rx(void);
-void app_main_loop_rx_metadata(void);
-uint64_t test_hash(void *key,
- void *key_mask,
- uint32_t key_size,
- uint64_t seed);
-
-uint32_t test_hash_cuckoo(const void *key,
- uint32_t key_size,
- uint32_t seed);
-
-void app_main_loop_worker(void);
-void app_main_loop_worker_pipeline_stub(void);
-void app_main_loop_worker_pipeline_hash(void);
-void app_main_loop_worker_pipeline_acl(void);
-void app_main_loop_worker_pipeline_lpm(void);
-void app_main_loop_worker_pipeline_lpm_ipv6(void);
-
-void app_main_loop_tx(void);
-
-#define APP_FLUSH 0
-#ifndef APP_FLUSH
-#define APP_FLUSH 0x3FF
-#endif
-
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#endif /* _MAIN_H_ */
diff --git a/app/test-pipeline/meson.build b/app/test-pipeline/meson.build
deleted file mode 100644
index 3add6b637b..0000000000
--- a/app/test-pipeline/meson.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2019 Intel Corporation
-
-if is_windows
- build = false
- reason = 'not supported on Windows'
- subdir_done()
-endif
-
-sources = files(
- 'config.c',
- 'init.c',
- 'main.c',
- 'pipeline_acl.c',
- 'pipeline_hash.c',
- 'pipeline_lpm.c',
- 'pipeline_lpm_ipv6.c',
- 'pipeline_stub.c',
- 'runtime.c',
-)
-deps += ['pipeline', 'pci']
diff --git a/app/test-pipeline/pipeline_acl.c b/app/test-pipeline/pipeline_acl.c
deleted file mode 100644
index 9eb4053e23..0000000000
--- a/app/test-pipeline/pipeline_acl.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_acl.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-/*
- * Here we define the 'shape' of the data we're searching for,
- * by defining the meta-data of the ACL rules.
- * in this case, we're defining 5 tuples. IP addresses, ports,
- * and protocol.
- */
-struct rte_acl_field_def ipv4_field_formats[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, src_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, dst_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr) + sizeof(uint16_t),
- },
-};
-
-
-
-void
-app_main_loop_worker_pipeline_acl(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with ACL table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_acl_params table_acl_params = {
- .name = "test", /* unique identifier for acl contexts */
- .n_rules = 1 << 5,
- .n_rule_fields = DIM(ipv4_field_formats),
- };
-
- /* Copy in the rule meta-data defined above into the params */
- memcpy(table_acl_params.field_format, ipv4_field_formats,
- sizeof(ipv4_field_formats));
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_acl_ops,
- .arg_create = &table_acl_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the ACL table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_entry *entry_ptr;
- int key_found, ret;
-
- memset(&rule_params, 0, sizeof(rule_params));
-
- /* Set the rule values */
- rule_params.field_value[SRC_FIELD_IPV4].value.u32 = 0;
- rule_params.field_value[SRC_FIELD_IPV4].mask_range.u32 = 0;
- rule_params.field_value[DST_FIELD_IPV4].value.u32 =
- i << (24 - rte_popcount32(app.n_ports - 1));
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32 =
- 8 + rte_popcount32(app.n_ports - 1);
- rule_params.field_value[SRCP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[SRCP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[DSTP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[DSTP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[PROTO_FIELD_IPV4].value.u8 = 0;
- rule_params.field_value[PROTO_FIELD_IPV4].mask_range.u8 = 0;
-
- rule_params.priority = 0;
-
- uint32_t dst_addr = rule_params.field_value[DST_FIELD_IPV4].
- value.u32;
- uint32_t dst_mask =
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32;
-
- printf("Adding rule to ACL table (IPv4 destination = "
- "%u.%u.%u.%u/%u => port out = %u)\n",
- (dst_addr & 0xFF000000) >> 24,
- (dst_addr & 0x00FF0000) >> 16,
- (dst_addr & 0x0000FF00) >> 8,
- dst_addr & 0x000000FF,
- dst_mask,
- table_entry.port_id);
-
- /* For ACL, add needs an rte_table_acl_rule_add_params struct */
- ret = rte_pipeline_table_entry_add(p, table_id, &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, ret);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
deleted file mode 100644
index 194e5c5dcc..0000000000
--- a/app/test-pipeline/pipeline_hash.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_hash.h>
-#include <rte_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-static void
-translate_options(uint32_t *special, uint32_t *ext, uint32_t *key_size)
-{
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- *special = 0; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- *special = 0; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- *special = 0; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- *special = 0; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- *special = 1; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- *special = 1; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- *special = 1; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- *special = 1; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- *special = 1; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- *special = 1; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- *special = 0; *ext = 0; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- *special = 0; *ext = 0; *key_size = 48; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- *special = 0; *ext = 0; *key_size = 64; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- *special = 0; *ext = 0; *key_size = 80; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- *special = 0; *ext = 0; *key_size = 96; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- *special = 0; *ext = 0; *key_size = 112; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- *special = 0; *ext = 0; *key_size = 128; return;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-}
-void
-app_main_loop_worker_pipeline_hash(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
- uint32_t special, ext, key_size;
-
- translate_options(&special, &ext, &key_size);
-
- RTE_LOG(INFO, USER1, "Core %u is doing work "
- "(pipeline with hash table, %s, %s, %d-byte key)\n",
- rte_lcore_id(),
- special ? "specialized" : "non-specialized",
- ext ? "extendible bucket" : "LRU",
- key_size);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- struct rte_table_hash_params table_hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash,
- .seed = 0,
- };
-
- struct rte_table_hash_cuckoo_params table_hash_cuckoo_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash_cuckoo,
- .seed = 0,
- };
-
- /* Table configuration */
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table)\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_cuckoo_ops,
- .arg_create = &table_hash_cuckoo_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < (1 << 24); i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_pipeline_table_entry *entry_ptr;
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) key;
- int key_found, status;
-
- memset(key, 0, sizeof(key));
- k32[0] = rte_be_to_cpu_32(i);
-
- status = rte_pipeline_table_entry_add(p, table_id, key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
-
-uint64_t test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-uint32_t test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-void
-app_main_loop_rx_metadata(void) {
- uint32_t i, j;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX (with meta-data)\n",
- rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- for (j = 0; j < n_mbufs; j++) {
- struct rte_mbuf *m;
- uint8_t *m_data, *key;
- struct rte_ipv4_hdr *ip_hdr;
- struct rte_ipv6_hdr *ipv6_hdr;
- uint32_t ip_dst;
- uint32_t *signature, *k32;
-
- m = app.mbuf_rx.array[j];
- m_data = rte_pktmbuf_mtod(m, uint8_t *);
- signature = RTE_MBUF_METADATA_UINT32_PTR(m,
- APP_METADATA_OFFSET(0));
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
- ip_hdr = (struct rte_ipv4_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
- ip_dst = ip_hdr->dst_addr;
-
- k32 = (uint32_t *) key;
- k32[0] = ip_dst & 0xFFFFFF00;
- } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
- ipv6_hdr = (struct rte_ipv6_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
-
- memcpy(key, &ipv6_hdr->dst_addr, 16);
- } else
- continue;
-
- *signature = test_hash(key, NULL, 0, 0);
- }
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
diff --git a/app/test-pipeline/pipeline_lpm.c b/app/test-pipeline/pipeline_lpm.c
deleted file mode 100644
index 8a59bd0042..0000000000
--- a/app/test-pipeline/pipeline_lpm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-#ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s
-#define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256
-#endif
-
-void
-app_main_loop_worker_pipeline_lpm(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with "
- "LPM table)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_params table_lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s,
- .flags = 0,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ops,
- .arg_create = &table_lpm_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_key key = {
- .ip = i << (24 - rte_popcount32(app.n_ports - 1)),
- .depth = 8 + rte_popcount32(app.n_ports - 1),
- };
-
- struct rte_pipeline_table_entry *entry_ptr;
-
- int key_found, status;
-
- printf("Adding rule to LPM table (IPv4 destination = %"
- PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8
- " => port out = %" PRIu32 ")\n",
- (key.ip & 0xFF000000) >> 24,
- (key.ip & 0x00FF0000) >> 16,
- (key.ip & 0x0000FF00) >> 8,
- key.ip & 0x000000FF,
- key.depth,
- i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_lpm_ipv6.c b/app/test-pipeline/pipeline_lpm_ipv6.c
deleted file mode 100644
index 6558e887c8..0000000000
--- a/app/test-pipeline/pipeline_lpm_ipv6.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_lpm_ipv6(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with IPv6 LPM table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_ipv6_params table_lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 21,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ipv6_ops,
- .arg_create = &table_lpm_ipv6_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the IPv6 LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_ipv6_key key;
- struct rte_pipeline_table_entry *entry_ptr;
- uint32_t ip;
- int key_found, status;
-
- key.depth = 8 + rte_popcount32(app.n_ports - 1);
-
- ip = rte_bswap32(i << (24 -
- rte_popcount32(app.n_ports - 1)));
- memcpy(&key.ip, &ip, sizeof(uint32_t));
-
- printf("Adding rule to IPv6 LPM table (IPv6 destination = "
- RTE_IPV6_ADDR_FMT "/%u => port out = %u)\n",
- RTE_IPV6_ADDR_SPLIT(&key.ip),
- key.depth, i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_stub.c b/app/test-pipeline/pipeline_stub.c
deleted file mode 100644
index 48a638aad7..0000000000
--- a/app/test-pipeline/pipeline_stub.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_port_ring.h>
-#include <rte_table_stub.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_stub(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id[APP_MAX_PORTS];
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with stub "
- "tables)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i]))
- rte_panic("Unable to configure table %u\n", i);
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i]))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i ^ 1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (rte_pipeline_table_default_entry_add(p, table_id[i], &entry,
- &default_entry_ptr))
- rte_panic("Unable to add default entry to table %u\n",
- table_id[i]);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/runtime.c b/app/test-pipeline/runtime.c
deleted file mode 100644
index 752f783370..0000000000
--- a/app/test-pipeline/runtime.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_malloc.h>
-
-#include "main.h"
-
-void
-app_main_loop_rx(void) {
- uint32_t i;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs, NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_worker(void) {
- struct app_mbuf_array *worker_mbuf;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (no pipeline)\n",
- rte_lcore_id());
-
- worker_mbuf = rte_malloc_socket(NULL, sizeof(struct app_mbuf_array),
- RTE_CACHE_LINE_SIZE, rte_socket_id());
- if (worker_mbuf == NULL)
- rte_panic("Worker thread: cannot allocate buffer space\n");
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- int ret;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_rx[i],
- (void **) worker_mbuf->array,
- app.burst_size_worker_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_tx[i ^ 1],
- (void **) worker_mbuf->array,
- app.burst_size_worker_write,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_tx(void) {
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing TX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs, n_pkts;
- int ret;
-
- n_mbufs = app.mbuf_tx[i].n_mbufs;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_tx[i],
- (void **) &app.mbuf_tx[i].array[n_mbufs],
- app.burst_size_tx_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- n_mbufs += app.burst_size_tx_read;
-
- if (n_mbufs < app.burst_size_tx_write) {
- app.mbuf_tx[i].n_mbufs = n_mbufs;
- continue;
- }
-
- n_pkts = rte_eth_tx_burst(
- app.ports[i],
- 0,
- app.mbuf_tx[i].array,
- n_mbufs);
-
- if (n_pkts < n_mbufs) {
- uint16_t k;
-
- for (k = n_pkts; k < n_mbufs; k++) {
- struct rte_mbuf *pkt_to_free;
-
- pkt_to_free = app.mbuf_tx[i].array[k];
- rte_pktmbuf_free(pkt_to_free);
- }
- }
-
- app.mbuf_tx[i].n_mbufs = 0;
- }
- }
-}
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index c8cc86295d..6ad0cf6eec 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -77,6 +77,9 @@ Removed Items
``rte_rib6_is_equal``
* table: ``RTE_LPM_IPV6_ADDR_SIZE``
+* Removed the ``dpdk-test-pipeline`` application, which was based on
+ the legacy pipeline library API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/img/test_pipeline_app.png b/doc/guides/sample_app_ug/img/test_pipeline_app.png
deleted file mode 100644
index d322a9e46e5e714126988a76456c9eae41635879..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 67410
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%0D%V3H
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"Exg8HvZ0ke@W&Fw<
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
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index f12623bb66..c8b50b801c 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -45,7 +45,6 @@ Sample Applications User Guides
vhost_crypto
vdpa
ip_pipeline
- test_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/test_pipeline.rst b/doc/guides/sample_app_ug/test_pipeline.rst
deleted file mode 100644
index e53d77a170..0000000000
--- a/doc/guides/sample_app_ug/test_pipeline.rst
+++ /dev/null
@@ -1,237 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2010-2014 Intel Corporation.
-
-Test Pipeline Application
-=========================
-
-The Test Pipeline application illustrates the use of the DPDK Packet Framework tool suite.
-Its purpose is to demonstrate the performance of single-table DPDK pipelines.
-
-Overview
---------
-
-The application uses three CPU cores:
-
-* Core A ("RX core") receives traffic from the NIC ports and feeds core B with traffic through SW queues.
-
-* Core B ("Pipeline core") implements a single-table DPDK pipeline
- whose type is selectable through specific command line parameter.
- Core B receives traffic from core A through software queues,
- processes it according to the actions configured in the table entries that
- are hit by the input packets and feeds it to core C through another set of software queues.
-
-* Core C ("TX core") receives traffic from core B through software queues and sends it to the NIC ports for transmission.
-
-.. figure:: img/test_pipeline_app.*
-
- Test Pipeline Application
-
-Compiling the Application
--------------------------
-To compile the sample application see :doc:`compiling`
-
-The application is located in the ``dpdk/<build_dir>/app`` directory.
-
-
-Running the Application
------------------------
-
-Application Command Line
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The application execution command line is:
-
-.. code-block:: console
-
- ./dpdk-test-pipeline [EAL options] -- -p PORTMASK --TABLE_TYPE
-
-The ``-l/--lcores`` EAL CPU corelist option has to contain exactly 3 CPU cores.
-The first CPU core in the core mask is assigned for core A, the second for core B and the third for core C.
-
-The PORTMASK parameter must contain 2 or 4 ports.
-
-Table Types and Behavior
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-:numref:`test_pipeline_table_1` describes the table types used and how they are populated.
-
-The hash tables are pre-populated with 16 million keys.
-For hash tables, the following parameters can be selected:
-
-* **Configurable key size implementation or fixed (specialized) key size implementation (e.g. hash-8-ext or hash-spec-8-ext).**
- The key size specialized implementations are expected to provide better performance for 8-byte and 16-byte key sizes,
- while the key-size-non-specialized implementation is expected to provide better performance for larger key sizes;
-
-* **Key size (e.g. hash-spec-8-ext or hash-spec-16-ext).**
- The available options are 8, 16 and 32 bytes;
-
-* **Table type (e.g. hash-spec-16-ext or hash-spec-16-lru).**
- The available options are ext (extendable bucket) or lru (least recently used).
-
-.. _test_pipeline_table_1:
-
-.. table:: Table Types
-
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | **#** | **TABLE_TYPE** | **Description of Core B Table** | **Pre-added Table Entries** |
- | | | | |
- +=======+========================+==========================================================+=======================================================+
- | 1 | none | Core B is not implementing a DPDK pipeline. | N/A |
- | | | Core B is implementing a pass-through from its input set | |
- | | | of software queues to its output set of software queues. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 2 | stub | Stub table. Core B is implementing the same pass-through | N/A |
- | | | functionality as described for the "none" option by | |
- | | | using the DPDK Packet Framework by using one | |
- | | | stub table for each input NIC port. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 3 | hash-[spec]-8-lru | LRU hash table with 8-byte key size and 16 million | 16 million entries are successfully added to the |
- | | | entries. | hash table with the following key format: |
- | | | | |
- | | | | [4-byte index, 4 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Sendto output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | core B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 4 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 4 | hash-[spec]-8-ext | Extendable bucket hash table with 8-byte key size | Same as hash-[spec]-8-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 5 | hash-[spec]-16-lru | LRU hash table with 16-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 12 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for core |
- | | | | B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 12 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 6 | hash-[spec]-16-ext | Extendable bucket hash table with 16-byte key size | Same as hash-[spec]-16-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 7 | hash-[spec]-32-lru | LRU hash table with 32-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 28 bytes of 0]. |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | Lpmcore B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 28 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 8 | hash-[spec]-32-ext | Extendable bucket hash table with 32-byte key size | Same as hash-[spec]-32-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 9 | lpm | Longest Prefix Match (LPM) IPv4 table. | In the case of two ports, two routes |
- | | | | are added to the table: |
- | | | | |
- | | | | [0.0.0.0/9 => send to output port 0] |
- | | | | |
- | | | | [0.128.0.0/9 => send to output port 1] |
- | | | | |
- | | | | In case of four ports, four entries are added to the |
- | | | | table: |
- | | | | |
- | | | | [0.0.0.0/10 => send to output port 0] |
- | | | | |
- | | | | [0.64.0.0/10 => send to output port 1] |
- | | | | |
- | | | | [0.128.0.0/10 => send to output port 2] |
- | | | | |
- | | | | [0.192.0.0/10 => send to output port 3] |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is storing the IPv4 destination |
- | | | | within the packet meta data to be later used by core |
- | | | | B as the lookup key. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 10 | acl | Access Control List (ACL) table | In the case of two ports, two ACL rules are added to |
- | | | | the table: |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.0.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0] |
- | | | | |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.128.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0]. |
- | | | | |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
-
-Input Traffic
-~~~~~~~~~~~~~
-
-Regardless of the table type used for the core B pipeline,
-the same input traffic can be used to hit all table entries with uniform distribution,
-which results in uniform distribution of packets sent out on the set of output NIC ports.
-The profile for input traffic is TCP/IPv4 packets with:
-
-* destination IP address as A.B.C.D with A fixed to 0 and B, C,D random
-
-* source IP address fixed to 0.0.0.0
-
-* destination TCP port fixed to 0
-
-* source TCP port fixed to 0
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v3 3/6] examples/ip_pipeline: remove example
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 1/6] app/test: remove packet framework tests Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 2/6] app/test-pipeline: remove application Stephen Hemminger
@ 2026-07-28 14:20 ` Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 4/6] pipeline: remove legacy API Stephen Hemminger
` (2 subsequent siblings)
5 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 14:20 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon, Cristian Dumitrescu
The ip_pipeline example is built on the legacy pipeline library
API (rte_pipeline_*) and the associated port and table action
APIs, which were announced for removal in the 24.11 release.
The pipeline example covers the SWX pipeline API.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
doc/guides/nics/softnic.rst | 3 +-
doc/guides/rel_notes/release_26_11.rst | 4 +
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
examples/ip_pipeline/Makefile | 60 -
examples/ip_pipeline/action.c | 391 -
examples/ip_pipeline/action.h | 78 -
examples/ip_pipeline/cli.c | 6791 -----------------
examples/ip_pipeline/cli.h | 18 -
examples/ip_pipeline/common.h | 12 -
examples/ip_pipeline/conn.c | 330 -
examples/ip_pipeline/conn.h | 47 -
examples/ip_pipeline/cryptodev.c | 160 -
examples/ip_pipeline/cryptodev.h | 46 -
examples/ip_pipeline/examples/firewall.cli | 59 -
examples/ip_pipeline/examples/flow.cli | 60 -
examples/ip_pipeline/examples/flow_crypto.cli | 57 -
examples/ip_pipeline/examples/l2fwd.cli | 51 -
examples/ip_pipeline/examples/route.cli | 60 -
examples/ip_pipeline/examples/route_ecmp.cli | 57 -
| 112 -
examples/ip_pipeline/examples/tap.cli | 66 -
examples/ip_pipeline/link.c | 270 -
examples/ip_pipeline/link.h | 66 -
examples/ip_pipeline/main.c | 260 -
examples/ip_pipeline/mempool.c | 82 -
examples/ip_pipeline/mempool.h | 40 -
examples/ip_pipeline/meson.build | 30 -
examples/ip_pipeline/parser.c | 506 --
examples/ip_pipeline/parser.h | 56 -
examples/ip_pipeline/pipeline.c | 1078 ---
examples/ip_pipeline/pipeline.h | 425 --
examples/ip_pipeline/swq.c | 76 -
examples/ip_pipeline/swq.h | 37 -
examples/ip_pipeline/tap.c | 102 -
examples/ip_pipeline/tap.h | 29 -
examples/ip_pipeline/thread.c | 3137 --------
examples/ip_pipeline/thread.h | 24 -
examples/ip_pipeline/tmgr.c | 248 -
examples/ip_pipeline/tmgr.h | 74 -
examples/meson.build | 1 -
42 files changed, 5 insertions(+), 15532 deletions(-)
delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
delete mode 100644 examples/ip_pipeline/Makefile
delete mode 100644 examples/ip_pipeline/action.c
delete mode 100644 examples/ip_pipeline/action.h
delete mode 100644 examples/ip_pipeline/cli.c
delete mode 100644 examples/ip_pipeline/cli.h
delete mode 100644 examples/ip_pipeline/common.h
delete mode 100644 examples/ip_pipeline/conn.c
delete mode 100644 examples/ip_pipeline/conn.h
delete mode 100644 examples/ip_pipeline/cryptodev.c
delete mode 100644 examples/ip_pipeline/cryptodev.h
delete mode 100644 examples/ip_pipeline/examples/firewall.cli
delete mode 100644 examples/ip_pipeline/examples/flow.cli
delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
delete mode 100644 examples/ip_pipeline/examples/route.cli
delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
delete mode 100644 examples/ip_pipeline/examples/rss.cli
delete mode 100644 examples/ip_pipeline/examples/tap.cli
delete mode 100644 examples/ip_pipeline/link.c
delete mode 100644 examples/ip_pipeline/link.h
delete mode 100644 examples/ip_pipeline/main.c
delete mode 100644 examples/ip_pipeline/mempool.c
delete mode 100644 examples/ip_pipeline/mempool.h
delete mode 100644 examples/ip_pipeline/meson.build
delete mode 100644 examples/ip_pipeline/parser.c
delete mode 100644 examples/ip_pipeline/parser.h
delete mode 100644 examples/ip_pipeline/pipeline.c
delete mode 100644 examples/ip_pipeline/pipeline.h
delete mode 100644 examples/ip_pipeline/swq.c
delete mode 100644 examples/ip_pipeline/swq.h
delete mode 100644 examples/ip_pipeline/tap.c
delete mode 100644 examples/ip_pipeline/tap.h
delete mode 100644 examples/ip_pipeline/thread.c
delete mode 100644 examples/ip_pipeline/thread.h
delete mode 100644 examples/ip_pipeline/tmgr.c
delete mode 100644 examples/ip_pipeline/tmgr.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 4c06f85706..ae84e7f289 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,9 +1739,7 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: examples/ip_pipeline/
F: examples/pipeline/
-F: doc/guides/sample_app_ug/ip_pipeline.rst
Algorithms
diff --git a/doc/guides/nics/softnic.rst b/doc/guides/nics/softnic.rst
index 603fdb49c4..87f3e5adc0 100644
--- a/doc/guides/nics/softnic.rst
+++ b/doc/guides/nics/softnic.rst
@@ -10,8 +10,7 @@ is DIY and reconfigurable through ``firmware`` (DPDK Packet Framework script).
The Soft NIC leverages the DPDK Packet Framework libraries (librte_port,
librte_table and librte_pipeline) to make it modular, flexible and extensible
with new functionality.
-Please refer to :doc:`/prog_guide/packet_framework` and
-:doc:`/sample_app_ug/ip_pipeline` for more details.
+Please refer to :doc:`/prog_guide/packet_framework` for more details.
The Soft NIC is configured through the standard DPDK ethdev API (ethdev, flow,
QoS, security). The internal framework is not externally visible.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 6ad0cf6eec..fc84ba367e 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -80,6 +80,10 @@ Removed Items
* Removed the ``dpdk-test-pipeline`` application, which was based on
the legacy pipeline library API.
+* Removed the ``ip_pipeline`` example application, which was based on
+ the legacy pipeline library API.
+ The ``pipeline`` example application covers the SWX pipeline API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index c8b50b801c..28c4c9a5b2 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -44,7 +44,6 @@ Sample Applications User Guides
vhost_blk
vhost_crypto
vdpa
- ip_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/ip_pipeline.rst b/doc/guides/sample_app_ug/ip_pipeline.rst
deleted file mode 100644
index 9a5cb517a2..0000000000
--- a/doc/guides/sample_app_ug/ip_pipeline.rst
+++ /dev/null
@@ -1,531 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2015-2018 Intel Corporation.
-
-Internet Protocol (IP) Pipeline Application
-===========================================
-
-Application overview
---------------------
-
-The *Internet Protocol (IP) Pipeline* application is intended to be a vehicle for rapid development of packet processing
-applications on multi-core CPUs.
-
-Following OpenFlow and P4 design principles, the application can be used to create functional blocks called pipelines out
-of input/output ports, tables and actions in a modular way. Multiple pipelines can be inter-connected through packet queues
-to create complete applications (super-pipelines).
-
-The pipelines are mapped to application threads, with each pipeline executed by a single thread and each thread able to run
-one or several pipelines. The possibilities of creating pipelines out of ports, tables and actions, connecting multiple
-pipelines together and mapping the pipelines to execution threads are endless, therefore this application can be seen as
-a true application generator.
-
-Pipelines are created and managed through Command Line Interface (CLI):
-
- * Any standard TCP client (e.g. telnet, netcat, custom script, etc) is typically able to connect to the application, send
- commands through the network and wait for the response before pushing the next command.
-
- * All the application objects are created and managed through CLI commands:
- * 'Primitive' objects used to create pipeline ports: memory pools, links (i.e. network interfaces), SW queues, traffic managers, etc.
- * Action profiles: used to define the actions to be executed by pipeline input/output ports and tables.
- * Pipeline components: input/output ports, tables, pipelines, mapping of pipelines to execution threads.
-
-Running the application
------------------------
-
-The application startup command line is::
-
- dpdk-ip_pipeline [EAL_ARGS] -- [-s SCRIPT_FILE] [-h HOST] [-p PORT]
-
-The application startup arguments are:
-
-``-s SCRIPT_FILE``
-
- * Optional: Yes
-
- * Default: Not present
-
- * Argument: Path to the CLI script file to be run at application startup.
- No CLI script file will run at startup if this argument is not present.
-
-``-h HOST``
-
- * Optional: Yes
-
- * Default: ``0.0.0.0``
-
- * Argument: IP Address of the host running ip pipeline application to be used by
- remote TCP based client (telnet, netcat, etc.) for connection.
-
-``-p PORT``
-
- * Optional: Yes
-
- * Default: ``8086``
-
- * Argument: TCP port number at which the ip pipeline is running.
- This port number should be used by remote TCP client (such as telnet, netcat, etc.) to connect to host application.
-
-Refer to *DPDK Getting Started Guide* for general information on running applications and the Environment Abstraction Layer (EAL) options.
-
-The following is an example command to run ip pipeline application configured for layer 2 forwarding:
-
-.. code-block:: console
-
- $ ./<build_dir>/examples/dpdk-ip_pipeline -l 0,1 -- -s examples/route_ecmp.cli
-
-The application should start successfully and display as follows:
-
-.. code-block:: console
-
- EAL: Detected 40 lcore(s)
- EAL: Detected 2 NUMA nodes
- EAL: Multi-process socket /var/run/.rte_unix
- EAL: Probing VFIO support...
- EAL: PCI device 0000:02:00.0 on NUMA socket 0
- EAL: probe driver: 8086:10fb net_ixgbe
- ...
-
-To run remote client (e.g. telnet) to communicate with the ip pipeline application:
-
-.. code-block:: console
-
- $ telnet 127.0.0.1 8086
-
-When running a telnet client as above, command prompt is displayed:
-
-.. code-block:: console
-
- Trying 127.0.0.1...
- Connected to 127.0.0.1.
- Escape character is '^]'.
-
- Welcome to IP Pipeline!
-
- pipeline>
-
-Once application and telnet client start running, messages can be sent from client to application.
-At any stage, telnet client can be terminated using the quit command.
-
-
-Application stages
-------------------
-
-Initialization
-~~~~~~~~~~~~~~
-
-During this stage, EAL layer is initialised and application specific arguments are parsed. Furthermore, the data structures
-(i.e. linked lists) for application objects are initialized. In case of any initialization error, an error message
-is displayed and the application is terminated.
-
-Run-time
-~~~~~~~~
-
-The main thread is creating and managing all the application objects based on CLI input.
-
-Each data plane thread runs one or several pipelines previously assigned to it in round-robin order. Each data plane thread
-executes two tasks in time-sharing mode:
-
-#. *Packet processing task*: Process bursts of input packets read from the pipeline input ports.
-
-#. *Message handling task*: Periodically, the data plane thread pauses the packet processing task and polls for request
- messages send by the main thread. Examples: add/remove pipeline to/from current data plane thread, add/delete rules
- to/from given table of a specific pipeline owned by the current data plane thread, read statistics, etc.
-
-Examples
---------
-
-.. tabularcolumns:: |p{3cm}|p{5cm}|p{4cm}|p{4cm}|
-
-.. table:: Pipeline examples provided with the application
-
- +-----------------------+----------------------+----------------+------------------------------------+
- | Name | Table(s) | Actions | Messages |
- +=======================+======================+================+====================================+
- | L2fwd | Stub | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | Note: Implemented | | | 3. Pipeline create |
- | using pipeline with | | | 4. Pipeline port in/out |
- | a simple pass-through | | | 5. Pipeline table |
- | connection between | | | 6. Pipeline port in table |
- | input and output | | | 7. Pipeline enable |
- | ports. | | | 8. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Flow classification | Exact match | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = byte array | | 3. Pipeline create |
- | | (16 bytes) | | 4. Pipeline port in/out |
- | | * Offset = 278 | | 5. Pipeline table |
- | | * Table size = 64K | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Firewall | ACL | Allow/Drop | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = n-tuple | | 3. Pipeline create |
- | | * Offset = 270 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | IP routing | LPM (IPv4) | Forward | 1. Mempool Create |
- | | | | 2. Link create |
- | | * Key = IP dest addr | | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Equal-cost multi-path | LPM (IPv4) | Forward, | 1. Mempool Create |
- | routing (ECMP) | | load balance, | 2. Link create |
- | | * Key = IP dest addr | encap ether | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table (LPM) |
- | | | | 6. Pipeline table (Array) |
- | | | | 7. Pipeline port in table (LPM) |
- | | Array | | 8. Pipeline enable |
- | | | | 9. Pipeline table rule add default |
- | | * Key = Array index | | 10. Pipeline table rule add(LPM) |
- | | * Offset = 256 | | 11. Pipeline table rule add(Array) |
- | | * Size = 64K | | |
- | | | | |
- +-----------------------+----------------------+----------------+------------------------------------+
-
-Command Line Interface (CLI)
-----------------------------
-
-Link
-~~~~
-
- Link configuration ::
-
- link <link_name>
- dev <device_name>|port <port_id>
- rxq <n_queues> <queue_size> <mempool_name>
- txq <n_queues> <queue_size> promiscuous on | off
- [rss <qid_0> ... <qid_n>]
-
- Note: The PCI device name must be specified in the Domain:Bus:Device.Function format.
-
-
-Mempool
-~~~~~~~
-
- Mempool create ::
-
- mempool <mempool_name> buffer <buffer_size>
- pool <pool_size> cache <cache_size> cpu <cpu_id>
-
-
-Software queue
-~~~~~~~~~~~~~~
-
- Create software queue ::
-
- swq <swq_name> size <size> cpu <cpu_id>
-
-
-Traffic manager
-~~~~~~~~~~~~~~~
-
- Add traffic manager subport profile ::
-
- tmgr subport profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
-
- Add traffic manager pipe profile ::
-
- tmgr pipe profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
- <tc_ov_weight>
- <wrr_weight0..3>
-
- Create traffic manager port ::
-
- tmgr <tmgr_name>
- rate <rate>
- spp <n_subports_per_port>
- pps <n_pipes_per_subport>
- fo <frame_overhead>
- mtu <mtu>
- cpu <cpu_id>
-
- Configure traffic manager subport ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- profile <subport_profile_id>
-
- Configure traffic manager pipe ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- pipe from <pipe_id_first> to <pipe_id_last>
- profile <pipe_profile_id>
-
-
-Tap
-~~~
-
- Create tap port ::
-
- tap <name>
-
-
-Cryptodev
-~~~~~~~~~
-
- Create cryptodev port ::
-
- cryptodev <cryptodev_name>
- dev <DPDK Cryptodev PMD name>
- queue <n_queues> <queue_size>
-
-Action profile
-~~~~~~~~~~~~~~
-
- Create action profile for pipeline input port ::
-
- port in action profile <profile_name>
- [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
- [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
-
- Create action profile for the pipeline table ::
-
- table action profile <profile_name>
- ipv4 | ipv6
- offset <ip_offset>
- fwd
- [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
- [meter srtcm | trtcm
- tc <n_tc>
- stats none | pkts | bytes | both]
- [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
- [encap ether | vlan | qinq | mpls | pppoe]
- [nat src | dst
- proto udp | tcp]
- [ttl drop | fwd
- stats none | pkts]
- [stats pkts | bytes | both]
- [sym_crypto cryptodev <cryptodev_name>
- mempool_create <mempool_name> mempool_init <mempool_name>]
- [time]
-
-
-Pipeline
-~~~~~~~~
-
-Create pipeline ::
-
- pipeline <pipeline_name>
- period <timer_period_ms>
- offset_port_id <offset_port_id>
- cpu <cpu_id>
-
-Create pipeline input port ::
-
- pipeline <pipeline_name> port in
- bsz <burst_size>
- link <link_name> rxq <queue_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name> mempool <mempool_name> mtu <mtu>
- | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
- [action <port_in_action_profile_name>]
- [disabled]
-
-Create pipeline output port ::
-
- pipeline <pipeline_name> port out
- bsz <burst_size>
- link <link_name> txq <txq_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name>
- | sink [file <file_name> pkts <max_n_pkts>]
-
-Create pipeline table ::
-
- pipeline <pipeline_name> table
- match
- acl
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | array
- offset <key_offset>
- size <n_keys>
- | hash
- ext | lru
- key <key_size>
- mask <key_mask>
- offset <key_offset>
- buckets <n_buckets>
- size <n_keys>
- | lpm
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | stub
- [action <table_action_profile_name>]
-
-Connect pipeline input port to table ::
-
- pipeline <pipeline_name> port in <port_id> table <table_id>
-
-Display statistics for specific pipeline input port, output port
-or table ::
-
- pipeline <pipeline_name> port in <port_id> stats read [clear]
- pipeline <pipeline_name> port out <port_id> stats read [clear]
- pipeline <pipeline_name> table <table_id> stats read [clear]
-
-Enable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Disable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Add default rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
- match
- default
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
-
-Add rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
-
- match
- acl
- priority <priority>
- ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- <sp0> <sp1> <dp0> <dp1> <proto>
- | array <pos>
- | hash
- raw <key>
- | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv4_addr <addr>
- | ipv6_addr <addr>
- | qinq <svlan> <cvlan>
- | lpm
- ipv4 | ipv6 <addr> <depth>
-
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
- [balance <out0> ... <out7>]
- [meter
- tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- [tm subport <subport_id> pipe <pipe_id>]
- [encap
- ether <da> <sa>
- | vlan <da> <sa> <pcp> <dei> <vid>
- | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- | mpls unicast | multicast
- <da> <sa>
- label0 <label> <tc> <ttl>
- [label1 <label> <tc> <ttl>
- [label2 <label> <tc> <ttl>
- [label3 <label> <tc> <ttl>]]]
- | pppoe <da> <sa> <session_id>]
- [nat ipv4 | ipv6 <addr> <port>]
- [ttl dec | keep]
- [stats]
- [time]
- [sym_crypto
- encrypt | decrypt
- type
- | cipher
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- | cipher_auth
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- auth_algo <algo> auth_key <key> digest_size <size>
- | aead
- aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- digest_size <size>
- data_offset <data_offset>]
-
- where:
- <pa> ::= g | y | r | drop
-
-Add bulk rules to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
-
- Where:
- - file_name = path to file
- - File line format = match <match> action <action>
-
-Delete table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match <match>
-
-Delete default table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match
- default
-
-Add meter profile to the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
- add srtcm cir <cir> cbs <cbs> ebs <ebs>
- | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
-
-Delete meter profile from the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id>
- meter profile <meter_profile_id> delete
-
-
-Update the dscp table for meter or traffic manager action for specific
-pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> dscp <file_name>
-
- Where:
- - file_name = path to file
- - exactly 64 lines
- - File line format = <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
-
-
-Pipeline enable/disable
-~~~~~~~~~~~~~~~~~~~~~~~
-
- Enable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> enable
-
-
- Disable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> disable
diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
deleted file mode 100644
index 438aa6b37f..0000000000
--- a/examples/ip_pipeline/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2010-2018 Intel Corporation
-
-# binary name
-APP = ip_pipeline
-
-# all source are stored in SRCS-y
-SRCS-y := action.c
-SRCS-y += cli.c
-SRCS-y += conn.c
-SRCS-y += link.c
-SRCS-y += main.c
-SRCS-y += mempool.c
-SRCS-y += parser.c
-SRCS-y += pipeline.c
-SRCS-y += swq.c
-SRCS-y += tap.c
-SRCS-y += thread.c
-SRCS-y += tmgr.c
-SRCS-y += cryptodev.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)
-
-CFLAGS += -I. -DALLOW_EXPERIMENTAL_API -D_GNU_SOURCE
-
-OBJS := $(patsubst %.c,build/%.o,$(SRCS-y))
-
-build/%.o: %.c Makefile $(PC_FILE) | build
- $(CC) $(CFLAGS) -c $< -o $@
-
-build/$(APP)-shared: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
-
-build/$(APP)-static: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
-
-build:
- @mkdir -p $@
-
-.PHONY: clean
-clean:
- rm -f build/$(APP)* build/*.o
- test -d build && rmdir -p build || true
diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
deleted file mode 100644
index d2104aad6e..0000000000
--- a/examples/ip_pipeline/action.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-#include <rte_table_hash_func.h>
-
-#include "action.h"
-
-/**
- * Input port
- */
-static struct port_in_action_profile_list port_in_action_profile_list;
-
-int
-port_in_action_profile_init(void)
-{
- TAILQ_INIT(&port_in_action_profile_list);
-
- return 0;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name)
-{
- struct port_in_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &port_in_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params)
-{
- struct port_in_action_profile *profile;
- struct rte_port_in_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- port_in_action_profile_find(name) ||
- (params == NULL))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
- /* Resource */
- ap = rte_port_in_action_profile_create(0);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_FLTR,
- ¶ms->fltr);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_port_in_action_profile_freeze(ap);
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct port_in_action_profile));
- if (profile == NULL) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&port_in_action_profile_list, profile, node);
-
- return profile;
-}
-
-/**
- * Table
- */
-static struct table_action_profile_list table_action_profile_list;
-
-int
-table_action_profile_init(void)
-{
- TAILQ_INIT(&table_action_profile_list);
-
- return 0;
-}
-
-struct table_action_profile *
-table_action_profile_find(const char *name)
-{
- struct table_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &table_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params)
-{
- struct table_action_profile *profile;
- struct rte_table_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- table_action_profile_find(name) ||
- (params == NULL) ||
- ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
-
- /* Resource */
- ap = rte_table_action_profile_create(¶ms->common);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_FWD,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_MTR,
- ¶ms->mtr);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TM,
- ¶ms->tm);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_ENCAP,
- ¶ms->encap);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_NAT,
- ¶ms->nat);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TTL,
- ¶ms->ttl);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_STATS,
- ¶ms->stats);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TIME,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- ¶ms->sym_crypto);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TAG,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_DECAP,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_table_action_profile_freeze(ap);
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct table_action_profile));
- if (profile == NULL) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node);
-
- return profile;
-}
diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
deleted file mode 100644
index cde17e69a3..0000000000
--- a/examples/ip_pipeline/action.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_ACTION_H_
-#define _INCLUDE_ACTION_H_
-
-#include <sys/queue.h>
-
-#include <rte_port_in_action.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-
-/**
- * Input port action
- */
-struct port_in_action_profile_params {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-struct port_in_action_profile {
- TAILQ_ENTRY(port_in_action_profile) node;
- char name[NAME_SIZE];
- struct port_in_action_profile_params params;
- struct rte_port_in_action_profile *ap;
-};
-
-TAILQ_HEAD(port_in_action_profile_list, port_in_action_profile);
-
-int
-port_in_action_profile_init(void);
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name);
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params);
-
-/**
- * Table action
- */
-struct table_action_profile_params {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-struct table_action_profile {
- TAILQ_ENTRY(table_action_profile) node;
- char name[NAME_SIZE];
- struct table_action_profile_params params;
- struct rte_table_action_profile *ap;
-};
-
-TAILQ_HEAD(table_action_profile_list, table_action_profile);
-
-int
-table_action_profile_init(void);
-
-struct table_action_profile *
-table_action_profile_find(const char *name);
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params);
-
-#endif /* _INCLUDE_ACTION_H_ */
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
deleted file mode 100644
index 935c9b39d5..0000000000
--- a/examples/ip_pipeline/cli.c
+++ /dev/null
@@ -1,6791 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-
-#include "cli.h"
-
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "parser.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-#ifndef CMD_MAX_TOKENS
-#define CMD_MAX_TOKENS 256
-#endif
-
-#define MSG_OUT_OF_MEMORY "Not enough memory.\n"
-#define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
-#define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
-#define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
-#define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
-#define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
-#define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
-#define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
-#define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
-#define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
-#define MSG_CMD_FAIL "Command \"%s\" failed.\n"
-
-static int
-is_comment(char *in)
-{
- if ((strlen(in) && index("!#%;", in[0])) ||
- (strncmp(in, "//", 2) == 0) ||
- (strncmp(in, "--", 2) == 0))
- return 1;
-
- return 0;
-}
-
-static const char cmd_mempool_help[] =
-"mempool <mempool_name>\n"
-" buffer <buffer_size>\n"
-" pool <pool_size>\n"
-" cache <cache_size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_mempool(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct mempool_params p;
- char *name;
- struct mempool *mempool;
-
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "buffer") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
- return;
- }
-
- if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
- return;
- }
-
- if (strcmp(tokens[4], "pool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
- return;
- }
-
- if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
- return;
- }
-
- if (strcmp(tokens[6], "cache") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
- return;
- }
-
- if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
- return;
- }
-
- if (strcmp(tokens[8], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- mempool = mempool_create(name, &p);
- if (mempool == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_link_help[] =
-"link <link_name>\n"
-" dev <device_name> | port <port_id>\n"
-" rxq <n_queues> <queue_size> <mempool_name>\n"
-" txq <n_queues> <queue_size>\n"
-" promiscuous on | off\n"
-" [rss <qid_0> ... <qid_n>]\n";
-
-static void
-cmd_link(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct link_params p;
- struct link_params_rss rss;
- struct link *link;
- char *name;
-
- memset(&p, 0, sizeof(p));
-
- if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- p.dev_name = tokens[3];
- else if (strcmp(tokens[2], "port") == 0) {
- p.dev_name = NULL;
-
- if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
- return;
- }
-
- if (strcmp(tokens[4], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
- if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- p.rx.mempool_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
-
- if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- if (strcmp(tokens[11], "promiscuous") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
- return;
- }
-
- if (strcmp(tokens[12], "on") == 0)
- p.promiscuous = 1;
- else if (strcmp(tokens[12], "off") == 0)
- p.promiscuous = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
- return;
- }
-
- /* RSS */
- p.rx.rss = NULL;
- if (n_tokens > 13) {
- uint32_t queue_id, i;
-
- if (strcmp(tokens[13], "rss") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
- return;
- }
-
- p.rx.rss = &rss;
-
- rss.n_queues = 0;
- for (i = 14; i < n_tokens; i++) {
- if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
-
- rss.queue_id[rss.n_queues] = queue_id;
- rss.n_queues++;
- }
- }
-
- link = link_create(name, &p);
- if (link == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-/* Print the link stats and info */
-static void
-print_link_info(struct link *link, char *out, size_t out_size)
-{
- struct rte_eth_stats stats;
- struct rte_ether_addr mac_addr;
- struct rte_eth_link eth_link;
- uint16_t mtu;
- int ret;
-
- memset(&stats, 0, sizeof(stats));
- rte_eth_stats_get(link->port_id, &stats);
-
- ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
- if (ret != 0) {
- snprintf(out, out_size, "\n%s: MAC address get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- ret = rte_eth_link_get(link->port_id, ð_link);
- if (ret < 0) {
- snprintf(out, out_size, "\n%s: link get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- rte_eth_dev_get_mtu(link->port_id, &mtu);
-
- snprintf(out, out_size,
- "\n"
- "%s: flags=<%s> mtu %u\n"
- "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
- "\tport# %u speed %s\n"
- "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
- "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tTX errors %" PRIu64"\n",
- link->name,
- eth_link.link_status == 0 ? "DOWN" : "UP",
- mtu,
- RTE_ETHER_ADDR_BYTES(&mac_addr),
- link->n_rxq,
- link->n_txq,
- link->port_id,
- rte_eth_link_speed_to_str(eth_link.link_speed),
- stats.ipackets,
- stats.ibytes,
- stats.ierrors,
- stats.imissed,
- stats.rx_nombuf,
- stats.opackets,
- stats.obytes,
- stats.oerrors);
-}
-
-/*
- * link show [<link_name>]
- */
-static void
-cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- struct link *link;
- char *link_name;
-
- if (n_tokens != 2 && n_tokens != 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (n_tokens == 2) {
- link = link_next(NULL);
-
- while (link != NULL) {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- print_link_info(link, out, out_size);
- link = link_next(link);
- }
- } else {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- link_name = tokens[2];
- link = link_find(link_name);
-
- if (link == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "Link does not exist");
- return;
- }
- print_link_info(link, out, out_size);
- }
-}
-
-static const char cmd_swq_help[] =
-"swq <swq_name>\n"
-" size <size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_swq(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct swq_params p;
- char *name;
- struct swq *swq;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "size");
- return;
- }
-
- if (strcmp(tokens[4], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- swq = swq_create(name, &p);
- if (swq == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_profile_help[] =
-"tmgr subport profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n";
-
-static void
-cmd_tmgr_subport_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_subport_profile_params subport_profile;
- int status, i;
-
- if (n_tokens != 19) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&subport_profile.tc_rate[i],
- tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- status = tmgr_subport_profile_add(&subport_profile);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_pipe_profile_help[] =
-"tmgr pipe profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n"
-" <tc_ov_weight>\n"
-" <wrr_weight0..3>\n";
-
-static void
-cmd_tmgr_pipe_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_pipe_params p;
- int status, i;
-
- if (n_tokens != 24) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&p.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&p.tc_rate[i], tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++)
- if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
- return;
- }
-
- status = tmgr_pipe_profile_add(&p);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_help[] =
-"tmgr <tmgr_name>\n"
-" rate <rate>\n"
-" spp <n_subports_per_port>\n"
-" pps <n_pipes_per_subport>\n"
-" fo <frame_overhead>\n"
-" mtu <mtu>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_tmgr(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct tmgr_port_params p;
- char *name;
- struct tmgr_port *tmgr_port;
-
- if (n_tokens != 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "rate") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
- return;
- }
-
- if (parser_read_uint64(&p.rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "rate");
- return;
- }
-
- if (strcmp(tokens[4], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[6], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
- return;
- }
-
- if (strcmp(tokens[8], "fo") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
- return;
- }
-
- if (parser_read_uint32(&p.frame_overhead, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
- return;
- }
-
- if (strcmp(tokens[10], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.mtu, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- if (strcmp(tokens[12], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- tmgr_port = tmgr_port_create(name, &p);
- if (tmgr_port == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_help[] =
-"tmgr <tmgr_name> subport <subport_id>\n"
-" profile <subport_profile_id>\n";
-
-static void
-cmd_tmgr_subport(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, subport_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
- return;
- }
-
- status = tmgr_subport_config(name, subport_id, subport_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tmgr_subport_pipe_help[] =
-"tmgr <tmgr_name> subport <subport_id> pipe\n"
-" from <pipe_id_first> to <pipe_id_last>\n"
-" profile <pipe_profile_id>\n";
-
-static void
-cmd_tmgr_subport_pipe(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (strcmp(tokens[4], "pipe") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
- return;
- }
-
- if (strcmp(tokens[5], "from") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
- return;
- }
-
- if (strcmp(tokens[7], "to") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
- return;
- }
-
- if (strcmp(tokens[9], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
- return;
- }
-
- status = tmgr_pipe_config(name, subport_id, pipe_id_first,
- pipe_id_last, pipe_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tap_help[] =
-"tap <tap_name>\n";
-
-static void
-cmd_tap(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *name;
- struct tap *tap;
-
- if (n_tokens != 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- tap = tap_create(name);
- if (tap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_cryptodev_help[] =
-"cryptodev <cryptodev_name>\n"
-" dev <device_name> | dev_id <device_id>\n"
-" queue <n_queues> <queue_size>\n"
-" max_sessions <n_sessions>";
-
-static void
-cmd_cryptodev(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct cryptodev_params params;
- char *name;
-
- memset(¶ms, 0, sizeof(params));
- if (n_tokens != 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- params.dev_name = tokens[3];
- else if (strcmp(tokens[2], "dev_id") == 0) {
- if (parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "dev_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cryptodev");
- return;
- }
-
- if (strcmp(tokens[4], "queue")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "queue");
- return;
- }
-
- if (parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "q");
- return;
- }
-
- if (parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (strcmp(tokens[7], "max_sessions")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "max_sessions");
- return;
- }
-
- if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (cryptodev_create(name, ¶ms) == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_port_in_action_profile_help[] =
-"port in action profile <profile_name>\n"
-" [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
-" [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
-
-static void
-cmd_port_in_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_action_profile_params p;
- struct port_in_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[2], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[3], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[4];
-
- t0 = 5;
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
- uint32_t size;
-
- if (n_tokens < t0 + 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "match") == 0)
- p.fltr.filter_on_match = 1;
- else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
- p.fltr.filter_on_match = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 6], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
- t0 += 10;
- } /* filter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- uint32_t i;
-
- if (n_tokens < t0 + 22) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "port in action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- for (i = 0; i < 16; i++)
- if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
- t0 += 22;
- } /* balance */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = port_in_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_table_action_profile_help[] =
-"table action profile <profile_name>\n"
-" ipv4 | ipv6\n"
-" offset <ip_offset>\n"
-" fwd\n"
-" [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
-" [meter srtcm | trtcm\n"
-" tc <n_tc>\n"
-" stats none | pkts | bytes | both]\n"
-" [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
-" [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
-" vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
-" [nat src | dst\n"
-" proto udp | tcp]\n"
-" [ttl drop | fwd\n"
-" stats none | pkts]\n"
-" [stats pkts | bytes | both]\n"
-" [time]\n"
-" [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
-" [tag]\n"
-" [decap]\n";
-
-static void
-cmd_table_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_action_profile_params p;
- struct table_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[2], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[3];
-
- if (strcmp(tokens[4], "ipv4") == 0)
- p.common.ip_version = 1;
- else if (strcmp(tokens[4], "ipv6") == 0)
- p.common.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[5], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
- return;
- }
-
- if (strcmp(tokens[7], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
-
- t0 = 8;
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- if (n_tokens < t0 + 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
- t0 += 7;
- } /* balance */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile meter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "srtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
- else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "srtcm or trtcm");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "tc") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
- return;
- }
-
- if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "none") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 5], "both") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
- t0 += 6;
- } /* meter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile tm");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_subports_per_port,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_pipes_per_subport,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_pipes_per_subport");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
- t0 += 5;
- } /* tm */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
- uint32_t n_extra_tokens = 0;
-
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "ether") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
- else if (strcmp(tokens[t0 + 1], "vlan") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
- else if (strcmp(tokens[t0 + 1], "qinq") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
- else if (strcmp(tokens[t0 + 1], "mpls") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
- else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
- else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
- if (n_tokens < t0 + 2 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap vxlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: offset");
- return;
- }
-
- if (parser_read_uint32(&p.encap.vxlan.data_offset,
- tokens[t0 + 2 + 1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ether_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
- p.encap.vxlan.ip_version = 1;
- else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
- p.encap.vxlan.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: vlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
- p.encap.vxlan.vlan = 1;
- else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
- p.encap.vxlan.vlan = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: on or off");
- return;
- }
-
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
- n_extra_tokens = 5;
- } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
- p.encap.encap_mask =
- 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
- t0 += 2 + n_extra_tokens;
- } /* encap */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile nat");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "src") == 0)
- p.nat.source_nat = 1;
- else if (strcmp(tokens[t0 + 1], "dst") == 0)
- p.nat.source_nat = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "src or dst");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "proto") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "tcp") == 0)
- p.nat.proto = 0x06;
- else if (strcmp(tokens[t0 + 3], "udp") == 0)
- p.nat.proto = 0x11;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "tcp or udp");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
- t0 += 4;
- } /* nat */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile ttl");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "drop") == 0)
- p.ttl.drop = 1;
- else if (strcmp(tokens[t0 + 1], "fwd") == 0)
- p.ttl.drop = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "drop or fwd");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "none") == 0)
- p.ttl.n_packets_enabled = 0;
- else if (strcmp(tokens[t0 + 3], "pkts") == 0)
- p.ttl.n_packets_enabled = 1;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
- t0 += 4;
- } /* ttl */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "pkts") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
- p.stats.n_packets_enabled = 0;
- p.stats.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 1], "both") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
- t0 += 2;
- } /* stats */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
- t0 += 1;
- } /* time */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
- struct cryptodev *cryptodev;
-
- if (n_tokens < t0 + 5 ||
- strcmp(tokens[t0 + 1], "dev") ||
- strcmp(tokens[t0 + 3], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile sym_crypto");
- return;
- }
-
- cryptodev = cryptodev_find(tokens[t0 + 2]);
- if (cryptodev == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.cryptodev_id = cryptodev->dev_id;
-
- if (parser_read_uint32(&p.sym_crypto.op_offset,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.mp_create = cryptodev->mp_create;
- p.sym_crypto.mp_init = cryptodev->mp_init;
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- t0 += 5;
- } /* sym_crypto */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
- t0 += 1;
- } /* tag */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "decap") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
- t0 += 1;
- } /* decap */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = table_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_help[] =
-"pipeline <pipeline_name>\n"
-" period <timer_period_ms>\n"
-" offset_port_id <offset_port_id>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_pipeline(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct pipeline_params p;
- char *name;
- struct pipeline *pipeline;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "period") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
- return;
- }
-
- if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
- return;
- }
-
- if (strcmp(tokens[4], "offset_port_id") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
- return;
- }
-
- if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
- return;
- }
-
- if (strcmp(tokens[6], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- pipeline = pipeline_create(name, &p);
- if (pipeline == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_help[] =
-"pipeline <pipeline_name> port in\n"
-" bsz <burst_size>\n"
-" link <link_name> rxq <queue_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
-" | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
-" | cryptodev <cryptodev_name> rxq <queue_id>\n"
-" [action <port_in_action_profile_name>]\n"
-" [disabled]\n";
-
-static void
-cmd_pipeline_port_in(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_params p;
- char *pipeline_name;
- uint32_t t0;
- int enabled, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- t0 = 6;
-
- if (strcmp(tokens[t0], "link") == 0) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in link");
- return;
- }
-
- p.type = PORT_IN_RXQ;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
- t0 += 4;
- } else if (strcmp(tokens[t0], "swq") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in swq");
- return;
- }
-
- p.type = PORT_IN_SWQ;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tmgr") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tmgr");
- return;
- }
-
- p.type = PORT_IN_TMGR;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tap") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tap");
- return;
- }
-
- p.type = PORT_IN_TAP;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.tap.mempool_name = tokens[t0 + 3];
-
- if (strcmp(tokens[t0 + 4], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "source") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in source");
- return;
- }
-
- p.type = PORT_IN_SOURCE;
-
- p.dev_name = NULL;
-
- if (strcmp(tokens[t0 + 1], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.source.mempool_name = tokens[t0 + 2];
-
- if (strcmp(tokens[t0 + 3], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.source.file_name = tokens[t0 + 4];
-
- if (strcmp(tokens[t0 + 5], "bpp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "bpp");
- return;
- }
-
- if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_bytes_per_pkt");
- return;
- }
-
- t0 += 7;
- } else if (strcmp(tokens[t0], "cryptodev") == 0) {
- if (n_tokens < t0 + 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in cryptodev");
- return;
- }
-
- p.type = PORT_IN_CRYPTODEV;
-
- p.dev_name = tokens[t0 + 1];
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "rxq");
- return;
- }
-
- p.cryptodev.arg_callback = NULL;
- p.cryptodev.f_callback = NULL;
-
- t0 += 4;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- enabled = 1;
- if ((n_tokens > t0) &&
- (strcmp(tokens[t0], "disabled") == 0)) {
- enabled = 0;
-
- t0 += 1;
- }
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_port_in_create(pipeline_name,
- &p, enabled);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_out_help[] =
-"pipeline <pipeline_name> port out\n"
-" bsz <burst_size>\n"
-" link <link_name> txq <txq_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name>\n"
-" | sink [file <file_name> pkts <max_n_pkts>]\n"
-" | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
-
-static void
-cmd_pipeline_port_out(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_out_params p;
- char *pipeline_name;
- int status;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- if (strcmp(tokens[6], "link") == 0) {
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out link");
- return;
- }
-
- p.type = PORT_OUT_TXQ;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else if (strcmp(tokens[6], "swq") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out swq");
- return;
- }
-
- p.type = PORT_OUT_SWQ;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tmgr") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tmgr");
- return;
- }
-
- p.type = PORT_OUT_TMGR;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tap") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tap");
- return;
- }
-
- p.type = PORT_OUT_TAP;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "sink") == 0) {
- if ((n_tokens != 7) && (n_tokens != 11)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out sink");
- return;
- }
-
- p.type = PORT_OUT_SINK;
-
- p.dev_name = NULL;
-
- if (n_tokens == 7) {
- p.sink.file_name = NULL;
- p.sink.max_n_pkts = 0;
- } else {
- if (strcmp(tokens[7], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.sink.file_name = tokens[8];
-
- if (strcmp(tokens[9], "pkts") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
- return;
- }
-
- if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
- return;
- }
- }
-
- } else if (strcmp(tokens[6], "cryptodev") == 0) {
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- p.type = PORT_OUT_CRYPTODEV;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
-
- if (strcmp(tokens[10], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_port_out_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_help[] =
-"pipeline <pipeline_name> table\n"
-" match\n"
-" acl\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | array\n"
-" offset <key_offset>\n"
-" size <n_keys>\n"
-" | hash\n"
-" ext | lru\n"
-" key <key_size>\n"
-" mask <key_mask>\n"
-" offset <key_offset>\n"
-" buckets <n_buckets>\n"
-" size <n_keys>\n"
-" | lpm\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | stub\n"
-" [action <table_action_profile_name>]\n";
-
-static void
-cmd_pipeline_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
- struct table_params p;
- char *pipeline_name;
- uint32_t t0;
- int status;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (strcmp(tokens[3], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- t0 = 4;
- if (strcmp(tokens[t0], "acl") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table acl");
- return;
- }
-
- p.match_type = TABLE_ACL;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.acl.ip_version = 1;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.acl.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.ip_header_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "ip_header_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "array") == 0) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table array");
- return;
- }
-
- p.match_type = TABLE_ARRAY;
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.key_offset,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.n_keys,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 5;
- } else if (strcmp(tokens[t0], "hash") == 0) {
- uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < t0 + 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table hash");
- return;
- }
-
- p.match_type = TABLE_HASH;
-
- if (strcmp(tokens[t0 + 1], "ext") == 0)
- p.match.hash.extendable_bucket = 1;
- else if (strcmp(tokens[t0 + 1], "lru") == 0)
- p.match.hash.extendable_bucket = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ext or lru");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- if ((parser_read_uint32(&p.match.hash.key_size,
- tokens[t0 + 3]) != 0) ||
- (p.match.hash.key_size == 0) ||
- (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- if ((parse_hex_string(tokens[t0 + 5],
- key_mask, &key_mask_size) != 0) ||
- (key_mask_size != p.match.hash.key_size)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
- p.match.hash.key_mask = key_mask;
-
- if (strcmp(tokens[t0 + 6], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.key_offset,
- tokens[t0 + 7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "buckets") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_buckets,
- tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
- return;
- }
-
- if (strcmp(tokens[t0 + 10], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_keys,
- tokens[t0 + 11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 12;
- } else if (strcmp(tokens[t0], "lpm") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table lpm");
- return;
- }
-
- p.match_type = TABLE_LPM;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.lpm.key_size = 4;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.lpm.key_size = 16;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.key_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "stub") == 0) {
- p.match_type = TABLE_STUB;
-
- t0 += 1;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- if (n_tokens > t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_table_help[] =
-"pipeline <pipeline_name> port in <port_id> table <table_id>\n";
-
-static void
-cmd_pipeline_port_in_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id, table_id;
- int status;
-
- if (n_tokens != 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- status = pipeline_port_in_connect_to_table(pipeline_name,
- port_id,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_stats_help[] =
-"pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_IN_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_in_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_in_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_in_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_port_in_enable_help[] =
-"pipeline <pipeline_name> port in <port_id> enable\n";
-
-static void
-cmd_pipeline_port_in_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = pipeline_port_in_enable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_disable_help[] =
-"pipeline <pipeline_name> port in <port_id> disable\n";
-
-static void
-cmd_pipeline_port_in_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = pipeline_port_in_disable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_out_stats_help[] =
-"pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_OUT_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_out_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_out_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_out_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_table_stats_help[] =
-"pipeline <pipeline_name> table <table_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_TABLE_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts in with lookup miss: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_table_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_table_stats stats;
- char *pipeline_name;
- uint32_t table_id;
- int clear, status;
-
- if ((n_tokens != 6) && (n_tokens != 7)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 7) {
- if (strcmp(tokens[6], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_table_stats_read(pipeline_name,
- table_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
- stats.stats.n_pkts_in,
- stats.stats.n_pkts_lookup_miss,
- stats.n_pkts_dropped_by_lkp_hit_ah,
- stats.n_pkts_dropped_lkp_hit,
- stats.n_pkts_dropped_by_lkp_miss_ah,
- stats.n_pkts_dropped_lkp_miss);
-}
-
-/**
- * <match> ::=
- *
- * match
- * acl
- * priority <priority>
- * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- * <sp0> <sp1> <dp0> <dp1> <proto>
- * | array <pos>
- * | hash
- * raw <key>
- * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv4_addr <addr>
- * | ipv6_addr <addr>
- * | qinq <svlan> <cvlan>
- * | lpm
- * ipv4 | ipv6 <addr> <depth>
- */
-struct pkt_key_qinq {
- uint16_t ethertype_svlan;
- uint16_t svlan;
- uint16_t ethertype_cvlan;
- uint16_t cvlan;
-};
-
-struct pkt_key_ipv4_5tuple {
- uint8_t time_to_live;
- uint8_t proto;
- uint16_t hdr_checksum;
- uint32_t sa;
- uint32_t da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv6_5tuple {
- uint16_t payload_length;
- uint8_t proto;
- uint8_t hop_limit;
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv4_addr {
- uint32_t addr;
-};
-
-struct pkt_key_ipv6_addr {
- struct rte_ipv6_addr addr;
-};
-
-static uint32_t
-parse_match(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_match *m)
-{
- memset(m, 0, sizeof(*m));
-
- if (n_tokens < 2)
- return 0;
-
- if (strcmp(tokens[0], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return 0;
- }
-
- if (strcmp(tokens[1], "acl") == 0) {
- if (n_tokens < 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ACL;
-
- if (strcmp(tokens[2], "priority") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.priority,
- tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "priority");
- return 0;
- }
-
- if (strcmp(tokens[4], "ipv4") == 0) {
- struct in_addr saddr, daddr;
-
- m->match.acl.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
-
- if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
- } else if (strcmp(tokens[4], "ipv6") == 0) {
- struct rte_ipv6_addr saddr, daddr;
-
- m->match.acl.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv6.sa = saddr;
-
- if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv6.da = daddr;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.sa_depth,
- tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.da_depth,
- tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "proto");
- return 0;
- }
-
- m->match.acl.proto_mask = 0xff;
-
- return 14;
- } /* acl */
-
- if (strcmp(tokens[1], "array") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ARRAY;
-
- if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pos");
- return 0;
- }
-
- return 3;
- } /* array */
-
- if (strcmp(tokens[1], "hash") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_HASH;
-
- if (strcmp(tokens[2], "raw") == 0) {
- uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_hex_string(tokens[3],
- m->match.hash.key, &key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key");
- return 0;
- }
-
- return 4;
- } /* hash raw */
-
- if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
- struct pkt_key_ipv4_5tuple *ipv4 =
- (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
- struct in_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv4->sa = saddr.s_addr;
- ipv4->da = daddr.s_addr;
- ipv4->sp = rte_cpu_to_be_16(sp);
- ipv4->dp = rte_cpu_to_be_16(dp);
- ipv4->proto = proto;
-
- return 8;
- } /* hash ipv4_5tuple */
-
- if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
- struct pkt_key_ipv6_5tuple *ipv6 =
- (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
- struct rte_ipv6_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv6->sa = saddr;
- ipv6->da = daddr;
- ipv6->sp = rte_cpu_to_be_16(sp);
- ipv6->dp = rte_cpu_to_be_16(dp);
- ipv6->proto = proto;
-
- return 8;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "ipv4_addr") == 0) {
- struct pkt_key_ipv4_addr *ipv4_addr =
- (struct pkt_key_ipv4_addr *) m->match.hash.key;
- struct in_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv4_addr->addr = addr.s_addr;
-
- return 4;
- } /* hash ipv4_addr */
-
- if (strcmp(tokens[2], "ipv6_addr") == 0) {
- struct pkt_key_ipv6_addr *ipv6_addr =
- (struct pkt_key_ipv6_addr *) m->match.hash.key;
- struct rte_ipv6_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv6_addr->addr = addr;
-
- return 4;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "qinq") == 0) {
- struct pkt_key_qinq *qinq =
- (struct pkt_key_qinq *) m->match.hash.key;
- uint16_t svlan, cvlan;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
- (svlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "svlan");
- return 0;
- }
-
- if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
- (cvlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cvlan");
- return 0;
- }
-
- qinq->svlan = rte_cpu_to_be_16(svlan);
- qinq->cvlan = rte_cpu_to_be_16(cvlan);
-
- return 5;
- } /* hash qinq */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- } /* hash */
-
- if (strcmp(tokens[1], "lpm") == 0) {
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_LPM;
-
- if (strcmp(tokens[2], "ipv4") == 0) {
- struct in_addr addr;
-
- m->match.lpm.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- } else if (strcmp(tokens[2], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
-
- m->match.lpm.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv6 = addr;
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "depth");
- return 0;
- }
-
- return 5;
- } /* lpm */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "acl or array or hash or lpm");
- return 0;
-}
-
-/**
- * table_action ::=
- *
- * action
- * fwd
- * drop
- * | port <port_id>
- * | meta
- * | table <table_id>
- * [balance <out0> ... <out7>]
- * [meter
- * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- * [tm subport <subport_id> pipe <pipe_id>]
- * [encap
- * ether <da> <sa>
- * | vlan <da> <sa> <pcp> <dei> <vid>
- * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
- * | mpls unicast | multicast
- * <da> <sa>
- * label0 <label> <tc> <ttl>
- * [label1 <label> <tc> <ttl>
- * [label2 <label> <tc> <ttl>
- * [label3 <label> <tc> <ttl>]]]
- * | pppoe <da> <sa> <session_id>
- * | vxlan ether <da> <sa>
- * [vlan <pcp> <dei> <vid>]
- * ipv4 <sa> <da> <dscp> <ttl>
- * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
- * udp <sp> <dp>
- * vxlan <vni>]
- * [nat ipv4 | ipv6 <addr> <port>]
- * [ttl dec | keep]
- * [stats]
- * [time]
- * [sym_crypto
- * encrypt | decrypt
- * type
- * | cipher
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * | cipher_auth
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * auth_algo <algo> auth_key <key> digest_size <size>
- * | aead
- * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- * digest_size <size>
- * data_offset <data_offset>]
- * [tag <tag>]
- * [decap <n>]
- *
- * where:
- * <pa> ::= g | y | r | drop
- */
-static uint32_t
-parse_table_action_fwd(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_DROP;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_PORT;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_balance(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t i;
-
- if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
- return 0;
-
- for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
- if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
- return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
-
-}
-
-static int
-parse_policer_action(char *token, enum rte_table_action_policer *a)
-{
- if (strcmp(token, "g") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
- return 0;
- }
-
- if (strcmp(token, "y") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
- return 0;
- }
-
- if (strcmp(token, "r") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
- return 0;
- }
-
- if (strcmp(token, "drop") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_DROP;
- return 0;
- }
-
- return -1;
-}
-
-static uint32_t
-parse_table_action_meter_tc(char **tokens,
- uint32_t n_tokens,
- struct rte_table_action_mtr_tc_params *mtr)
-{
- if ((n_tokens < 9) ||
- strcmp(tokens[0], "meter") ||
- parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
- strcmp(tokens[2], "policer") ||
- strcmp(tokens[3], "g") ||
- parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
- strcmp(tokens[5], "y") ||
- parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
- strcmp(tokens[7], "r") ||
- parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
- return 0;
-
- return 9;
-}
-
-static uint32_t
-parse_table_action_meter(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if ((n_tokens < 10) ||
- strcmp(tokens[0], "tc0") ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1,
- &a->mtr.mtr[0]) == 0))
- return 0;
-
- tokens += 10;
- n_tokens -= 10;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
- a->mtr.tc_mask = 1;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10;
- }
-
- if ((n_tokens < 30) ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
- strcmp(tokens[10], "tc2") ||
- (parse_table_action_meter_tc(tokens + 11,
- n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
- strcmp(tokens[20], "tc3") ||
- (parse_table_action_meter_tc(tokens + 21,
- n_tokens - 21, &a->mtr.mtr[3]) == 0))
- return 0;
-
- a->mtr.tc_mask = 0xF;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10 + 3 * 10;
-}
-
-static uint32_t
-parse_table_action_tm(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t subport_id, pipe_id;
-
- if ((n_tokens < 5) ||
- strcmp(tokens[0], "tm") ||
- strcmp(tokens[1], "subport") ||
- parser_read_uint32(&subport_id, tokens[2]) ||
- strcmp(tokens[3], "pipe") ||
- parser_read_uint32(&pipe_id, tokens[4]))
- return 0;
-
- a->tm.subport_id = subport_id;
- a->tm.pipe_id = pipe_id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
- return 5;
-}
-
-static uint32_t
-parse_table_action_encap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- /* ether */
- if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
- if ((n_tokens < 3) ||
- parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 3;
- }
-
- /* vlan */
- if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 6) ||
- parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
- parser_read_uint32(&pcp, tokens[3]) ||
- (pcp > 0x7) ||
- parser_read_uint32(&dei, tokens[4]) ||
- (dei > 0x1) ||
- parser_read_uint32(&vid, tokens[5]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vlan.vlan.pcp = pcp & 0x7;
- a->encap.vlan.vlan.dei = dei & 0x1;
- a->encap.vlan.vlan.vid = vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 6;
- }
-
- /* qinq */
- if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 9) ||
- parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF))
- return 0;
-
- a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 9;
- }
-
- /* qinq_pppoe */
- if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 10) ||
- parse_mac_addr(tokens[1],
- &a->encap.qinq_pppoe.ether.da) ||
- parse_mac_addr(tokens[2],
- &a->encap.qinq_pppoe.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF) ||
- parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
- tokens[9]))
- return 0;
-
- a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 10;
-
- }
-
- /* mpls */
- if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
- uint32_t label, tc, ttl;
-
- if (n_tokens < 8)
- return 0;
-
- if (strcmp(tokens[1], "unicast") == 0)
- a->encap.mpls.unicast = 1;
- else if (strcmp(tokens[1], "multicast") == 0)
- a->encap.mpls.unicast = 0;
- else
- return 0;
-
- if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
- parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
- strcmp(tokens[4], "label0") ||
- parser_read_uint32(&label, tokens[5]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[6]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[7]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[0].label = label;
- a->encap.mpls.mpls[0].tc = tc;
- a->encap.mpls.mpls[0].ttl = ttl;
-
- tokens += 8;
- n_tokens -= 8;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
- a->encap.mpls.mpls_count = 1;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[1].label = label;
- a->encap.mpls.mpls[1].tc = tc;
- a->encap.mpls.mpls[1].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
- a->encap.mpls.mpls_count = 2;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[2].label = label;
- a->encap.mpls.mpls[2].tc = tc;
- a->encap.mpls.mpls[2].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
- a->encap.mpls.mpls_count = 3;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[3].label = label;
- a->encap.mpls.mpls[3].tc = tc;
- a->encap.mpls.mpls[3].ttl = ttl;
-
- a->encap.mpls.mpls_count = 4;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4 + 4;
- }
-
- /* pppoe */
- if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
- if ((n_tokens < 4) ||
- parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
- parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
- tokens[3]))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 4;
- }
-
- /* vxlan */
- if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
- uint32_t n = 0;
-
- n_tokens--;
- tokens++;
- n++;
-
- /* ether <da> <sa> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "ether") ||
- parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* [vlan <pcp> <dei> <vid>] */
- if (strcmp(tokens[0], "vlan") == 0) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&pcp, tokens[1]) ||
- (pcp > 7) ||
- parser_read_uint32(&dei, tokens[2]) ||
- (dei > 1) ||
- parser_read_uint32(&vid, tokens[3]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vxlan.vlan.pcp = pcp;
- a->encap.vxlan.vlan.dei = dei;
- a->encap.vxlan.vlan.vid = vid;
-
- n_tokens -= 4;
- tokens += 4;
- n += 4;
- }
-
- /* ipv4 <sa> <da> <dscp> <ttl>
- | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
- if (strcmp(tokens[0], "ipv4") == 0) {
- struct in_addr sa, da;
- uint8_t dscp, ttl;
-
- if ((n_tokens < 5) ||
- parse_ipv4_addr(tokens[1], &sa) ||
- parse_ipv4_addr(tokens[2], &da) ||
- parser_read_uint8(&dscp, tokens[3]) ||
- (dscp > 64) ||
- parser_read_uint8(&ttl, tokens[4]))
- return 0;
-
- a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
- a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
- a->encap.vxlan.ipv4.dscp = dscp;
- a->encap.vxlan.ipv4.ttl = ttl;
-
- n_tokens -= 5;
- tokens += 5;
- n += 5;
- } else if (strcmp(tokens[0], "ipv6") == 0) {
- struct rte_ipv6_addr sa, da;
- uint32_t flow_label;
- uint8_t dscp, hop_limit;
-
- if ((n_tokens < 6) ||
- parse_ipv6_addr(tokens[1], &sa) ||
- parse_ipv6_addr(tokens[2], &da) ||
- parser_read_uint32(&flow_label, tokens[3]) ||
- parser_read_uint8(&dscp, tokens[4]) ||
- (dscp > 64) ||
- parser_read_uint8(&hop_limit, tokens[5]))
- return 0;
-
- a->encap.vxlan.ipv6.sa = sa;
- a->encap.vxlan.ipv6.da = da;
- a->encap.vxlan.ipv6.flow_label = flow_label;
- a->encap.vxlan.ipv6.dscp = dscp;
- a->encap.vxlan.ipv6.hop_limit = hop_limit;
-
- n_tokens -= 6;
- tokens += 6;
- n += 6;
- } else
- return 0;
-
- /* udp <sp> <dp> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "udp") ||
- parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
- parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* vxlan <vni> */
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "vxlan") ||
- parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
- (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
- return 0;
-
- n_tokens -= 2;
- tokens += 2;
- n += 2;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + n;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_nat(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 4) ||
- strcmp(tokens[0], "nat"))
- return 0;
-
- if (strcmp(tokens[1], "ipv4") == 0) {
- struct in_addr addr;
- uint16_t port;
-
- if (parse_ipv4_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 1;
- a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- if (strcmp(tokens[1], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
- uint16_t port;
-
- if (parse_ipv6_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 0;
- a->nat.addr.ipv6 = addr;
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_ttl(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "ttl"))
- return 0;
-
- if (strcmp(tokens[1], "dec") == 0)
- a->ttl.decrement = 1;
- else if (strcmp(tokens[1], "keep") == 0)
- a->ttl.decrement = 0;
- else
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
- return 2;
-}
-
-static uint32_t
-parse_table_action_stats(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "stats"))
- return 0;
-
- a->stats.n_packets = 0;
- a->stats.n_bytes = 0;
- a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
- return 1;
-}
-
-static uint32_t
-parse_table_action_time(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "time"))
- return 0;
-
- a->time.time = rte_rdtsc();
- a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
- return 1;
-}
-
-static void
-parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
-{
- struct rte_crypto_sym_xform *xform[2] = {NULL};
- uint32_t i;
-
- xform[0] = p->xform;
- if (xform[0])
- xform[1] = xform[0]->next;
-
- for (i = 0; i < 2; i++) {
- if (xform[i] == NULL)
- continue;
-
- switch (xform[i]->type) {
- case RTE_CRYPTO_SYM_XFORM_CIPHER:
- free(p->cipher_auth.cipher_iv.val);
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AUTH:
- if (p->cipher_auth.auth_iv.val)
- free(p->cipher_auth.cipher_iv.val);
- if (p->cipher_auth.auth_iv_update.val)
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AEAD:
- free(p->aead.iv.val);
- free(p->aead.aad.val);
- break;
- default:
- continue;
- }
- }
-
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- int status;
- size_t len;
-
- if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
- strcmp(tokens[3], "cipher_key") ||
- strcmp(tokens[5], "cipher_iv"))
- return NULL;
-
- xform_cipher = calloc(1, sizeof(*xform_cipher));
- if (xform_cipher == NULL)
- return NULL;
-
- xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
- xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- /* cipher_algo */
- status = rte_cryptodev_get_cipher_algo_enum(
- &xform_cipher->cipher.algo, tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* cipher_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.key.data = key;
- xform_cipher->cipher.key.length = (uint16_t)len;
-
- /* cipher_iv */
- len = strlen(tokens[6]);
-
- p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
- if (p->cipher_auth.cipher_iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6],
- p->cipher_auth.cipher_iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.iv.length = (uint16_t)len;
- xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->cipher_auth.cipher_iv.length = (uint32_t)len;
- *used_n_tokens = 7;
-
- return xform_cipher;
-
-error_exit:
- if (p->cipher_auth.cipher_iv.val) {
- free(p->cipher_auth.cipher_iv.val);
- p->cipher_auth.cipher_iv.val = NULL;
- }
-
- free(xform_cipher);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- struct rte_crypto_sym_xform *xform_auth;
- int status;
- size_t len;
-
- if (n_tokens < 13 ||
- strcmp(tokens[7], "auth_algo") ||
- strcmp(tokens[9], "auth_key") ||
- strcmp(tokens[11], "digest_size"))
- return NULL;
-
- xform_auth = calloc(1, sizeof(*xform_auth));
- if (xform_auth == NULL)
- return NULL;
-
- xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
- xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
- RTE_CRYPTO_AUTH_OP_VERIFY;
-
- /* auth_algo */
- status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
- tokens[8]);
- if (status < 0)
- goto error_exit;
-
- /* auth_key */
- len = strlen(tokens[10]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_auth->auth.key.data = key;
- xform_auth->auth.key.length = (uint16_t)len;
-
- key += xform_auth->auth.key.length;
- max_key_len -= xform_auth->auth.key.length;
-
- if (strcmp(tokens[11], "digest_size"))
- goto error_exit;
-
- status = parser_read_uint16(&xform_auth->auth.digest_length,
- tokens[12]);
- if (status < 0)
- goto error_exit;
-
- xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
- 7, encrypt, used_n_tokens);
- if (xform_cipher == NULL)
- goto error_exit;
-
- *used_n_tokens += 6;
-
- if (encrypt) {
- xform_cipher->next = xform_auth;
- return xform_cipher;
- } else {
- xform_auth->next = xform_cipher;
- return xform_auth;
- }
-
-error_exit:
- if (p->cipher_auth.auth_iv.val) {
- free(p->cipher_auth.auth_iv.val);
- p->cipher_auth.auth_iv.val = 0;
- }
-
- free(xform_auth);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_aead;
- int status;
- size_t len;
-
- if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
- strcmp(tokens[3], "aead_key") ||
- strcmp(tokens[5], "aead_iv") ||
- strcmp(tokens[7], "aead_aad") ||
- strcmp(tokens[9], "digest_size"))
- return NULL;
-
- xform_aead = calloc(1, sizeof(*xform_aead));
- if (xform_aead == NULL)
- return NULL;
-
- xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
- xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
- RTE_CRYPTO_AEAD_OP_DECRYPT;
-
- /* aead_algo */
- status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
- tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* aead_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.key.data = key;
- xform_aead->aead.key.length = (uint16_t)len;
-
- /* aead_iv */
- len = strlen(tokens[6]);
- p->aead.iv.val = calloc(1, len / 2 + 1);
- if (p->aead.iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6], p->aead.iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.iv.length = (uint16_t)len;
- xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->aead.iv.length = (uint32_t)len;
-
- /* aead_aad */
- len = strlen(tokens[8]);
- p->aead.aad.val = calloc(1, len / 2 + 1);
- if (p->aead.aad.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.aad_length = (uint16_t)len;
- p->aead.aad.length = (uint32_t)len;
-
- /* digest_size */
- status = parser_read_uint16(&xform_aead->aead.digest_length,
- tokens[10]);
- if (status < 0)
- goto error_exit;
-
- *used_n_tokens = 11;
-
- return xform_aead;
-
-error_exit:
- if (p->aead.iv.val) {
- free(p->aead.iv.val);
- p->aead.iv.val = NULL;
- }
- if (p->aead.aad.val) {
- free(p->aead.aad.val);
- p->aead.aad.val = NULL;
- }
-
- free(xform_aead);
-
- return NULL;
-}
-
-
-static uint32_t
-parse_table_action_sym_crypto(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
- struct rte_crypto_sym_xform *xform = NULL;
- uint8_t *key = a->sym_crypto_key;
- uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
- uint32_t used_n_tokens;
- uint32_t encrypt;
- int status;
-
- if ((n_tokens < 12) ||
- strcmp(tokens[0], "sym_crypto") ||
- strcmp(tokens[2], "type"))
- return 0;
-
- memset(p, 0, sizeof(*p));
-
- if (strcmp(tokens[1], "encrypt") == 0)
- encrypt = 1;
- else
- encrypt = 0;
-
- status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
- if (status < 0)
- return 0;
-
- if (strcmp(tokens[3], "cipher") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "cipher_auth") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher_auth(p, key, max_key_len,
- tokens, n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "aead") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_aead(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- }
-
- if (xform == NULL)
- return 0;
-
- p->xform = xform;
-
- if (strcmp(tokens[used_n_tokens], "data_offset")) {
- parse_free_sym_crypto_param_data(p);
- return 0;
- }
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- return used_n_tokens + 5;
-}
-
-static uint32_t
-parse_table_action_tag(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "tag"))
- return 0;
-
- if (parser_read_uint32(&a->tag.tag, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
- return 2;
-}
-
-static uint32_t
-parse_table_action_decap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "decap"))
- return 0;
-
- if (parser_read_uint16(&a->decap.n, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
- return 2;
-}
-
-static uint32_t
-parse_table_action(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_action *a)
-{
- uint32_t n_tokens0 = n_tokens;
-
- memset(a, 0, sizeof(*a));
-
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "action"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
- uint32_t n;
-
- n = parse_table_action_fwd(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action fwd");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
- uint32_t n;
-
- n = parse_table_action_balance(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action balance");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
- uint32_t n;
-
- n = parse_table_action_meter(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action meter");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tm(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tm");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_encap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action encap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
- uint32_t n;
-
- n = parse_table_action_nat(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action nat");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
- uint32_t n;
-
- n = parse_table_action_ttl(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action ttl");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
- uint32_t n;
-
- n = parse_table_action_stats(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action stats");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
- uint32_t n;
-
- n = parse_table_action_time(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action time");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
- uint32_t n;
-
- n = parse_table_action_sym_crypto(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action sym_crypto");
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tag(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tag");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_decap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action decap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens0 - n_tokens == 1) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return 0;
- }
-
- return n_tokens0 - n_tokens;
-}
-
-
-static const char cmd_pipeline_table_rule_add_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match <match>\n"
-" action <table_action>\n";
-
-static void
-cmd_pipeline_table_rule_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct table_rule_action a;
- char *pipeline_name;
- uint32_t table_id, t0, n_tokens_parsed;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- /* action */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &a);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (t0 != n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
- parse_free_sym_crypto_param_data(&a.sym_crypto);
-}
-
-
-static const char cmd_pipeline_table_rule_add_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match\n"
-" default\n"
-" action\n"
-" fwd\n"
-" drop\n"
-" | port <port_id>\n"
-" | meta\n"
-" | table <table_id>\n";
-
-static void
-cmd_pipeline_table_rule_add_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_action action;
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if ((n_tokens != 11) && (n_tokens != 12)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- if (strcmp(tokens[8], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return;
- }
-
- if (strcmp(tokens[9], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
- return;
- }
-
- action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
-
- if (strcmp(tokens[10], "drop") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_DROP;
- } else if (strcmp(tokens[10], "port") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT;
- action.fwd.id = id;
- } else if (strcmp(tokens[10], "meta") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- } else if (strcmp(tokens[10], "table") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
- action.fwd.id = id;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "drop or port or meta or table");
- return;
- }
-
- status = pipeline_table_rule_add_default(pipeline_name,
- table_id,
- &action);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_add_bulk_help[] =
-"pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - line format: match <match> action <action>\n";
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size);
-
-static void
-cmd_pipeline_table_rule_add_bulk(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *pipeline_name, *file_name;
- uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "bulk") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
- return;
- }
-
- file_name = tokens[7];
-
- /* Load rules from file. */
- status = cli_rule_file_process(file_name,
- 1024,
- &list,
- &n_rules,
- &line_number,
- out,
- out_size);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- /* Rule bulk add */
- status = pipeline_table_rule_add_bulk(pipeline_name,
- table_id,
- list,
- &n_rules_added,
- &n_rules_not_added);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, "Added %u rules out of %u.\n",
- n_rules_added,
- n_rules);
-}
-
-
-static const char cmd_pipeline_table_rule_delete_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed, t0;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_delete(pipeline_name,
- table_id,
- &m);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_delete_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match\n"
-" default\n";
-
-static void
-cmd_pipeline_table_rule_delete_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- status = pipeline_table_rule_delete_default(pipeline_name,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static void
-ether_addr_show(FILE *f, struct rte_ether_addr *addr)
-{
- fprintf(f, RTE_ETHER_ADDR_PRT_FMT, RTE_ETHER_ADDR_BYTES(addr));
-}
-
-static void
-ipv4_addr_show(FILE *f, uint32_t addr)
-{
- fprintf(f, "%u.%u.%u.%u",
- addr >> 24,
- (addr >> 16) & 0xFF,
- (addr >> 8) & 0xFF,
- addr & 0xFF);
-}
-
-static void
-ipv6_addr_show(FILE *f, const struct rte_ipv6_addr *ip)
-{
- fprintf(f, RTE_IPV6_ADDR_FMT ":", RTE_IPV6_ADDR_SPLIT(ip));
-}
-
-static const char *
-policer_action_string(enum rte_table_action_policer action) {
- switch (action) {
- case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
- case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
- case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
- case RTE_TABLE_ACTION_POLICER_DROP: return "D";
- default: return "?";
- }
-}
-
-static int
-table_rule_show(const char *pipeline_name,
- uint32_t table_id,
- const char *file_name)
-{
- struct pipeline *pipeline;
- struct table *table;
- struct table_rule *rule;
- FILE *f = NULL;
- uint32_t i;
-
- /* Check input params. */
- if ((pipeline_name == NULL) ||
- (file_name == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL || table_id >= pipeline->n_tables)
- return -1;
-
- table = &pipeline->table[table_id];
-
- /* Open file. */
- f = fopen(file_name, "w");
- if (f == NULL)
- return -1;
-
- /* Write table rules to file. */
- TAILQ_FOREACH(rule, &table->rules, node) {
- struct table_rule_match *m = &rule->match;
- struct table_rule_action *a = &rule->action;
-
- fprintf(f, "match ");
- switch (m->match_type) {
- case TABLE_ACL:
- fprintf(f, "acl priority %u ",
- m->match.acl.priority);
-
- fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.sa);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.sa);
-
- fprintf(f, "%u", m->match.acl.sa_depth);
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.da);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.da);
-
- fprintf(f, "%u", m->match.acl.da_depth);
-
- fprintf(f, "%u %u %u %u %u ",
- (uint32_t)m->match.acl.sp0,
- (uint32_t)m->match.acl.sp1,
- (uint32_t)m->match.acl.dp0,
- (uint32_t)m->match.acl.dp1,
- (uint32_t)m->match.acl.proto);
- break;
-
- case TABLE_ARRAY:
- fprintf(f, "array %u ",
- m->match.array.pos);
- break;
-
- case TABLE_HASH:
- fprintf(f, "hash raw ");
- for (i = 0; i < table->params.match.hash.key_size; i++)
- fprintf(f, "%02x", m->match.hash.key[i]);
- fprintf(f, " ");
- break;
-
- case TABLE_LPM:
- fprintf(f, "lpm ");
-
- fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.lpm.ipv4);
- else
- ipv6_addr_show(f, &m->match.lpm.ipv6);
-
- fprintf(f, "%u ",
- (uint32_t)m->match.lpm.depth);
- break;
-
- default:
- fprintf(f, "unknown ");
- }
-
- fprintf(f, "action ");
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- fprintf(f, "fwd ");
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- fprintf(f, "balance ");
- for (i = 0; i < RTE_DIM(a->lb.out); i++)
- fprintf(f, "%u ", a->lb.out[i]);
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- fprintf(f, "mtr ");
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
- if (a->mtr.tc_mask & (1 << i)) {
- struct rte_table_action_mtr_tc_params *p =
- &a->mtr.mtr[i];
- enum rte_table_action_policer ga =
- p->policer[RTE_COLOR_GREEN];
- enum rte_table_action_policer ya =
- p->policer[RTE_COLOR_YELLOW];
- enum rte_table_action_policer ra =
- p->policer[RTE_COLOR_RED];
-
- fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
- i,
- a->mtr.mtr[i].meter_profile_id,
- policer_action_string(ga),
- policer_action_string(ya),
- policer_action_string(ra));
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
- fprintf(f, "tm subport %u pipe %u ",
- a->tm.subport_id,
- a->tm.pipe_id);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- fprintf(f, "encap ");
- switch (a->encap.type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- fprintf(f, "ether ");
- ether_addr_show(f, &a->encap.ether.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.ether.ether.sa);
- fprintf(f, " ");
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- fprintf(f, "vlan ");
- ether_addr_show(f, &a->encap.vlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vlan.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u ",
- a->encap.vlan.vlan.pcp,
- a->encap.vlan.vlan.dei,
- a->encap.vlan.vlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- fprintf(f, "qinq ");
- ether_addr_show(f, &a->encap.qinq.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.qinq.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
- a->encap.qinq.svlan.pcp,
- a->encap.qinq.svlan.dei,
- a->encap.qinq.svlan.vid,
- a->encap.qinq.cvlan.pcp,
- a->encap.qinq.cvlan.dei,
- a->encap.qinq.cvlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
- "unicast " : "multicast ");
- ether_addr_show(f, &a->encap.mpls.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.mpls.ether.sa);
- fprintf(f, " ");
- for (i = 0; i < a->encap.mpls.mpls_count; i++) {
- struct rte_table_action_mpls_hdr *l =
- &a->encap.mpls.mpls[i];
-
- fprintf(f, "label%u %u %u %u ",
- i,
- l->label,
- l->tc,
- l->ttl);
- }
- break;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- fprintf(f, "pppoe ");
- ether_addr_show(f, &a->encap.pppoe.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.pppoe.ether.sa);
- fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- fprintf(f, "vxlan ether ");
- ether_addr_show(f, &a->encap.vxlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vxlan.ether.sa);
- if (table->ap->params.encap.vxlan.vlan)
- fprintf(f, " vlan pcp %u dei %u vid %u ",
- a->encap.vxlan.vlan.pcp,
- a->encap.vxlan.vlan.dei,
- a->encap.vxlan.vlan.vid);
- if (table->ap->params.encap.vxlan.ip_version) {
- fprintf(f, " ipv4 ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
- fprintf(f, " ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
- fprintf(f, " %u %u ",
- (uint32_t)a->encap.vxlan.ipv4.dscp,
- (uint32_t)a->encap.vxlan.ipv4.ttl);
- } else {
- fprintf(f, " ipv6 ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.sa);
- fprintf(f, " ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.da);
- fprintf(f, " %u %u %u ",
- a->encap.vxlan.ipv6.flow_label,
- (uint32_t)a->encap.vxlan.ipv6.dscp,
- (uint32_t)a->encap.vxlan.ipv6.hop_limit);
- fprintf(f, " udp %u %u vxlan %u ",
- a->encap.vxlan.udp.sp,
- a->encap.vxlan.udp.dp,
- a->encap.vxlan.vxlan.vni);
- }
- break;
-
- default:
- fprintf(f, "unknown ");
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
- if (a->nat.ip_version)
- ipv4_addr_show(f, a->nat.addr.ipv4);
- else
- ipv6_addr_show(f, &a->nat.addr.ipv6);
- fprintf(f, " %u ", (uint32_t)(a->nat.port));
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
- fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
- fprintf(f, "stats ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
- fprintf(f, "time ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
- fprintf(f, "sym_crypto ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
- fprintf(f, "tag %u ", a->tag.tag);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
- fprintf(f, "decap %u ", a->decap.n);
-
- /* end */
- fprintf(f, "\n");
- }
-
- /* Write table default rule to file. */
- if (table->rule_default) {
- struct table_rule_action *a = &table->rule_default->action;
-
- fprintf(f, "# match default action fwd ");
-
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- } else
- fprintf(f, "# match default action fwd drop ");
-
- fprintf(f, "\n");
-
- /* Close file. */
- fclose(f);
-
- return 0;
-}
-
-static const char cmd_pipeline_table_rule_show_help[] =
-"pipeline <pipeline_name> table <table_id> rule show\n"
-" file <file_name>\n";
-
-static void
-cmd_pipeline_table_rule_show(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *file_name = NULL, *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "show") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
- return;
- }
-
- if (strcmp(tokens[6], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
- return;
- }
-
- file_name = tokens[7];
-
- status = table_rule_show(pipeline_name, table_id, file_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_rule_stats_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_stats_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_stats_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule stats. */
- status = pipeline_table_rule_stats_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- if (stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
- stats.n_packets,
- stats.n_bytes);
-
- if (stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
- stats.n_packets);
-
- if (!stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
- stats.n_bytes);
-
- if (!stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
-}
-
-static const char cmd_pipeline_table_meter_profile_add_help[] =
-"pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
-" add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
-" | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
-
-static void
-cmd_pipeline_table_meter_profile_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_meter_profile p;
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens < 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[8], "srtcm") == 0) {
- if (n_tokens != 15) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_SRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[13], "ebs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
- return;
- }
- } else if (strcmp(tokens[8], "trtcm") == 0) {
- if (n_tokens != 17) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_TRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "pir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pir");
- return;
- }
- if (strcmp(tokens[13], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[15], "pbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_mtr_profile_add(pipeline_name,
- table_id,
- meter_profile_id,
- &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_meter_profile_delete_help[] =
-"pipeline <pipeline_name> table <table_id>\n"
-" meter profile <meter_profile_id> delete\n";
-
-static void
-cmd_pipeline_table_meter_profile_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- status = pipeline_table_mtr_profile_delete(pipeline_name,
- table_id,
- meter_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_meter_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_meter_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_mtr_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule meter stats. */
- status = pipeline_table_rule_mtr_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
-}
-
-
-static const char cmd_pipeline_table_dscp_help[] =
-"pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - exactly 64 lines\n"
-" - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
-
-static int
-load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
- const char *file_name,
- uint32_t *line_number)
-{
- FILE *f = NULL;
- uint32_t dscp, l;
-
- /* Check input arguments */
- if ((dscp_table == NULL) ||
- (file_name == NULL) ||
- (line_number == NULL)) {
- if (line_number)
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Read file */
- for (dscp = 0, l = 1; ; l++) {
- char line[64];
- char *tokens[3];
- enum rte_color color;
- uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
-
- if (fgets(line, sizeof(line), f) == NULL)
- break;
-
- if (is_comment(line))
- continue;
-
- if (parse_tokenize_string(line, tokens, &n_tokens)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- if (n_tokens == 0)
- continue;
-
- if ((dscp >= RTE_DIM(dscp_table->entry)) ||
- (n_tokens != RTE_DIM(tokens)) ||
- parser_read_uint32(&tc_id, tokens[0]) ||
- (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
- parser_read_uint32(&tc_queue_id, tokens[1]) ||
- (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
- (strlen(tokens[2]) != 1)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- switch (tokens[2][0]) {
- case 'g':
- case 'G':
- color = RTE_COLOR_GREEN;
- break;
-
- case 'y':
- case 'Y':
- color = RTE_COLOR_YELLOW;
- break;
-
- case 'r':
- case 'R':
- color = RTE_COLOR_RED;
- break;
-
- default:
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- dscp_table->entry[dscp].tc_id = tc_id;
- dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
- dscp_table->entry[dscp].color = color;
- dscp++;
- }
-
- /* Close file */
- fclose(f);
- return 0;
-}
-
-static void
-cmd_pipeline_table_dscp(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_dscp_table dscp_table;
- char *pipeline_name, *file_name;
- uint32_t table_id, line_number;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "dscp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
- return;
- }
-
- file_name = tokens[5];
-
- status = load_dscp_table(&dscp_table, file_name, &line_number);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- status = pipeline_table_dscp_table_update(pipeline_name,
- table_id,
- UINT64_MAX,
- &dscp_table);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_ttl_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_ttl_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_ttl_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "ttl") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule TTL stats. */
- status = pipeline_table_rule_ttl_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n",
- stats.n_packets);
-}
-
-static const char cmd_pipeline_table_rule_time_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read time\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_time_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint64_t timestamp;
- uint32_t table_id, n_tokens_parsed;
- int status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "time") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule timestamp. */
- status = pipeline_table_rule_time_read(pipeline_name,
- table_id,
- &m,
- ×tamp);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
-}
-
-static const char cmd_thread_pipeline_enable_help[] =
-"thread <thread_id> pipeline <pipeline_name> enable\n";
-
-static void
-cmd_thread_pipeline_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = thread_pipeline_enable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
- return;
- }
-}
-
-
-static const char cmd_thread_pipeline_disable_help[] =
-"thread <thread_id> pipeline <pipeline_name> disable\n";
-
-static void
-cmd_thread_pipeline_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = thread_pipeline_disable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL,
- "thread pipeline disable");
- return;
- }
-}
-
-static void
-cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- tokens++;
- n_tokens--;
-
- if (n_tokens == 0) {
- snprintf(out, out_size,
- "Type 'help <command>' for details on each command.\n\n"
- "List of commands:\n"
- "\tmempool\n"
- "\tlink\n"
- "\tswq\n"
- "\ttmgr subport profile\n"
- "\ttmgr pipe profile\n"
- "\ttmgr\n"
- "\ttmgr subport\n"
- "\ttmgr subport pipe\n"
- "\ttap\n"
- "\tport in action profile\n"
- "\ttable action profile\n"
- "\tpipeline\n"
- "\tpipeline port in\n"
- "\tpipeline port out\n"
- "\tpipeline table\n"
- "\tpipeline port in table\n"
- "\tpipeline port in stats\n"
- "\tpipeline port in enable\n"
- "\tpipeline port in disable\n"
- "\tpipeline port out stats\n"
- "\tpipeline table stats\n"
- "\tpipeline table rule add\n"
- "\tpipeline table rule add default\n"
- "\tpipeline table rule add bulk\n"
- "\tpipeline table rule delete\n"
- "\tpipeline table rule delete default\n"
- "\tpipeline table rule show\n"
- "\tpipeline table rule stats read\n"
- "\tpipeline table meter profile add\n"
- "\tpipeline table meter profile delete\n"
- "\tpipeline table rule meter read\n"
- "\tpipeline table dscp\n"
- "\tpipeline table rule ttl read\n"
- "\tpipeline table rule time read\n"
- "\tthread pipeline enable\n"
- "\tthread pipeline disable\n\n");
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_link_help);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_swq_help);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if (n_tokens == 1) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
- return;
- }
-
- if ((n_tokens == 2) &&
- (strcmp(tokens[1], "subport")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_tmgr_subport_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "pipe") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
- return;
- }
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tap_help);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[0], "port") == 0) &&
- (strcmp(tokens[1], "in") == 0) &&
- (strcmp(tokens[2], "action") == 0) &&
- (strcmp(tokens[3], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "table") == 0) &&
- (strcmp(tokens[1], "action") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "port") == 0)) {
- if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
- return;
- }
-
- if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "table") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_table_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_stats_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "enable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_enable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "disable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_disable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "out") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_out_stats_help);
- return;
- }
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "table") == 0)) {
- if (n_tokens == 2) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_stats_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_dscp_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_default_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "bulk") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_bulk_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_default_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "show") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_show_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "stats") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_stats_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "meter") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_meter_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "ttl") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_ttl_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "time") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_time_read_help);
- return;
- }
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "thread") == 0) &&
- (strcmp(tokens[1], "pipeline") == 0)) {
- if (strcmp(tokens[2], "enable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_enable_help);
- return;
- }
-
- if (strcmp(tokens[2], "disable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_disable_help);
- return;
- }
- }
-
- snprintf(out, out_size, "Invalid command\n");
-}
-
-void
-cli_process(char *in, char *out, size_t out_size)
-{
- char *tokens[CMD_MAX_TOKENS];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- if (is_comment(in))
- return;
-
- status = parse_tokenize_string(in, tokens, &n_tokens);
- if (status) {
- snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
- return;
- }
-
- if (n_tokens == 0)
- return;
-
- if (strcmp(tokens[0], "help") == 0) {
- cmd_help(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- cmd_mempool(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- if (strcmp(tokens[1], "show") == 0) {
- cmd_link_show(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_link(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- cmd_swq(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_subport_profile(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "profile") == 0)) {
- cmd_tmgr_subport(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "pipe") == 0)) {
- cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_tmgr(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- cmd_tap(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- cmd_cryptodev(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "port") == 0) {
- cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "table") == 0) {
- cmd_table_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "pipeline") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[2], "period") == 0)) {
- cmd_pipeline(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 4) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[3], "match") == 0)) {
- cmd_pipeline_table(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "table") == 0)) {
- cmd_pipeline_port_in_table(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_in_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "enable") == 0)) {
- cmd_pipeline_port_in_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "disable") == 0)) {
- cmd_pipeline_port_in_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_out_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "stats") == 0)) {
- cmd_pipeline_table_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_add_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "bulk") == 0)) {
- cmd_pipeline_table_rule_add_bulk(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "delete") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_delete_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_delete(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "show") == 0)) {
- cmd_pipeline_table_rule_show(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "stats") == 0)) {
- cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "add") == 0)) {
- cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "delete") == 0)) {
- cmd_pipeline_table_meter_profile_delete(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "meter") == 0)) {
- cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "dscp") == 0)) {
- cmd_pipeline_table_dscp(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "ttl") == 0)) {
- cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "time") == 0)) {
- cmd_pipeline_table_rule_time_read(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- if (strcmp(tokens[0], "thread") == 0) {
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "enable") == 0)) {
- cmd_thread_pipeline_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "disable") == 0)) {
- cmd_thread_pipeline_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
-}
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max)
-{
- char *msg_in = NULL, *msg_out = NULL;
- FILE *f = NULL;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (msg_in_len_max == 0) ||
- (msg_out_len_max == 0))
- return -EINVAL;
-
- msg_in = malloc(msg_in_len_max + 1);
- msg_out = malloc(msg_out_len_max + 1);
- if ((msg_in == NULL) ||
- (msg_out == NULL)) {
- free(msg_out);
- free(msg_in);
- return -ENOMEM;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- free(msg_out);
- free(msg_in);
- return -EIO;
- }
-
- /* Read file */
- for ( ; ; ) {
- if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
- break;
-
- printf("%s", msg_in);
- msg_out[0] = 0;
-
- cli_process(msg_in,
- msg_out,
- msg_out_len_max);
-
- if (strlen(msg_out))
- printf("%s", msg_out);
- }
-
- /* Close file */
- fclose(f);
- free(msg_out);
- free(msg_in);
- return 0;
-}
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *line = NULL;
- FILE *f = NULL;
- uint32_t rule_id = 0, line_id = 0;
- int status = 0;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (line_len_max == 0) ||
- (rule_list == NULL) ||
- (n_rules == NULL) ||
- (line_number == NULL) ||
- (out == NULL)) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Memory allocation */
- list = malloc(sizeof(struct table_rule_list));
- if (list == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INIT(list);
-
- line = malloc(line_len_max + 1);
- if (line == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- /* Open file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- status = -EIO;
- goto cli_rule_file_process_free;
- }
-
- /* Read file */
- for (line_id = 1, rule_id = 0; ; line_id++) {
- char *tokens[CMD_MAX_TOKENS];
- struct table_rule *rule = NULL;
- uint32_t n_tokens, n_tokens_parsed, t0;
-
- /* Read next line from file. */
- if (fgets(line, line_len_max + 1, f) == NULL)
- break;
-
- /* Comment. */
- if (is_comment(line))
- continue;
-
- /* Parse line. */
- n_tokens = RTE_DIM(tokens);
- status = parse_tokenize_string(line, tokens, &n_tokens);
- if (status) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Empty line. */
- if (n_tokens == 0)
- continue;
- t0 = 0;
-
- /* Rule alloc and insert. */
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INSERT_TAIL(list, rule, node);
-
- /* Rule match. */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->match);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Rule action. */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->action);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Line completed. */
- if (t0 < n_tokens) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Increment rule count */
- rule_id++;
- }
-
- /* Close file */
- fclose(f);
-
- /* Memory free */
- free(line);
-
- *rule_list = list;
- *n_rules = rule_id;
- *line_number = line_id;
- return 0;
-
-cli_rule_file_process_free:
- if (rule_list != NULL)
- *rule_list = NULL;
-
- if (n_rules != NULL)
- *n_rules = rule_id;
-
- if (line_number != NULL)
- *line_number = line_id;
-
- if (list != NULL)
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- }
-
- if (f)
- fclose(f);
- free(line);
- free(list);
-
- return status;
-}
diff --git a/examples/ip_pipeline/cli.h b/examples/ip_pipeline/cli.h
deleted file mode 100644
index 992e4c3a4a..0000000000
--- a/examples/ip_pipeline/cli.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CLI_H__
-#define __INCLUDE_CLI_H__
-
-#include <stddef.h>
-
-void
-cli_process(char *in, char *out, size_t out_size);
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max);
-
-#endif
diff --git a/examples/ip_pipeline/common.h b/examples/ip_pipeline/common.h
deleted file mode 100644
index 0886dfbe95..0000000000
--- a/examples/ip_pipeline/common.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_COMMON_H_
-#define _INCLUDE_COMMON_H_
-
-#ifndef NAME_SIZE
-#define NAME_SIZE 64
-#endif
-
-#endif /* _INCLUDE_COMMON_H_ */
diff --git a/examples/ip_pipeline/conn.c b/examples/ip_pipeline/conn.c
deleted file mode 100644
index b2406b7af1..0000000000
--- a/examples/ip_pipeline/conn.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <sys/socket.h>
-
-#include <sys/epoll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#include <rte_string_fns.h>
-
-#include "conn.h"
-
-#define MSG_CMD_TOO_LONG "Command too long."
-
-struct conn {
- char *welcome;
- char *prompt;
- char *buf;
- char *msg_in;
- char *msg_out;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- size_t msg_in_len;
- int fd_server;
- int fd_client_group;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p)
-{
- struct sockaddr_in server_address;
- struct conn *conn;
- int fd_server, fd_client_group, status;
-
- memset(&server_address, 0, sizeof(server_address));
-
- /* Check input arguments */
- if ((p == NULL) ||
- (p->welcome == NULL) ||
- (p->prompt == NULL) ||
- (p->addr == NULL) ||
- (p->buf_size == 0) ||
- (p->msg_in_len_max == 0) ||
- (p->msg_out_len_max == 0) ||
- (p->msg_handle == NULL))
- return NULL;
-
- status = inet_aton(p->addr, &server_address.sin_addr);
- if (status == 0)
- return NULL;
-
- /* Memory allocation */
- conn = calloc(1, sizeof(struct conn));
- if (conn == NULL)
- return NULL;
-
- conn->welcome = calloc(1, CONN_WELCOME_LEN_MAX + 1);
- conn->prompt = calloc(1, CONN_PROMPT_LEN_MAX + 1);
- conn->buf = calloc(1, p->buf_size);
- conn->msg_in = calloc(1, p->msg_in_len_max + 1);
- conn->msg_out = calloc(1, p->msg_out_len_max + 1);
-
- if ((conn->welcome == NULL) ||
- (conn->prompt == NULL) ||
- (conn->buf == NULL) ||
- (conn->msg_in == NULL) ||
- (conn->msg_out == NULL)) {
- conn_free(conn);
- return NULL;
- }
-
- /* Server socket */
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(p->port);
-
- fd_server = socket(AF_INET,
- SOCK_STREAM | SOCK_NONBLOCK,
- 0);
- if (fd_server == -1) {
- conn_free(conn);
- return NULL;
- }
-
- status = bind(fd_server,
- (struct sockaddr *) &server_address,
- sizeof(server_address));
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- status = listen(fd_server, 16);
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Client group */
- fd_client_group = epoll_create(1);
- if (fd_client_group == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Fill in */
- strlcpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX + 1);
- strlcpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX + 1);
- conn->buf_size = p->buf_size;
- conn->msg_in_len_max = p->msg_in_len_max;
- conn->msg_out_len_max = p->msg_out_len_max;
- conn->msg_in_len = 0;
- conn->fd_server = fd_server;
- conn->fd_client_group = fd_client_group;
- conn->msg_handle = p->msg_handle;
-
- return conn;
-}
-
-void
-conn_free(struct conn *conn)
-{
- if (conn == NULL)
- return;
-
- if (conn->fd_client_group)
- close(conn->fd_client_group);
-
- if (conn->fd_server)
- close(conn->fd_server);
-
- free(conn->msg_out);
- free(conn->msg_in);
- free(conn->prompt);
- free(conn->welcome);
- free(conn);
-}
-
-int
-conn_poll_for_conn(struct conn *conn)
-{
- struct sockaddr_in client_address;
- struct epoll_event event;
- socklen_t client_address_length;
- int fd_client, status;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Server socket */
- client_address_length = sizeof(client_address);
- fd_client = accept4(conn->fd_server,
- (struct sockaddr *) &client_address,
- &client_address_length,
- SOCK_NONBLOCK);
- if (fd_client == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
-
- /* Client group */
- event.events = EPOLLIN | EPOLLRDHUP | EPOLLHUP;
- event.data.fd = fd_client;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_ADD,
- fd_client,
- &event);
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- /* Client */
- status = write(fd_client,
- conn->welcome,
- strlen(conn->welcome));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- return 0;
-}
-
-static int
-data_event_handle(struct conn *conn,
- int fd_client)
-{
- ssize_t len, i, status;
-
- /* Read input message */
-
- len = read(fd_client,
- conn->buf,
- conn->buf_size);
- if (len == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
- if (len == 0)
- return 0;
-
- /* Handle input messages */
- for (i = 0; i < len; i++) {
- if (conn->buf[i] == '\n') {
- size_t n;
-
- conn->msg_in[conn->msg_in_len] = 0;
- conn->msg_out[0] = 0;
-
- conn->msg_handle(conn->msg_in,
- conn->msg_out,
- conn->msg_out_len_max);
-
- n = strlen(conn->msg_out);
- if (n) {
- status = write(fd_client,
- conn->msg_out,
- n);
- if (status == -1)
- return status;
- }
-
- conn->msg_in_len = 0;
- } else if (conn->msg_in_len < conn->msg_in_len_max) {
- conn->msg_in[conn->msg_in_len] = conn->buf[i];
- conn->msg_in_len++;
- } else {
- status = write(fd_client,
- MSG_CMD_TOO_LONG,
- strlen(MSG_CMD_TOO_LONG));
- if (status == -1)
- return status;
-
- conn->msg_in_len = 0;
- }
- }
-
- /* Write prompt */
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1)
- return status;
-
- return 0;
-}
-
-static int
-control_event_handle(struct conn *conn,
- int fd_client)
-{
- int status;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_DEL,
- fd_client,
- NULL);
- if (status == -1)
- return -1;
-
- status = close(fd_client);
- if (status == -1)
- return -1;
-
- return 0;
-}
-
-int
-conn_poll_for_msg(struct conn *conn)
-{
- struct epoll_event event;
- int fd_client, status, status_data = 0, status_control = 0;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Client group */
- status = epoll_wait(conn->fd_client_group,
- &event,
- 1,
- 0);
- if (status == -1)
- return -1;
- if (status == 0)
- return 0;
-
- fd_client = event.data.fd;
-
- /* Data available */
- if (event.events & EPOLLIN)
- status_data = data_event_handle(conn, fd_client);
-
- /* Control events */
- if (event.events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP))
- status_control = control_event_handle(conn, fd_client);
-
- if (status_data || status_control)
- return -1;
-
- return 0;
-}
diff --git a/examples/ip_pipeline/conn.h b/examples/ip_pipeline/conn.h
deleted file mode 100644
index 46f9f95e9c..0000000000
--- a/examples/ip_pipeline/conn.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CONN_H__
-#define __INCLUDE_CONN_H__
-
-#include <stdint.h>
-
-struct conn;
-
-#ifndef CONN_WELCOME_LEN_MAX
-#define CONN_WELCOME_LEN_MAX 1024
-#endif
-
-#ifndef CONN_PROMPT_LEN_MAX
-#define CONN_PROMPT_LEN_MAX 16
-#endif
-
-typedef void (*conn_msg_handle_t)(char *msg_in,
- char *msg_out,
- size_t msg_out_len_max);
-
-struct conn_params {
- const char *welcome;
- const char *prompt;
- const char *addr;
- uint16_t port;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p);
-
-void
-conn_free(struct conn *conn);
-
-int
-conn_poll_for_conn(struct conn *conn);
-
-int
-conn_poll_for_msg(struct conn *conn);
-
-#endif
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
deleted file mode 100644
index cd0f9c3d4e..0000000000
--- a/examples/ip_pipeline/cryptodev.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <rte_cryptodev.h>
-#include <rte_string_fns.h>
-
-#include "cryptodev.h"
-
-#define PIPELINE_CRYPTO_SESSION_CACHE_SIZE 128
-
-static struct cryptodev_list cryptodev_list;
-
-int
-cryptodev_init(void)
-{
- TAILQ_INIT(&cryptodev_list);
-
- return 0;
-}
-
-struct cryptodev *
-cryptodev_find(const char *name)
-{
- struct cryptodev *cryptodev;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(cryptodev, &cryptodev_list, node)
- if (strcmp(cryptodev->name, name) == 0)
- return cryptodev;
-
- return NULL;
-}
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev)
-{
- return (cryptodev == NULL) ?
- TAILQ_FIRST(&cryptodev_list) :
- TAILQ_NEXT(cryptodev, node);
-}
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params)
-{
- struct rte_cryptodev_info dev_info;
- struct rte_cryptodev_config dev_conf;
- struct rte_cryptodev_qp_conf queue_conf;
- struct cryptodev *cryptodev;
- uint32_t dev_id, i;
- uint32_t socket_id;
- uint32_t cache_size;
- char mp_name[NAME_SIZE];
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- cryptodev_find(name) ||
- (params->n_queues == 0) ||
- (params->queue_size == 0) ||
- (params->session_pool_size == 0))
- return NULL;
-
- if (params->dev_name) {
- status = rte_cryptodev_get_dev_id(params->dev_name);
- if (status == -1)
- return NULL;
-
- dev_id = (uint32_t)status;
- } else {
- if (rte_cryptodev_is_valid_dev(params->dev_id) == 0)
- return NULL;
-
- dev_id = params->dev_id;
- }
-
- cache_size = (params->session_pool_size / 2 <
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE) ?
- (params->session_pool_size / 2) :
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE;
-
- socket_id = rte_cryptodev_socket_id(dev_id);
- rte_cryptodev_info_get(dev_id, &dev_info);
-
- if (dev_info.max_nb_queue_pairs < params->n_queues)
- return NULL;
-
- dev_conf.socket_id = socket_id;
- dev_conf.nb_queue_pairs = params->n_queues;
- dev_conf.ff_disable = 0;
-
- status = rte_cryptodev_configure(dev_id, &dev_conf);
- if (status < 0)
- return NULL;
-
- queue_conf.nb_descriptors = params->queue_size;
- for (i = 0; i < params->n_queues; i++) {
- status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id);
- if (status < 0)
- return NULL;
- }
-
- if (rte_cryptodev_start(dev_id) < 0)
- return NULL;
-
- cryptodev = calloc(1, sizeof(struct cryptodev));
- if (cryptodev == NULL) {
- rte_cryptodev_stop(dev_id);
- return NULL;
- }
-
- strlcpy(cryptodev->name, name, sizeof(cryptodev->name));
- cryptodev->dev_id = dev_id;
- cryptodev->n_queues = params->n_queues;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id);
- cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(
- mp_name,
- params->session_pool_size,
- 0,
- cache_size,
- 0,
- socket_id);
- if (!cryptodev->mp_create)
- goto error_exit;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp_priv%u", name, dev_id);
- cryptodev->mp_init = rte_mempool_create(
- NULL,
- params->session_pool_size,
- rte_cryptodev_sym_get_private_session_size(dev_id),
- cache_size,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- socket_id,
- 0);
- if (!cryptodev->mp_init)
- goto error_exit;
-
- TAILQ_INSERT_TAIL(&cryptodev_list, cryptodev, node);
-
- return cryptodev;
-
-error_exit:
- rte_mempool_free(cryptodev->mp_create);
- rte_mempool_free(cryptodev->mp_init);
-
- free(cryptodev);
-
- return NULL;
-}
diff --git a/examples/ip_pipeline/cryptodev.h b/examples/ip_pipeline/cryptodev.h
deleted file mode 100644
index d00434379e..0000000000
--- a/examples/ip_pipeline/cryptodev.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SYM_C_H_
-#define _INCLUDE_SYM_C_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_cryptodev.h>
-
-#include "common.h"
-
-struct cryptodev {
- TAILQ_ENTRY(cryptodev) node;
- char name[NAME_SIZE];
- uint16_t dev_id;
- uint32_t n_queues;
- struct rte_mempool *mp_create;
- struct rte_mempool *mp_init;
-};
-
-TAILQ_HEAD(cryptodev_list, cryptodev);
-
-int
-cryptodev_init(void);
-
-struct cryptodev *
-cryptodev_find(const char *name);
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev);
-
-struct cryptodev_params {
- const char *dev_name;
- uint32_t dev_id; /**< Valid only when *dev_name* is NULL. */
- uint32_t n_queues;
- uint32_t queue_size;
- uint32_t session_pool_size;
-};
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params);
-
-#endif
diff --git a/examples/ip_pipeline/examples/firewall.cli b/examples/ip_pipeline/examples/firewall.cli
deleted file mode 100644
index 269256c161..0000000000
--- a/examples/ip_pipeline/examples/firewall.cli
+++ /dev/null
@@ -1,59 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Firewall |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; -+-
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match acl ipv4 offset 270 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd drop
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow.cli b/examples/ip_pipeline/examples/flow.cli
deleted file mode 100644
index 426ff90255..0000000000
--- a/examples/ip_pipeline/examples/flow.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Flow |
-; LINK2 RXQ0 --->| Classification |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 16 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF offset 278 buckets 16K size 65K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.10 200.0.0.10 100 200 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.11 200.0.0.11 101 201 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.12 200.0.0.12 102 202 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.13 200.0.0.13 103 203 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow_crypto.cli b/examples/ip_pipeline/examples/flow_crypto.cli
deleted file mode 100644
index 849f9d5fec..0000000000
--- a/examples/ip_pipeline/examples/flow_crypto.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> CRYPTO0 TXQ0
-; | Flow |
-; CRYPTO0 RXQ0-->| Classification |---> LINK0 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 280 20
-; 4 Packet 256 1536
-; 5 Crypto Operation 1792 160
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 1
-
-link LINK0 dev 81:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-#Cryptodev
-cryptodev CRYPTO0 dev crypto_aesni_gcm0 queue 1 1024 max_sessions 512
-
-table action profile AP0 ipv4 offset 270 fwd sym_crypto dev CRYPTO0 offset 1792
-table action profile AP1 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 1
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 cryptodev CRYPTO0 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 cryptodev CRYPTO0 txq 0 offset 1792
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 8 mask FFFFFFFF00000000 offset 282 buckets 1K size 4K action AP0
-pipeline PIPELINE0 table match stub action AP1
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-
-thread 2 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 2
-
-#AES-GCM encrypt
-pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto encrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-#AES-GCM decrypt
-#pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto decrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
diff --git a/examples/ip_pipeline/examples/l2fwd.cli b/examples/ip_pipeline/examples/l2fwd.cli
deleted file mode 100644
index 35e77cc968..0000000000
--- a/examples/ip_pipeline/examples/l2fwd.cli
+++ /dev/null
@@ -1,51 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; The pipeline below implements a simple pass-through connection between the
-; input ports to the output ports, as in this diagram:
-; ________________
-; LINK0 RXQ0 --->|................|---> LINK1 TXQ0
-; | |
-; LINK1 RXQ0 --->|................|---> LINK0 TXQ0
-; | PIPELINE0 |
-; LINK2 RXQ0 --->|................|---> LINK3 TXQ0
-; | |
-; LINK3 RXQ0 --->|................|---> LINK2 TXQ0
-; |________________|
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 1
-pipeline PIPELINE0 table 1 rule add match default action fwd port 0
-pipeline PIPELINE0 table 2 rule add match default action fwd port 3
-pipeline PIPELINE0 table 3 rule add match default action fwd port 2
diff --git a/examples/ip_pipeline/examples/route.cli b/examples/ip_pipeline/examples/route.cli
deleted file mode 100644
index 579b36a659..0000000000
--- a/examples/ip_pipeline/examples/route.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Routing |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; +-----------> SINK0 (route miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/route_ecmp.cli b/examples/ip_pipeline/examples/route_ecmp.cli
deleted file mode 100644
index 06434a2560..0000000000
--- a/examples/ip_pipeline/examples/route_ecmp.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; Equal Cost Multi-Path (ECMP) Routing
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile APRT ipv4 offset 270 fwd balance offset 278 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF outoffset 256
-table action profile APNH ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action APRT
-pipeline PIPELINE0 table match array offset 256 size 64K action APNH
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd table 1 balance 0 0 0 0 1 1 2 2
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd table 1 balance 1 1 1 1 2 2 3 3
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd table 1 balance 2 2 2 2 3 3 0 0
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd table 1 balance 3 3 3 3 0 0 1 1
-
-pipeline PIPELINE0 table 1 rule add match array 0 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 1 rule add match array 1 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 1 rule add match array 2 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 1 rule add match array 3 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/rss.cli b/examples/ip_pipeline/examples/rss.cli
deleted file mode 100644
index 29c0a91392..0000000000
--- a/examples/ip_pipeline/examples/rss.cli
+++ /dev/null
@@ -1,112 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; This setup demonstrates the usage of NIC Receive Side Scaling (RSS) feature.
-; Each NIC splits the input traffic into 4 RX queues, with each of its RX queues
-; being handled by a different pipeline:
-;
-; +-----------+ +----------+
-; +--------------------------->| | | |
-; | +------------------->| PIPELINE0 +--->| LINK 0 |--->
-; | | +------------->| (CORE A) | | TX |
-; | | | +------->| | | |
-; | | | | +-----------+ +----------+
-; +----------+ | | | |
-; | |-------+ | | |
-;--->| LINK 0 |-----------+ | | |
-; | RX |---------+ | | | |
-; | |-------+ | | | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | | +---|-----|-----|------->| | | |
-; +----------+ | | | +---|-----|------->| PIPELINE1 +--->| LINK 1 |--->
-; | |-------|-|-----+ | | +---|------->| (CORE B) | | TX |
-;--->| LINK 1 |-------|-|-------+ | | | +----->| | | |
-; | RX |-------|-|-------+ | | | | +-----------+ +----------+
-; | |-------|-|-----+ | | | | |
-; +----------+ | | | | | | | |
-; | | | | | | | |
-; +----------+ | | | | | | | |
-; | |-------|-|-----|-|---+ | | |
-;--->| LINK 2 |-------|-|-----|-|-----+ | | +-----------+ +----------+
-; | RX |-----+ | +-----|-|---------|-|----->| | | |
-; | |---+ | | | +---------|-|----->| PIPELINE2 +--->| LINK 2 |--->
-; +----------+ | +-|-------|-----------|-|----->| (CORE C) | | TX |
-; | | | | | +--->| | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | |---|---|-------|-----------+ | |
-;--->| LINK 3 |---|---|-------|-------------+ |
-; | RX |---|---|-------|---------------+
-; | |---|---|-------|-----------+
-; +----------+ | | | |
-; | | | | +-----------+ +----------+
-; | +-------|-----------|------->| | | |
-; | +-----------|------->| PIPELINE3 +--->| LINK 3 |--->
-; +-----------------------|------->| (CORE D) | | TX |
-; +------->| | | |
-; +-----------+ +----------+
-;
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK1 dev 0000:02:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK2 dev 0000:06:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK3 dev 0000:06:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE1 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE1 port in bsz 32 link LINK0 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK1 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK2 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK3 rxq 1
-pipeline PIPELINE1 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE1 table match stub
-pipeline PIPELINE1 port in 0 table 0
-pipeline PIPELINE1 port in 1 table 0
-pipeline PIPELINE1 port in 2 table 0
-pipeline PIPELINE1 port in 3 table 0
-pipeline PIPELINE1 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE2 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE2 port in bsz 32 link LINK0 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK1 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK2 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK3 rxq 2
-pipeline PIPELINE2 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE2 table match stub
-pipeline PIPELINE2 port in 0 table 0
-pipeline PIPELINE2 port in 1 table 0
-pipeline PIPELINE2 port in 2 table 0
-pipeline PIPELINE2 port in 3 table 0
-pipeline PIPELINE2 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE3 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE3 port in bsz 32 link LINK0 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK1 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK2 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK3 rxq 3
-pipeline PIPELINE3 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE3 table match stub
-pipeline PIPELINE3 port in 0 table 0
-pipeline PIPELINE3 port in 1 table 0
-pipeline PIPELINE3 port in 2 table 0
-pipeline PIPELINE3 port in 3 table 0
-pipeline PIPELINE3 table 0 rule add match default action fwd port 0
-
-thread 1 pipeline PIPELINE0 enable
-thread 2 pipeline PIPELINE1 enable
-thread 3 pipeline PIPELINE2 enable
-thread 4 pipeline PIPELINE3 enable
diff --git a/examples/ip_pipeline/examples/tap.cli b/examples/ip_pipeline/examples/tap.cli
deleted file mode 100644
index 600cea2643..0000000000
--- a/examples/ip_pipeline/examples/tap.cli
+++ /dev/null
@@ -1,66 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________ ______________________
-; | | TAP0 | |
-; LINK0 RXQ0 --->|...............|------->|--+ |
-; | | TAP1 | | br0 |
-; LINK1 TXQ0 <---|...............|<-------|<-+ |
-; | | | Linux Kernel |
-; | PIPELINE0 | | Network Stack |
-; | | TAP1 | |
-; LINK1 RXQ0 --->|...............|------->|--+ |
-; | | TAP0 | | br0 |
-; LINK0 TXQ0 <---|...............|<-------|<-+ |
-; |_______________| |______________________|
-;
-; Configure Linux kernel bridge between TAP0 and TAP1 interfaces:
-; [Linux]$ brctl addbr br0
-; [Linux]$ brctl addif br0 TAP0
-; [Linux]$ brctl addif br0 TAP1
-; [Linux]$ ifconfig TAP0 up
-; [Linux]$ ifconfig TAP1 up
-; [Linux]$ ifconfig br0 up
-;
-; Monitor packet forwarding performed by Linux kernel between TAP0 and TAP1:
-; [Linux]$ tcpdump -i TAP0
-; [Linux]$ tcpdump -i TAP1
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-tap TAP0
-tap TAP1
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP1 mempool MEMPOOL0 mtu 1500
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP0 mempool MEMPOOL0 mtu 1500
-
-pipeline PIPELINE0 port out bsz 32 tap TAP0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 tap TAP1
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
-pipeline PIPELINE0 table 2 rule add match default action fwd port 2
-pipeline PIPELINE0 table 3 rule add match default action fwd port 3
diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
deleted file mode 100644
index 4d69ebebfb..0000000000
--- a/examples/ip_pipeline/link.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_ethdev.h>
-#include <rte_string_fns.h>
-
-#include "link.h"
-#include "mempool.h"
-
-static struct link_list link_list;
-
-int
-link_init(void)
-{
- TAILQ_INIT(&link_list);
-
- return 0;
-}
-
-struct link *
-link_find(const char *name)
-{
- struct link *link;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(link, &link_list, node)
- if (strcmp(link->name, name) == 0)
- return link;
-
- return NULL;
-}
-
-struct link *
-link_next(struct link *link)
-{
- return (link == NULL) ? TAILQ_FIRST(&link_list) : TAILQ_NEXT(link, node);
-}
-
-static struct rte_eth_conf port_conf_default = {
- .link_speeds = 0,
- .rxmode = {
- .mq_mode = RTE_ETH_MQ_RX_NONE,
- .mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_key_len = 40,
- .rss_hf = 0,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
- .lpbk_mode = 0,
-};
-
-#define RETA_CONF_SIZE (RTE_ETH_RSS_RETA_SIZE_512 / RTE_ETH_RETA_GROUP_SIZE)
-
-static int
-rss_setup(uint16_t port_id,
- uint16_t reta_size,
- struct link_params_rss *rss)
-{
- struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
- uint32_t i;
- int status;
-
- /* RETA setting */
- memset(reta_conf, 0, sizeof(reta_conf));
-
- for (i = 0; i < reta_size; i++)
- reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX;
-
- for (i = 0; i < reta_size; i++) {
- uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE;
- uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE;
- uint32_t rss_qs_pos = i % rss->n_queues;
-
- reta_conf[reta_id].reta[reta_pos] =
- (uint16_t) rss->queue_id[rss_qs_pos];
- }
-
- /* RETA update */
- status = rte_eth_dev_rss_reta_update(port_id,
- reta_conf,
- reta_size);
-
- return status;
-}
-
-struct link *
-link_create(const char *name, struct link_params *params)
-{
- struct rte_eth_dev_info port_info;
- struct rte_eth_conf port_conf;
- struct link *link;
- struct link_params_rss *rss;
- struct mempool *mempool;
- uint32_t cpu_id, i;
- int status;
- uint16_t port_id;
-
- /* Check input params */
- if ((name == NULL) ||
- link_find(name) ||
- (params == NULL) ||
- (params->rx.n_queues == 0) ||
- (params->rx.queue_size == 0) ||
- (params->tx.n_queues == 0) ||
- (params->tx.queue_size == 0))
- return NULL;
-
- port_id = params->port_id;
- if (params->dev_name) {
- status = rte_eth_dev_get_port_by_name(params->dev_name,
- &port_id);
-
- if (status)
- return NULL;
- } else
- if (!rte_eth_dev_is_valid_port(port_id))
- return NULL;
-
- if (rte_eth_dev_info_get(port_id, &port_info) != 0)
- return NULL;
-
- mempool = mempool_find(params->rx.mempool_name);
- if (mempool == NULL)
- return NULL;
-
- rss = params->rx.rss;
- if (rss) {
- if ((port_info.reta_size == 0) ||
- (port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512))
- return NULL;
-
- if ((rss->n_queues == 0) ||
- (rss->n_queues >= LINK_RXQ_RSS_MAX))
- return NULL;
-
- for (i = 0; i < rss->n_queues; i++)
- if (rss->queue_id[i] >= port_info.max_rx_queues)
- return NULL;
- }
-
- /**
- * Resource create
- */
- /* Port */
- memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
- if (rss) {
- port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
- port_conf.rx_adv_conf.rss_conf.rss_hf =
- (RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP) &
- port_info.flow_type_rss_offloads;
- }
-
- cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
- if (cpu_id == (uint32_t) SOCKET_ID_ANY)
- cpu_id = 0;
-
- status = rte_eth_dev_configure(
- port_id,
- params->rx.n_queues,
- params->tx.n_queues,
- &port_conf);
-
- if (status < 0)
- return NULL;
-
- if (params->promiscuous) {
- status = rte_eth_promiscuous_enable(port_id);
- if (status != 0)
- return NULL;
- }
-
- /* Port RX */
- for (i = 0; i < params->rx.n_queues; i++) {
- status = rte_eth_rx_queue_setup(
- port_id,
- i,
- params->rx.queue_size,
- cpu_id,
- NULL,
- mempool->m);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port TX */
- for (i = 0; i < params->tx.n_queues; i++) {
- status = rte_eth_tx_queue_setup(
- port_id,
- i,
- params->tx.queue_size,
- cpu_id,
- NULL);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port start */
- status = rte_eth_dev_start(port_id);
- if (status < 0)
- return NULL;
-
- if (rss) {
- status = rss_setup(port_id, port_info.reta_size, rss);
-
- if (status) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
- }
-
- /* Port link up */
- status = rte_eth_dev_set_link_up(port_id);
- if ((status < 0) && (status != -ENOTSUP)) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node allocation */
- link = calloc(1, sizeof(struct link));
- if (link == NULL) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(link->name, name, sizeof(link->name));
- link->port_id = port_id;
- link->n_rxq = params->rx.n_queues;
- link->n_txq = params->tx.n_queues;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&link_list, link, node);
-
- return link;
-}
-
-int
-link_is_up(const char *name)
-{
- struct rte_eth_link link_params;
- struct link *link;
-
- /* Check input params */
- if (name == NULL)
- return 0;
-
- link = link_find(name);
- if (link == NULL)
- return 0;
-
- /* Resource */
- if (rte_eth_link_get(link->port_id, &link_params) < 0)
- return 0;
-
- return (link_params.link_status == RTE_ETH_LINK_DOWN) ? 0 : 1;
-}
diff --git a/examples/ip_pipeline/link.h b/examples/ip_pipeline/link.h
deleted file mode 100644
index 34ff1149e0..0000000000
--- a/examples/ip_pipeline/link.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_LINK_H_
-#define _INCLUDE_LINK_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include "common.h"
-
-#ifndef LINK_RXQ_RSS_MAX
-#define LINK_RXQ_RSS_MAX 16
-#endif
-
-struct link {
- TAILQ_ENTRY(link) node;
- char name[NAME_SIZE];
- uint16_t port_id;
- uint32_t n_rxq;
- uint32_t n_txq;
-};
-
-TAILQ_HEAD(link_list, link);
-
-int
-link_init(void);
-
-struct link *
-link_find(const char *name);
-
-struct link *
-link_next(struct link *link);
-
-struct link_params_rss {
- uint32_t queue_id[LINK_RXQ_RSS_MAX];
- uint32_t n_queues;
-};
-
-struct link_params {
- const char *dev_name;
- uint16_t port_id; /**< Valid only when *dev_name* is NULL. */
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- const char *mempool_name;
- struct link_params_rss *rss;
- } rx;
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- } tx;
-
- int promiscuous;
-};
-
-struct link *
-link_create(const char *name, struct link_params *params);
-
-int
-link_is_up(const char *name);
-
-#endif /* _INCLUDE_LINK_H_ */
diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c
deleted file mode 100644
index 663f538f02..0000000000
--- a/examples/ip_pipeline/main.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include <rte_launch.h>
-#include <rte_eal.h>
-
-#include "cli.h"
-#include "conn.h"
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-static const char usage[] =
- "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n";
-
-static const char welcome[] =
- "\n"
- "Welcome to IP Pipeline!\n"
- "\n";
-
-static const char prompt[] = "pipeline> ";
-
-static struct app_params {
- struct conn_params conn;
- char *script_name;
-} app = {
- .conn = {
- .welcome = welcome,
- .prompt = prompt,
- .addr = "0.0.0.0",
- .port = 8086,
- .buf_size = 1024 * 1024,
- .msg_in_len_max = 1024,
- .msg_out_len_max = 1024 * 1024,
- .msg_handle = cli_process,
- },
- .script_name = NULL,
-};
-
-static int
-parse_args(int argc, char **argv)
-{
- char *app_name = argv[0];
- struct option lgopts[] = {
- { NULL, 0, 0, 0 }
- };
- int opt, option_index;
- int h_present, p_present, s_present, n_args, i;
-
- /* Skip EAL input args */
- n_args = argc;
- for (i = 0; i < n_args; i++)
- if (strcmp(argv[i], "--") == 0) {
- argc -= i;
- argv += i;
- break;
- }
-
- if (i == n_args)
- return 0;
-
- /* Parse args */
- h_present = 0;
- p_present = 0;
- s_present = 0;
-
- while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index))
- != EOF)
- switch (opt) {
- case 'h':
- if (h_present) {
- printf("Error: Multiple -h arguments\n");
- return -1;
- }
- h_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -h not provided\n");
- return -1;
- }
-
- app.conn.addr = strdup(optarg);
- if (app.conn.addr == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- case 'p':
- if (p_present) {
- printf("Error: Multiple -p arguments\n");
- return -1;
- }
- p_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -p not provided\n");
- return -1;
- }
-
- app.conn.port = (uint16_t) atoi(optarg);
- break;
-
- case 's':
- if (s_present) {
- printf("Error: Multiple -s arguments\n");
- return -1;
- }
- s_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -s not provided\n");
- return -1;
- }
-
- app.script_name = strdup(optarg);
- if (app.script_name == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- default:
- printf(usage, app_name);
- return -1;
- }
-
- optind = 1; /* reset getopt lib */
-
- return 0;
-}
-
-int
-main(int argc, char **argv)
-{
- struct conn *conn;
- int status;
-
- /* Parse application arguments */
- status = parse_args(argc, argv);
- if (status < 0)
- return status;
-
- /* EAL */
- status = rte_eal_init(argc, argv);
- if (status < 0) {
- printf("Error: EAL initialization failed (%d)\n", status);
- return status;
- };
-
- /* Connectivity */
- conn = conn_init(&app.conn);
- if (conn == NULL) {
- printf("Error: Connectivity initialization failed (%d)\n",
- status);
- return status;
- };
-
- /* Mempool */
- status = mempool_init();
- if (status) {
- printf("Error: Mempool initialization failed (%d)\n", status);
- return status;
- }
-
- /* Link */
- status = link_init();
- if (status) {
- printf("Error: Link initialization failed (%d)\n", status);
- return status;
- }
-
- /* SWQ */
- status = swq_init();
- if (status) {
- printf("Error: SWQ initialization failed (%d)\n", status);
- return status;
- }
-
- /* Traffic Manager */
- status = tmgr_init();
- if (status) {
- printf("Error: TMGR initialization failed (%d)\n", status);
- return status;
- }
-
- /* TAP */
- status = tap_init();
- if (status) {
- printf("Error: TAP initialization failed (%d)\n", status);
- return status;
- }
-
- /* Sym Crypto */
- status = cryptodev_init();
- if (status) {
- printf("Error: Cryptodev initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Action */
- status = port_in_action_profile_init();
- if (status) {
- printf("Error: Input port action profile initialization failed (%d)\n", status);
- return status;
- }
-
- status = table_action_profile_init();
- if (status) {
- printf("Error: Action profile initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Pipeline */
- status = pipeline_init();
- if (status) {
- printf("Error: Pipeline initialization failed (%d)\n", status);
- return status;
- }
-
- /* Thread */
- status = thread_init();
- if (status) {
- printf("Error: Thread initialization failed (%d)\n", status);
- return status;
- }
-
- rte_eal_mp_remote_launch(
- thread_main,
- NULL,
- SKIP_MAIN);
-
- /* Script */
- if (app.script_name)
- cli_script_process(app.script_name,
- app.conn.msg_in_len_max,
- app.conn.msg_out_len_max);
-
- /* Dispatch loop */
- for ( ; ; ) {
- conn_poll_for_conn(conn);
-
- conn_poll_for_msg(conn);
- }
-}
diff --git a/examples/ip_pipeline/mempool.c b/examples/ip_pipeline/mempool.c
deleted file mode 100644
index f5d2a7d108..0000000000
--- a/examples/ip_pipeline/mempool.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-
-#include "mempool.h"
-
-#define BUFFER_SIZE_MIN (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-
-static struct mempool_list mempool_list;
-
-int
-mempool_init(void)
-{
- TAILQ_INIT(&mempool_list);
-
- return 0;
-}
-
-struct mempool *
-mempool_find(const char *name)
-{
- struct mempool *mempool;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(mempool, &mempool_list, node)
- if (strcmp(mempool->name, name) == 0)
- return mempool;
-
- return NULL;
-}
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params)
-{
- struct mempool *mempool;
- struct rte_mempool *m;
-
- /* Check input params */
- if ((name == NULL) ||
- mempool_find(name) ||
- (params == NULL) ||
- (params->buffer_size < BUFFER_SIZE_MIN) ||
- (params->pool_size == 0))
- return NULL;
-
- /* Resource create */
- m = rte_pktmbuf_pool_create(
- name,
- params->pool_size,
- params->cache_size,
- 0,
- params->buffer_size - sizeof(struct rte_mbuf),
- params->cpu_id);
-
- if (m == NULL)
- return NULL;
-
- /* Node allocation */
- mempool = calloc(1, sizeof(struct mempool));
- if (mempool == NULL) {
- rte_mempool_free(m);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(mempool->name, name, sizeof(mempool->name));
- mempool->m = m;
- mempool->buffer_size = params->buffer_size;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&mempool_list, mempool, node);
-
- return mempool;
-}
diff --git a/examples/ip_pipeline/mempool.h b/examples/ip_pipeline/mempool.h
deleted file mode 100644
index bd46a11ca0..0000000000
--- a/examples/ip_pipeline/mempool.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_MEMPOOL_H_
-#define _INCLUDE_MEMPOOL_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_mempool.h>
-
-#include "common.h"
-
-struct mempool {
- TAILQ_ENTRY(mempool) node;
- char name[NAME_SIZE];
- struct rte_mempool *m;
- uint32_t buffer_size;
-};
-
-TAILQ_HEAD(mempool_list, mempool);
-
-int
-mempool_init(void);
-
-struct mempool *
-mempool_find(const char *name);
-
-struct mempool_params {
- uint32_t buffer_size;
- uint32_t pool_size;
- uint32_t cache_size;
- uint32_t cpu_id;
-};
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params);
-
-#endif /* _INCLUDE_MEMPOOL_H_ */
diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build
deleted file mode 100644
index 68049157e4..0000000000
--- a/examples/ip_pipeline/meson.build
+++ /dev/null
@@ -1,30 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017-2018 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'
-
-build = cc.has_header('sys/epoll.h')
-if not build
- subdir_done()
-endif
-
-deps += ['pipeline', 'bus_pci']
-allow_experimental_apis = true
-sources = files(
- 'action.c',
- 'cli.c',
- 'conn.c',
- 'cryptodev.c',
- 'link.c',
- 'main.c',
- 'mempool.c',
- 'parser.c',
- 'pipeline.c',
- 'swq.c',
- 'tap.c',
- 'thread.c',
- 'tmgr.c',
-)
diff --git a/examples/ip_pipeline/parser.c b/examples/ip_pipeline/parser.c
deleted file mode 100644
index 8baa70e1f4..0000000000
--- a/examples/ip_pipeline/parser.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation.
- * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
- * All rights reserved.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <libgen.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include <rte_errno.h>
-#include <rte_string_fns.h>
-
-#include "parser.h"
-
-static uint32_t
-get_hex_val(char c)
-{
- switch (c) {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- return c - '0';
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- return c - 'A' + 10;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- return c - 'a' + 10;
- default:
- return 0;
- }
-}
-
-int
-parser_read_arg_bool(const char *p)
-{
- p = rte_str_skip_leading_spaces(p);
- int result = -EINVAL;
-
- if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
- ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
- p += 3;
- result = 1;
- }
-
- if (((p[0] == 'o') && (p[1] == 'n')) ||
- ((p[0] == 'O') && (p[1] == 'N'))) {
- p += 2;
- result = 1;
- }
-
- if (((p[0] == 'n') && (p[1] == 'o')) ||
- ((p[0] == 'N') && (p[1] == 'O'))) {
- p += 2;
- result = 0;
- }
-
- if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
- ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
- p += 3;
- result = 0;
- }
-
- p = rte_str_skip_leading_spaces(p);
-
- if (p[0] != '\0')
- return -EINVAL;
-
- return result;
-}
-
-int
-parser_read_uint64(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
- if (!isdigit(*p))
- return -EINVAL;
-
- val = strtoul(p, &next, 10);
- if (p == next)
- return -EINVAL;
-
- p = next;
- switch (*p) {
- case 'T':
- val *= 1024ULL;
- /* fall through */
- case 'G':
- val *= 1024ULL;
- /* fall through */
- case 'M':
- val *= 1024ULL;
- /* fall through */
- case 'k':
- case 'K':
- val *= 1024ULL;
- p++;
- break;
- }
-
- p = rte_str_skip_leading_spaces(p);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint64_hex(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
-
- val = strtoul(p, &next, 16);
- if (p == next)
- return -EINVAL;
-
- p = rte_str_skip_leading_spaces(next);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32_hex(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16_hex(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8_hex(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
-{
- uint32_t i;
-
- if ((string == NULL) ||
- (tokens == NULL) ||
- (*n_tokens < 1))
- return -EINVAL;
-
- for (i = 0; i < *n_tokens; i++) {
- tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
- if (tokens[i] == NULL)
- break;
- }
-
- if ((i == *n_tokens) &&
- (NULL != strtok_r(string, PARSE_DELIMITER, &string)))
- return -E2BIG;
-
- *n_tokens = i;
- return 0;
-}
-
-int
-parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
-{
- char *c;
- uint32_t len, i;
-
- /* Check input parameters */
- if ((src == NULL) ||
- (dst == NULL) ||
- (size == NULL) ||
- (*size == 0))
- return -1;
-
- len = strlen(src);
- if (((len & 3) != 0) ||
- (len > (*size) * 2))
- return -1;
- *size = len / 2;
-
- for (c = src; *c != 0; c++) {
- if ((((*c) >= '0') && ((*c) <= '9')) ||
- (((*c) >= 'A') && ((*c) <= 'F')) ||
- (((*c) >= 'a') && ((*c) <= 'f')))
- continue;
-
- return -1;
- }
-
- /* Convert chars to bytes */
- for (i = 0; i < *size; i++)
- dst[i] = get_hex_val(src[2 * i]) * 16 +
- get_hex_val(src[2 * i + 1]);
-
- return 0;
-}
-
-int
-parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels)
-{
- uint32_t n_max_labels = *n_labels, count = 0;
-
- /* Check for void list of labels */
- if (strcmp(string, "<void>") == 0) {
- *n_labels = 0;
- return 0;
- }
-
- /* At least one label should be present */
- for ( ; (*string != '\0'); ) {
- char *next;
- int value;
-
- if (count >= n_max_labels)
- return -1;
-
- if (count > 0) {
- if (string[0] != ':')
- return -1;
-
- string++;
- }
-
- value = strtol(string, &next, 10);
- if (next == string)
- return -1;
- string = next;
-
- labels[count++] = (uint32_t) value;
- }
-
- *n_labels = count;
- return 0;
-}
-
-static struct rte_ether_addr *
-my_ether_aton(const char *a)
-{
- int i;
- char *end;
- unsigned long o[RTE_ETHER_ADDR_LEN];
- static struct rte_ether_addr ether_addr;
-
- i = 0;
- do {
- errno = 0;
- o[i] = strtoul(a, &end, 16);
- if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
- return NULL;
- a = end + 1;
- } while (++i != RTE_DIM(o) && end[0] != 0);
-
- /* Junk at the end of line */
- if (end[0] != 0)
- return NULL;
-
- /* Support the format XX:XX:XX:XX:XX:XX */
- if (i == RTE_ETHER_ADDR_LEN) {
- while (i-- != 0) {
- if (o[i] > UINT8_MAX)
- return NULL;
- ether_addr.addr_bytes[i] = (uint8_t)o[i];
- }
- /* Support the format XXXX:XXXX:XXXX */
- } else if (i == RTE_ETHER_ADDR_LEN / 2) {
- while (i-- != 0) {
- if (o[i] > UINT16_MAX)
- return NULL;
- ether_addr.addr_bytes[i * 2] = (uint8_t)(o[i] >> 8);
- ether_addr.addr_bytes[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
- }
- /* unknown format */
- } else
- return NULL;
-
- return (struct rte_ether_addr *)ðer_addr;
-}
-
-int
-parse_ipv4_addr(const char *token, struct in_addr *ipv4)
-{
- if (strlen(token) >= INET_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET, token, ipv4) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6)
-{
- if (strlen(token) >= INET6_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET6, token, ipv6) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_mac_addr(const char *token, struct rte_ether_addr *addr)
-{
- struct rte_ether_addr *tmp;
-
- tmp = my_ether_aton(token);
- if (tmp == NULL)
- return -1;
-
- *addr = *tmp;
- return 0;
-}
-
-int
-parse_cpu_core(const char *entry,
- struct cpu_core_params *p)
-{
- size_t num_len;
- char num[8];
-
- uint32_t s = 0, c = 0, h = 0, val;
- uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
- const char *next = rte_str_skip_leading_spaces(entry);
- char type;
-
- if (p == NULL)
- return -EINVAL;
-
- /* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
- while (*next != '\0') {
- /* If everything parsed nothing should left */
- if (s_parsed && c_parsed && h_parsed)
- return -EINVAL;
-
- type = *next;
- switch (type) {
- case 's':
- case 'S':
- if (s_parsed || c_parsed || h_parsed)
- return -EINVAL;
- s_parsed = 1;
- next++;
- break;
- case 'c':
- case 'C':
- if (c_parsed || h_parsed)
- return -EINVAL;
- c_parsed = 1;
- next++;
- break;
- case 'h':
- case 'H':
- if (h_parsed)
- return -EINVAL;
- h_parsed = 1;
- next++;
- break;
- default:
- /* If it start from digit it must be only core id. */
- if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
- return -EINVAL;
-
- type = 'C';
- }
-
- for (num_len = 0; *next != '\0'; next++, num_len++) {
- if (num_len == RTE_DIM(num))
- return -EINVAL;
-
- if (!isdigit(*next))
- break;
-
- num[num_len] = *next;
- }
-
- if (num_len == 0 && type != 'h' && type != 'H')
- return -EINVAL;
-
- if (num_len != 0 && (type == 'h' || type == 'H'))
- return -EINVAL;
-
- num[num_len] = '\0';
- val = strtol(num, NULL, 10);
-
- h = 0;
- switch (type) {
- case 's':
- case 'S':
- s = val;
- break;
- case 'c':
- case 'C':
- c = val;
- break;
- case 'h':
- case 'H':
- h = 1;
- break;
- }
- }
-
- p->socket_id = s;
- p->core_id = c;
- p->thread_id = h;
- return 0;
-}
diff --git a/examples/ip_pipeline/parser.h b/examples/ip_pipeline/parser.h
deleted file mode 100644
index c8f0187d71..0000000000
--- a/examples/ip_pipeline/parser.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_PARSER_H__
-#define __INCLUDE_PARSER_H__
-
-#include <ctype.h>
-#include <stdint.h>
-
-#include <rte_ip.h>
-#include <rte_ether.h>
-
-#define PARSE_DELIMITER " \f\n\r\t\v"
-
-static inline size_t
-skip_digits(const char *src)
-{
- size_t i;
-
- for (i = 0; isdigit(src[i]); i++)
- ;
-
- return i;
-}
-
-int parser_read_arg_bool(const char *p);
-
-int parser_read_uint64(uint64_t *value, const char *p);
-int parser_read_uint32(uint32_t *value, const char *p);
-int parser_read_uint16(uint16_t *value, const char *p);
-int parser_read_uint8(uint8_t *value, const char *p);
-
-int parser_read_uint64_hex(uint64_t *value, const char *p);
-int parser_read_uint32_hex(uint32_t *value, const char *p);
-int parser_read_uint16_hex(uint16_t *value, const char *p);
-int parser_read_uint8_hex(uint8_t *value, const char *p);
-
-int parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
-
-int parse_ipv4_addr(const char *token, struct in_addr *ipv4);
-int parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6);
-int parse_mac_addr(const char *token, struct rte_ether_addr *addr);
-int parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels);
-
-struct cpu_core_params {
- uint32_t socket_id;
- uint32_t core_id;
- uint32_t thread_id;
-};
-
-int parse_cpu_core(const char *entry, struct cpu_core_params *p);
-
-int parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens);
-
-#endif
diff --git a/examples/ip_pipeline/pipeline.c b/examples/ip_pipeline/pipeline.c
deleted file mode 100644
index 792aab0059..0000000000
--- a/examples/ip_pipeline/pipeline.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-
-#include <rte_string_fns.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_ring.h>
-#include <rte_port_source_sink.h>
-#include <rte_port_fd.h>
-#include <rte_port_sched.h>
-#include <rte_port_sym_crypto.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_func.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_stub.h>
-
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "tap.h"
-#include "tmgr.h"
-#include "swq.h"
-#include "cryptodev.h"
-
-#ifndef PIPELINE_MSGQ_SIZE
-#define PIPELINE_MSGQ_SIZE 64
-#endif
-
-#ifndef TABLE_LPM_NUMBER_TBL8
-#define TABLE_LPM_NUMBER_TBL8 256
-#endif
-
-static struct pipeline_list pipeline_list;
-
-int
-pipeline_init(void)
-{
- TAILQ_INIT(&pipeline_list);
-
- return 0;
-}
-
-struct pipeline *
-pipeline_find(const char *name)
-{
- struct pipeline *pipeline;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(pipeline, &pipeline_list, node)
- if (strcmp(name, pipeline->name) == 0)
- return pipeline;
-
- return NULL;
-}
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params)
-{
- char msgq_name[NAME_MAX];
- struct rte_pipeline_params pp;
- struct pipeline *pipeline;
- struct rte_pipeline *p;
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- /* Check input params */
- if ((name == NULL) ||
- pipeline_find(name) ||
- (params == NULL) ||
- (params->timer_period_ms == 0))
- return NULL;
-
- /* Resource create */
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-REQ", name);
-
- msgq_req = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_req == NULL)
- return NULL;
-
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-RSP", name);
-
- msgq_rsp = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_rsp == NULL) {
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- pp.name = name;
- pp.socket_id = (int) params->cpu_id;
- pp.offset_port_id = params->offset_port_id;
-
- p = rte_pipeline_create(&pp);
- if (p == NULL) {
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node allocation */
- pipeline = calloc(1, sizeof(struct pipeline));
- if (pipeline == NULL) {
- rte_pipeline_free(p);
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(pipeline->name, name, sizeof(pipeline->name));
- pipeline->p = p;
- pipeline->n_ports_in = 0;
- pipeline->n_ports_out = 0;
- pipeline->n_tables = 0;
- pipeline->msgq_req = msgq_req;
- pipeline->msgq_rsp = msgq_rsp;
- pipeline->timer_period_ms = params->timer_period_ms;
- pipeline->enabled = 0;
- pipeline->cpu_id = params->cpu_id;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&pipeline_list, pipeline, node);
-
- return pipeline;
-}
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled)
-{
- struct rte_pipeline_port_in_params p;
-
- union {
- struct rte_port_ethdev_reader_params ethdev;
- struct rte_port_ring_reader_params ring;
- struct rte_port_sched_reader_params sched;
- struct rte_port_fd_reader_params fd;
- struct rte_port_source_params source;
- struct rte_port_sym_crypto_reader_params sym_crypto;
- } pp;
-
- struct pipeline *pipeline;
- struct port_in *port_in;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *action;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = port_in_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- switch (params->type) {
- case PORT_IN_RXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->rxq.queue_id >= link->n_rxq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->rxq.queue_id;
-
- p.ops = &rte_port_ethdev_reader_ops;
- p.arg_create = &pp.ethdev;
- break;
- }
-
- case PORT_IN_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
-
- p.ops = &rte_port_ring_reader_ops;
- p.arg_create = &pp.ring;
- break;
- }
-
- case PORT_IN_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
-
- p.ops = &rte_port_sched_reader_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_IN_TAP:
- {
- struct tap *tap;
- struct mempool *mempool;
-
- tap = tap_find(params->dev_name);
- mempool = mempool_find(params->tap.mempool_name);
- if ((tap == NULL) || (mempool == NULL))
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.mempool = mempool->m;
- pp.fd.mtu = params->tap.mtu;
-
- p.ops = &rte_port_fd_reader_ops;
- p.arg_create = &pp.fd;
- break;
- }
-
-
- case PORT_IN_SOURCE:
- {
- struct mempool *mempool;
-
- mempool = mempool_find(params->source.mempool_name);
- if (mempool == NULL)
- return -1;
-
- pp.source.mempool = mempool->m;
- pp.source.file_name = params->source.file_name;
- pp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;
-
- p.ops = &rte_port_source_ops;
- p.arg_create = &pp.source;
- break;
- }
-
- case PORT_IN_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->rxq.queue_id > cryptodev->n_queues - 1)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.f_callback = params->cryptodev.f_callback;
- pp.sym_crypto.arg_callback = params->cryptodev.arg_callback;
- p.ops = &rte_port_sym_crypto_reader_ops;
- p.arg_create = &pp.sym_crypto;
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.burst_size = params->burst_size;
-
- /* Resource create */
- action = NULL;
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_port_in_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_port_in_action_params_get(
- action,
- &p);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
- }
-
- status = rte_pipeline_port_in_create(pipeline->p,
- &p,
- &port_id);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
-
- if (enabled)
- rte_pipeline_port_in_enable(pipeline->p, port_id);
-
- /* Pipeline */
- port_in = &pipeline->port_in[pipeline->n_ports_in];
- memcpy(&port_in->params, params, sizeof(*params));
- port_in->ap = ap;
- port_in->a = action;
- pipeline->n_ports_in++;
-
- return 0;
-}
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct pipeline *pipeline;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (port_id >= pipeline->n_ports_in) ||
- (table_id >= pipeline->n_tables))
- return -1;
-
- /* Resource */
- status = rte_pipeline_port_in_connect_to_table(pipeline->p,
- port_id,
- table_id);
-
- return status;
-
-}
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params)
-{
- struct rte_pipeline_port_out_params p;
-
- union {
- struct rte_port_ethdev_writer_params ethdev;
- struct rte_port_ring_writer_params ring;
- struct rte_port_sched_writer_params sched;
- struct rte_port_fd_writer_params fd;
- struct rte_port_sink_params sink;
- struct rte_port_sym_crypto_writer_params sym_crypto;
- } pp;
-
- union {
- struct rte_port_ethdev_writer_nodrop_params ethdev;
- struct rte_port_ring_writer_nodrop_params ring;
- struct rte_port_fd_writer_nodrop_params fd;
- struct rte_port_sym_crypto_writer_nodrop_params sym_crypto;
- } pp_nodrop;
-
- struct pipeline *pipeline;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
- memset(&pp_nodrop, 0, sizeof(pp_nodrop));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- switch (params->type) {
- case PORT_OUT_TXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->txq.queue_id >= link->n_txq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->txq.queue_id;
- pp.ethdev.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ethdev.port_id = link->port_id;
- pp_nodrop.ethdev.queue_id = params->txq.queue_id;
- pp_nodrop.ethdev.tx_burst_sz = params->burst_size;
- pp_nodrop.ethdev.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ethdev_writer_ops;
- p.arg_create = &pp.ethdev;
- } else {
- p.ops = &rte_port_ethdev_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ethdev;
- }
- break;
- }
-
- case PORT_OUT_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
- pp.ring.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ring.ring = swq->r;
- pp_nodrop.ring.tx_burst_sz = params->burst_size;
- pp_nodrop.ring.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ring_writer_ops;
- p.arg_create = &pp.ring;
- } else {
- p.ops = &rte_port_ring_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ring;
- }
- break;
- }
-
- case PORT_OUT_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
- pp.sched.tx_burst_sz = params->burst_size;
-
- p.ops = &rte_port_sched_writer_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_OUT_TAP:
- {
- struct tap *tap;
-
- tap = tap_find(params->dev_name);
- if (tap == NULL)
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.tx_burst_sz = params->burst_size;
-
- pp_nodrop.fd.fd = tap->fd;
- pp_nodrop.fd.tx_burst_sz = params->burst_size;
- pp_nodrop.fd.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_fd_writer_ops;
- p.arg_create = &pp.fd;
- } else {
- p.ops = &rte_port_fd_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.fd;
- }
- break;
- }
-
-
- case PORT_OUT_SINK:
- {
- pp.sink.file_name = params->sink.file_name;
- pp.sink.max_n_pkts = params->sink.max_n_pkts;
-
- p.ops = &rte_port_sink_ops;
- p.arg_create = &pp.sink;
- break;
- }
-
- case PORT_OUT_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->cryptodev.queue_id >= cryptodev->n_queues)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.tx_burst_sz = params->burst_size;
- pp.sym_crypto.crypto_op_offset = params->cryptodev.op_offset;
-
- pp_nodrop.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp_nodrop.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp_nodrop.sym_crypto.tx_burst_sz = params->burst_size;
- pp_nodrop.sym_crypto.n_retries = params->retry;
- pp_nodrop.sym_crypto.crypto_op_offset =
- params->cryptodev.op_offset;
-
- if (params->retry == 0) {
- p.ops = &rte_port_sym_crypto_writer_ops;
- p.arg_create = &pp.sym_crypto;
- } else {
- p.ops = &rte_port_sym_crypto_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.sym_crypto;
- }
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- /* Resource create */
- status = rte_pipeline_port_out_create(pipeline->p,
- &p,
- &port_id);
-
- if (status)
- return -1;
-
- /* Pipeline */
- pipeline->n_ports_out++;
-
- return 0;
-}
-
-static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
-
- /* Source IP address (IPv4) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv4_hdr, src_addr),
- },
-
- /* Destination IP address (IPv4) */
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv4_hdr, dst_addr),
- },
-
- /* Source Port */
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 3,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 4,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv6_hdr, proto),
- },
-
- /* Source IP address (IPv6) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[0]),
- },
-
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[4]),
- },
-
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 3,
- .input_index = 3,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[8]),
- },
-
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 4,
- .input_index = 4,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[12]),
- },
-
- /* Destination IP address (IPv6) */
- [5] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 5,
- .input_index = 5,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[0]),
- },
-
- [6] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 6,
- .input_index = 6,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[4]),
- },
-
- [7] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 7,
- .input_index = 7,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[8]),
- },
-
- [8] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 8,
- .input_index = 8,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[12]),
- },
-
- /* Source Port */
- [9] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 9,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [10] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 10,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params)
-{
- char name[NAME_MAX];
- struct rte_pipeline_table_params p;
-
- union {
- struct rte_table_acl_params acl;
- struct rte_table_array_params array;
- struct rte_table_hash_params hash;
- struct rte_table_lpm_params lpm;
- struct rte_table_lpm_ipv6_params lpm_ipv6;
- } pp;
-
- struct pipeline *pipeline;
- struct table *table;
- struct table_action_profile *ap;
- struct rte_table_action *action;
- uint32_t table_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX))
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = table_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- snprintf(name, NAME_MAX, "%s_table%u",
- pipeline_name, pipeline->n_tables);
-
- switch (params->match_type) {
- case TABLE_ACL:
- {
- uint32_t ip_header_offset = params->match.acl.ip_header_offset -
- (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
- uint32_t i;
-
- if (params->match.acl.n_rules == 0)
- return -1;
-
- pp.acl.name = name;
- pp.acl.n_rules = params->match.acl.n_rules;
- if (params->match.acl.ip_version) {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv4,
- sizeof(table_acl_field_format_ipv4));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv4);
- } else {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv6,
- sizeof(table_acl_field_format_ipv6));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv6);
- }
-
- for (i = 0; i < pp.acl.n_rule_fields; i++)
- pp.acl.field_format[i].offset += ip_header_offset;
-
- p.ops = &rte_table_acl_ops;
- p.arg_create = &pp.acl;
- break;
- }
-
- case TABLE_ARRAY:
- {
- if (params->match.array.n_keys == 0)
- return -1;
-
- pp.array.n_entries = params->match.array.n_keys;
- pp.array.offset = params->match.array.key_offset;
-
- p.ops = &rte_table_array_ops;
- p.arg_create = &pp.array;
- break;
- }
-
- case TABLE_HASH:
- {
- struct rte_table_ops *ops;
- rte_table_hash_op_hash f_hash;
-
- if (params->match.hash.n_keys == 0)
- return -1;
-
- switch (params->match.hash.key_size) {
- case 8:
- f_hash = rte_table_hash_crc_key8;
- break;
- case 16:
- f_hash = rte_table_hash_crc_key16;
- break;
- case 24:
- f_hash = rte_table_hash_crc_key24;
- break;
- case 32:
- f_hash = rte_table_hash_crc_key32;
- break;
- case 40:
- f_hash = rte_table_hash_crc_key40;
- break;
- case 48:
- f_hash = rte_table_hash_crc_key48;
- break;
- case 56:
- f_hash = rte_table_hash_crc_key56;
- break;
- case 64:
- f_hash = rte_table_hash_crc_key64;
- break;
- default:
- return -1;
- }
-
- pp.hash.name = name;
- pp.hash.key_size = params->match.hash.key_size;
- pp.hash.key_offset = params->match.hash.key_offset;
- pp.hash.key_mask = params->match.hash.key_mask;
- pp.hash.n_keys = params->match.hash.n_keys;
- pp.hash.n_buckets = params->match.hash.n_buckets;
- pp.hash.f_hash = f_hash;
- pp.hash.seed = 0;
-
- if (params->match.hash.extendable_bucket)
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_ext_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_ext_ops;
- break;
- default:
- ops = &rte_table_hash_ext_ops;
- }
- else
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_lru_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_lru_ops;
- break;
- default:
- ops = &rte_table_hash_lru_ops;
- }
-
- p.ops = ops;
- p.arg_create = &pp.hash;
- break;
- }
-
- case TABLE_LPM:
- {
- if (params->match.lpm.n_rules == 0)
- return -1;
-
- switch (params->match.lpm.key_size) {
- case 4:
- {
- pp.lpm.name = name;
- pp.lpm.n_rules = params->match.lpm.n_rules;
- pp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm.flags = 0;
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ops;
- p.arg_create = &pp.lpm;
- break;
- }
-
- case 16:
- {
- pp.lpm_ipv6.name = name;
- pp.lpm_ipv6.n_rules = params->match.lpm.n_rules;
- pp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm_ipv6.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ipv6_ops;
- p.arg_create = &pp.lpm_ipv6;
- break;
- }
-
- default:
- return -1;
- }
-
- break;
- }
-
- case TABLE_STUB:
- {
- p.ops = &rte_table_stub_ops;
- p.arg_create = NULL;
- break;
- }
-
- default:
- return -1;
- }
-
- /* Resource create */
- action = NULL;
- p.f_action_hit = NULL;
- p.f_action_miss = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_table_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_table_action_table_params_get(
- action,
- &p);
- if (status ||
- ((p.action_data_size +
- sizeof(struct rte_pipeline_table_entry)) >
- TABLE_RULE_ACTION_SIZE_MAX)) {
- rte_table_action_free(action);
- return -1;
- }
- }
-
- if (params->match_type == TABLE_LPM) {
- if (params->match.lpm.key_size == 4)
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
-
- if (params->match.lpm.key_size == 16)
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- }
-
- status = rte_pipeline_table_create(pipeline->p,
- &p,
- &table_id);
- if (status) {
- rte_table_action_free(action);
- return -1;
- }
-
- /* Pipeline */
- table = &pipeline->table[pipeline->n_tables];
- memcpy(&table->params, params, sizeof(*params));
- table->ap = ap;
- table->a = action;
- TAILQ_INIT(&table->rules);
- table->rule_default = NULL;
-
- pipeline->n_tables++;
-
- return 0;
-}
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- TAILQ_FOREACH(rule, &table->rules, node)
- if (memcmp(&rule->match, match, sizeof(*match)) == 0)
- return rule;
-
- return NULL;
-}
-
-void
-table_rule_add(struct table *table,
- struct table_rule *new_rule)
-{
- struct table_rule *existing_rule;
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
-}
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules)
-{
- uint32_t i;
-
- for (i = 0; i < n_rules; i++) {
- struct table_rule *existing_rule, *new_rule;
-
- new_rule = TAILQ_FIRST(list);
- if (new_rule == NULL)
- break;
-
- TAILQ_REMOVE(list, new_rule, node);
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
- }
-}
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return;
-
- TAILQ_REMOVE(&table->rules, rule, node);
- free(rule);
-}
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule)
-{
- free(table->rule_default);
- table->rule_default = rule;
-}
-
-void
-table_rule_default_delete(struct table *table)
-{
- free(table->rule_default);
- table->rule_default = NULL;
-}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
deleted file mode 100644
index 89696480fc..0000000000
--- a/examples/ip_pipeline/pipeline.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_PIPELINE_H_
-#define _INCLUDE_PIPELINE_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_pipeline.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-#include "action.h"
-
-struct pipeline_params {
- uint32_t timer_period_ms;
- uint32_t offset_port_id;
- uint32_t cpu_id;
-};
-
-enum port_in_type {
- PORT_IN_RXQ,
- PORT_IN_SWQ,
- PORT_IN_TMGR,
- PORT_IN_TAP,
- PORT_IN_SOURCE,
- PORT_IN_CRYPTODEV,
-};
-
-struct port_in_params {
- /* Read */
- enum port_in_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } rxq;
-
- struct {
- const char *mempool_name;
- uint32_t mtu;
- } tap;
-
- struct {
- const char *mempool_name;
- const char *file_name;
- uint32_t n_bytes_per_pkt;
- } source;
-
- struct {
- uint16_t queue_id;
- void *f_callback;
- void *arg_callback;
- } cryptodev;
- };
- uint32_t burst_size;
-
- /* Action */
- const char *action_profile_name;
-};
-
-enum port_out_type {
- PORT_OUT_TXQ,
- PORT_OUT_SWQ,
- PORT_OUT_TMGR,
- PORT_OUT_TAP,
- PORT_OUT_SINK,
- PORT_OUT_CRYPTODEV,
-};
-
-struct port_out_params {
- enum port_out_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } txq;
-
- struct {
- const char *file_name;
- uint32_t max_n_pkts;
- } sink;
-
- struct {
- uint16_t queue_id;
- uint32_t op_offset;
- } cryptodev;
- };
- uint32_t burst_size;
- int retry;
- uint32_t n_retries;
-};
-
-enum table_type {
- TABLE_ACL,
- TABLE_ARRAY,
- TABLE_HASH,
- TABLE_LPM,
- TABLE_STUB,
-};
-
-struct table_acl_params {
- uint32_t n_rules;
- uint32_t ip_header_offset;
- int ip_version;
-};
-
-struct table_array_params {
- uint32_t n_keys;
- uint32_t key_offset;
-};
-
-struct table_hash_params {
- uint32_t n_keys;
- uint32_t key_offset;
- uint32_t key_size;
- uint8_t *key_mask;
- uint32_t n_buckets;
- int extendable_bucket;
-};
-
-struct table_lpm_params {
- uint32_t n_rules;
- uint32_t key_offset;
- uint32_t key_size;
-};
-
-struct table_params {
- /* Match */
- enum table_type match_type;
- union {
- struct table_acl_params acl;
- struct table_array_params array;
- struct table_hash_params hash;
- struct table_lpm_params lpm;
- } match;
-
- /* Action */
- const char *action_profile_name;
-};
-
-struct table_rule;
-
-TAILQ_HEAD(table_rule_list, table_rule);
-
-struct port_in {
- struct port_in_params params;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *a;
-};
-
-struct table {
- struct table_params params;
- struct table_action_profile *ap;
- struct rte_table_action *a;
- struct table_rule_list rules;
- struct table_rule *rule_default;
-};
-
-struct pipeline {
- TAILQ_ENTRY(pipeline) node;
- char name[NAME_SIZE];
-
- struct rte_pipeline *p;
- struct port_in port_in[RTE_PIPELINE_PORT_IN_MAX];
- struct table table[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
-
- int enabled;
- uint32_t thread_id;
- uint32_t cpu_id;
-};
-
-TAILQ_HEAD(pipeline_list, pipeline);
-
-int
-pipeline_init(void);
-
-struct pipeline *
-pipeline_find(const char *name);
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params);
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled);
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id);
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params);
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params);
-
-struct table_rule_match_acl {
- int ip_version;
-
- union {
- struct {
- uint32_t sa;
- uint32_t da;
- } ipv4;
-
- struct {
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- } ipv6;
- };
-
- uint32_t sa_depth;
- uint32_t da_depth;
- uint16_t sp0;
- uint16_t sp1;
- uint16_t dp0;
- uint16_t dp1;
- uint8_t proto;
- uint8_t proto_mask;
- uint32_t priority;
-};
-
-struct table_rule_match_array {
- uint32_t pos;
-};
-
-#ifndef TABLE_RULE_MATCH_SIZE_MAX
-#define TABLE_RULE_MATCH_SIZE_MAX 256
-#endif
-
-#ifndef TABLE_RULE_ACTION_SIZE_MAX
-#define TABLE_RULE_ACTION_SIZE_MAX 2048
-#endif
-
-struct table_rule_match_hash {
- uint8_t key[TABLE_RULE_MATCH_SIZE_MAX];
-};
-
-struct table_rule_match_lpm {
- int ip_version;
-
- union {
- uint32_t ipv4;
- struct rte_ipv6_addr ipv6;
- };
-
- uint8_t depth;
-};
-
-struct table_rule_match {
- enum table_type match_type;
-
- union {
- struct table_rule_match_acl acl;
- struct table_rule_match_array array;
- struct table_rule_match_hash hash;
- struct table_rule_match_lpm lpm;
- } match;
-};
-
-#ifndef SYM_CRYPTO_MAX_KEY_SIZE
-#define SYM_CRYPTO_MAX_KEY_SIZE (256)
-#endif
-
-struct table_rule_action {
- uint64_t action_mask;
- struct rte_table_action_fwd_params fwd;
- struct rte_table_action_lb_params lb;
- struct rte_table_action_mtr_params mtr;
- struct rte_table_action_tm_params tm;
- struct rte_table_action_encap_params encap;
- struct rte_table_action_nat_params nat;
- struct rte_table_action_ttl_params ttl;
- struct rte_table_action_stats_params stats;
- struct rte_table_action_time_params time;
- struct rte_table_action_sym_crypto_params sym_crypto;
- uint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];
- struct rte_table_action_tag_params tag;
- struct rte_table_action_decap_params decap;
-
-};
-
-struct table_rule {
- TAILQ_ENTRY(table_rule) node;
- struct table_rule_match match;
- struct table_rule_action action;
- void *data;
-};
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear);
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear);
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear);
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added);
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match);
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id);
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id);
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table);
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp);
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules);
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_default_delete(struct table *table);
-
-#endif /* _INCLUDE_PIPELINE_H_ */
diff --git a/examples/ip_pipeline/swq.c b/examples/ip_pipeline/swq.c
deleted file mode 100644
index 7e54a1dbfe..0000000000
--- a/examples/ip_pipeline/swq.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-
-#include "swq.h"
-
-static struct swq_list swq_list;
-
-int
-swq_init(void)
-{
- TAILQ_INIT(&swq_list);
-
- return 0;
-}
-
-struct swq *
-swq_find(const char *name)
-{
- struct swq *swq;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(swq, &swq_list, node)
- if (strcmp(swq->name, name) == 0)
- return swq;
-
- return NULL;
-}
-
-struct swq *
-swq_create(const char *name, struct swq_params *params)
-{
- struct swq *swq;
- struct rte_ring *r;
- unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ;
-
- /* Check input params */
- if ((name == NULL) ||
- swq_find(name) ||
- (params == NULL) ||
- (params->size == 0))
- return NULL;
-
- /* Resource create */
- r = rte_ring_create(
- name,
- params->size,
- params->cpu_id,
- flags);
-
- if (r == NULL)
- return NULL;
-
- /* Node allocation */
- swq = calloc(1, sizeof(struct swq));
- if (swq == NULL) {
- rte_ring_free(r);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(swq->name, name, sizeof(swq->name));
- swq->r = r;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&swq_list, swq, node);
-
- return swq;
-}
diff --git a/examples/ip_pipeline/swq.h b/examples/ip_pipeline/swq.h
deleted file mode 100644
index c8440ee3cd..0000000000
--- a/examples/ip_pipeline/swq.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SWQ_H_
-#define _INCLUDE_SWQ_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_ring.h>
-
-#include "common.h"
-
-struct swq {
- TAILQ_ENTRY(swq) node;
- char name[NAME_SIZE];
- struct rte_ring *r;
-};
-
-TAILQ_HEAD(swq_list, swq);
-
-int
-swq_init(void);
-
-struct swq *
-swq_find(const char *name);
-
-struct swq_params {
- uint32_t size;
- uint32_t cpu_id;
-};
-
-struct swq *
-swq_create(const char *name, struct swq_params *params);
-
-#endif /* _INCLUDE_SWQ_H_ */
diff --git a/examples/ip_pipeline/tap.c b/examples/ip_pipeline/tap.c
deleted file mode 100644
index adae640c1e..0000000000
--- a/examples/ip_pipeline/tap.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <netinet/in.h>
-#ifdef RTE_EXEC_ENV_LINUX
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <rte_string_fns.h>
-
-#include "tap.h"
-
-#define TAP_DEV "/dev/net/tun"
-
-static struct tap_list tap_list;
-
-int
-tap_init(void)
-{
- TAILQ_INIT(&tap_list);
-
- return 0;
-}
-
-struct tap *
-tap_find(const char *name)
-{
- struct tap *tap;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tap, &tap_list, node)
- if (strcmp(tap->name, name) == 0)
- return tap;
-
- return NULL;
-}
-
-#ifndef RTE_EXEC_ENV_LINUX
-
-struct tap *
-tap_create(const char *name __rte_unused)
-{
- return NULL;
-}
-
-#else
-
-struct tap *
-tap_create(const char *name)
-{
- struct tap *tap;
- struct ifreq ifr;
- int fd, status;
-
- /* Check input params */
- if ((name == NULL) ||
- tap_find(name))
- return NULL;
-
- /* Resource create */
- fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
- if (fd < 0)
- return NULL;
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
- strlcpy(ifr.ifr_name, name, IFNAMSIZ);
-
- status = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (status < 0) {
- close(fd);
- return NULL;
- }
-
- /* Node allocation */
- tap = calloc(1, sizeof(struct tap));
- if (tap == NULL) {
- close(fd);
- return NULL;
- }
- /* Node fill in */
- strlcpy(tap->name, name, sizeof(tap->name));
- tap->fd = fd;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tap_list, tap, node);
-
- return tap;
-}
-
-#endif
diff --git a/examples/ip_pipeline/tap.h b/examples/ip_pipeline/tap.h
deleted file mode 100644
index 0dce72fe3c..0000000000
--- a/examples/ip_pipeline/tap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TAP_H_
-#define _INCLUDE_TAP_H_
-
-#include <sys/queue.h>
-
-#include "common.h"
-
-struct tap {
- TAILQ_ENTRY(tap) node;
- char name[NAME_SIZE];
- int fd;
-};
-
-TAILQ_HEAD(tap_list, tap);
-
-int
-tap_init(void);
-
-struct tap *
-tap_find(const char *name);
-
-struct tap *
-tap_create(const char *name);
-
-#endif /* _INCLUDE_TAP_H_ */
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
deleted file mode 100644
index 0a44bddd90..0000000000
--- a/examples/ip_pipeline/thread.c
+++ /dev/null
@@ -1,3137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_lcore.h>
-#include <rte_ring.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-
-#include "common.h"
-#include "thread.h"
-#include "pipeline.h"
-
-#ifndef THREAD_PIPELINES_MAX
-#define THREAD_PIPELINES_MAX 256
-#endif
-
-#ifndef THREAD_MSGQ_SIZE
-#define THREAD_MSGQ_SIZE 64
-#endif
-
-#ifndef THREAD_TIMER_PERIOD_MS
-#define THREAD_TIMER_PERIOD_MS 100
-#endif
-
-/**
- * Main thread: data plane thread context
- */
-struct thread {
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- uint32_t enabled;
-};
-
-static struct thread thread[RTE_MAX_LCORE];
-
-/**
- * Data plane threads: context
- */
-struct table_data {
- struct rte_table_action *a;
-};
-
-struct pipeline_data {
- struct rte_pipeline *p;
- struct table_data table_data[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
-
- uint8_t buffer[TABLE_RULE_ACTION_SIZE_MAX];
-};
-
-struct __rte_cache_aligned thread_data {
- struct rte_pipeline *p[THREAD_PIPELINES_MAX];
- uint32_t n_pipelines;
-
- struct pipeline_data pipeline_data[THREAD_PIPELINES_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
- uint64_t time_next_min;
-};
-
-static struct thread_data thread_data[RTE_MAX_LCORE];
-
-/**
- * Main thread: data plane thread init
- */
-static void
-thread_free(void)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- struct thread *t = &thread[i];
-
- if (!rte_lcore_is_enabled(i))
- continue;
-
- /* MSGQs */
- rte_ring_free(t->msgq_req);
-
- rte_ring_free(t->msgq_rsp);
- }
-}
-
-int
-thread_init(void)
-{
- uint32_t i;
-
- RTE_LCORE_FOREACH_WORKER(i) {
- char name[NAME_MAX];
- struct rte_ring *msgq_req, *msgq_rsp;
- struct thread *t = &thread[i];
- struct thread_data *t_data = &thread_data[i];
- uint32_t cpu_id = rte_lcore_to_socket_id(i);
-
- /* MSGQs */
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-REQ", i);
-
- msgq_req = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_req == NULL) {
- thread_free();
- return -1;
- }
-
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-RSP", i);
-
- msgq_rsp = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_rsp == NULL) {
- thread_free();
- return -1;
- }
-
- /* Main thread records */
- t->msgq_req = msgq_req;
- t->msgq_rsp = msgq_rsp;
- t->enabled = 1;
-
- /* Data plane thread records */
- t_data->n_pipelines = 0;
- t_data->msgq_req = msgq_req;
- t_data->msgq_rsp = msgq_rsp;
- t_data->timer_period =
- (rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;
- t_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;
- t_data->time_next_min = t_data->time_next;
- }
-
- return 0;
-}
-
-static inline int
-thread_is_running(uint32_t thread_id)
-{
- enum rte_lcore_state_t thread_state;
-
- thread_state = rte_eal_get_lcore_state(thread_id);
- return (thread_state == RUNNING) ? 1 : 0;
-}
-
-/**
- * Pipeline is running when:
- * (A) Pipeline is mapped to a data plane thread AND
- * (B) Its data plane thread is in RUNNING state.
- */
-static inline int
-pipeline_is_running(struct pipeline *p)
-{
- if (p->enabled == 0)
- return 0;
-
- return thread_is_running(p->thread_id);
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum thread_req_type {
- THREAD_REQ_PIPELINE_ENABLE = 0,
- THREAD_REQ_PIPELINE_DISABLE,
- THREAD_REQ_MAX
-};
-
-struct thread_msg_req {
- enum thread_req_type type;
-
- union {
- struct {
- struct rte_pipeline *p;
- struct {
- struct rte_table_action *a;
- } table[RTE_PIPELINE_TABLE_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
- uint32_t n_tables;
- } pipeline_enable;
-
- struct {
- struct rte_pipeline *p;
- } pipeline_disable;
- };
-};
-
-struct thread_msg_rsp {
- int status;
-};
-
-/**
- * Main thread
- */
-static struct thread_msg_req *
-thread_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct thread_msg_req),
- sizeof(struct thread_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-thread_msg_free(struct thread_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct thread_msg_rsp *
-thread_msg_send_recv(uint32_t thread_id,
- struct thread_msg_req *req)
-{
- struct thread *t = &thread[thread_id];
- struct rte_ring *msgq_req = t->msgq_req;
- struct rte_ring *msgq_rsp = t->msgq_rsp;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- uint32_t i;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL) ||
- (p->n_ports_in == 0) ||
- (p->n_ports_out == 0) ||
- (p->n_tables == 0))
- return -1;
-
- t = &thread[thread_id];
- if ((t->enabled == 0) ||
- p->enabled)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- struct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];
-
- if (td->n_pipelines >= THREAD_PIPELINES_MAX)
- return -1;
-
- /* Data plane thread */
- td->p[td->n_pipelines] = p->p;
-
- tdp->p = p->p;
- for (i = 0; i < p->n_tables; i++)
- tdp->table_data[i].a = p->table[i].a;
-
- tdp->n_tables = p->n_tables;
-
- tdp->msgq_req = p->msgq_req;
- tdp->msgq_rsp = p->msgq_rsp;
- tdp->timer_period = (rte_get_tsc_hz() * p->timer_period_ms) / 1000;
- tdp->time_next = rte_get_tsc_cycles() + tdp->timer_period;
-
- td->n_pipelines++;
-
- /* Pipeline */
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_ENABLE;
- req->pipeline_enable.p = p->p;
- for (i = 0; i < p->n_tables; i++)
- req->pipeline_enable.table[i].a =
- p->table[i].a;
- req->pipeline_enable.msgq_req = p->msgq_req;
- req->pipeline_enable.msgq_rsp = p->msgq_rsp;
- req->pipeline_enable.timer_period_ms = p->timer_period_ms;
- req->pipeline_enable.n_tables = p->n_tables;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
-}
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL))
- return -1;
-
- t = &thread[thread_id];
- if (t->enabled == 0)
- return -1;
-
- if (p->enabled == 0)
- return 0;
-
- if (p->thread_id != thread_id)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- uint32_t i;
-
- for (i = 0; i < td->n_pipelines; i++) {
- struct pipeline_data *tdp = &td->pipeline_data[i];
-
- if (tdp->p != p->p)
- continue;
-
- /* Data plane thread */
- if (i < td->n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- td->p[td->n_pipelines - 1];
- struct pipeline_data *tdp_last =
- &td->pipeline_data[td->n_pipelines - 1];
-
- td->p[i] = pipeline_last;
- memcpy(tdp, tdp_last, sizeof(*tdp));
- }
-
- td->n_pipelines--;
-
- /* Pipeline */
- p->enabled = 0;
-
- break;
- }
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_DISABLE;
- req->pipeline_disable.p = p->p;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->enabled = 0;
-
- return 0;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct thread_msg_req *
-thread_msg_recv(struct rte_ring *msgq_req)
-{
- struct thread_msg_req *req = NULL;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-thread_msg_send(struct rte_ring *msgq_rsp,
- struct thread_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_enable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- struct pipeline_data *p = &t->pipeline_data[t->n_pipelines];
- uint32_t i;
-
- /* Request */
- if (t->n_pipelines >= THREAD_PIPELINES_MAX) {
- rsp->status = -1;
- return rsp;
- }
-
- t->p[t->n_pipelines] = req->pipeline_enable.p;
-
- p->p = req->pipeline_enable.p;
- for (i = 0; i < req->pipeline_enable.n_tables; i++)
- p->table_data[i].a =
- req->pipeline_enable.table[i].a;
-
- p->n_tables = req->pipeline_enable.n_tables;
-
- p->msgq_req = req->pipeline_enable.msgq_req;
- p->msgq_rsp = req->pipeline_enable.msgq_rsp;
- p->timer_period =
- (rte_get_tsc_hz() * req->pipeline_enable.timer_period_ms) / 1000;
- p->time_next = rte_get_tsc_cycles() + p->timer_period;
-
- t->n_pipelines++;
-
- /* Response */
- rsp->status = 0;
- return rsp;
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_disable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- uint32_t n_pipelines = t->n_pipelines;
- struct rte_pipeline *pipeline = req->pipeline_disable.p;
- uint32_t i;
-
- /* find pipeline */
- for (i = 0; i < n_pipelines; i++) {
- struct pipeline_data *p = &t->pipeline_data[i];
-
- if (p->p != pipeline)
- continue;
-
- if (i < n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- t->p[n_pipelines - 1];
- struct pipeline_data *p_last =
- &t->pipeline_data[n_pipelines - 1];
-
- t->p[i] = pipeline_last;
- memcpy(p, p_last, sizeof(*p));
- }
-
- t->n_pipelines--;
-
- rsp->status = 0;
- return rsp;
- }
-
- /* should not get here */
- rsp->status = 0;
- return rsp;
-}
-
-static void
-thread_msg_handle(struct thread_data *t)
-{
- for ( ; ; ) {
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
-
- req = thread_msg_recv(t->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case THREAD_REQ_PIPELINE_ENABLE:
- rsp = thread_msg_handle_pipeline_enable(t, req);
- break;
-
- case THREAD_REQ_PIPELINE_DISABLE:
- rsp = thread_msg_handle_pipeline_disable(t, req);
- break;
-
- default:
- rsp = (struct thread_msg_rsp *) req;
- rsp->status = -1;
- }
-
- thread_msg_send(t->msgq_rsp, rsp);
- }
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum pipeline_req_type {
- /* Port IN */
- PIPELINE_REQ_PORT_IN_STATS_READ,
- PIPELINE_REQ_PORT_IN_ENABLE,
- PIPELINE_REQ_PORT_IN_DISABLE,
-
- /* Port OUT */
- PIPELINE_REQ_PORT_OUT_STATS_READ,
-
- /* Table */
- PIPELINE_REQ_TABLE_STATS_READ,
- PIPELINE_REQ_TABLE_RULE_ADD,
- PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_ADD_BULK,
- PIPELINE_REQ_TABLE_RULE_DELETE,
- PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_STATS_READ,
- PIPELINE_REQ_TABLE_MTR_PROFILE_ADD,
- PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE,
- PIPELINE_REQ_TABLE_RULE_MTR_READ,
- PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,
- PIPELINE_REQ_TABLE_RULE_TTL_READ,
- PIPELINE_REQ_TABLE_RULE_TIME_READ,
- PIPELINE_REQ_MAX
-};
-
-struct pipeline_msg_req_port_in_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_port_out_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_add {
- struct table_rule_match match;
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_default {
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_bulk {
- struct table_rule_list *list;
- int bulk;
-};
-
-struct pipeline_msg_req_table_rule_delete {
- struct table_rule_match match;
-};
-
-struct pipeline_msg_req_table_rule_stats_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_mtr_profile_add {
- uint32_t meter_profile_id;
- struct rte_table_action_meter_profile profile;
-};
-
-struct pipeline_msg_req_table_mtr_profile_delete {
- uint32_t meter_profile_id;
-};
-
-struct pipeline_msg_req_table_rule_mtr_read {
- void *data;
- uint32_t tc_mask;
- int clear;
-};
-
-struct pipeline_msg_req_table_dscp_table_update {
- uint64_t dscp_mask;
- struct rte_table_action_dscp_table dscp_table;
-};
-
-struct pipeline_msg_req_table_rule_ttl_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_time_read {
- void *data;
-};
-
-struct pipeline_msg_req {
- enum pipeline_req_type type;
- uint32_t id; /* Port IN, port OUT or table ID */
-
- union {
- struct pipeline_msg_req_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_req_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_req_table_stats_read table_stats_read;
- struct pipeline_msg_req_table_rule_add table_rule_add;
- struct pipeline_msg_req_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_req_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_req_table_rule_delete table_rule_delete;
- struct pipeline_msg_req_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_req_table_mtr_profile_add table_mtr_profile_add;
- struct pipeline_msg_req_table_mtr_profile_delete table_mtr_profile_delete;
- struct pipeline_msg_req_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_req_table_dscp_table_update table_dscp_table_update;
- struct pipeline_msg_req_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_req_table_rule_time_read table_rule_time_read;
- };
-};
-
-struct pipeline_msg_rsp_port_in_stats_read {
- struct rte_pipeline_port_in_stats stats;
-};
-
-struct pipeline_msg_rsp_port_out_stats_read {
- struct rte_pipeline_port_out_stats stats;
-};
-
-struct pipeline_msg_rsp_table_stats_read {
- struct rte_pipeline_table_stats stats;
-};
-
-struct pipeline_msg_rsp_table_rule_add {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_default {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_bulk {
- uint32_t n_rules;
-};
-
-struct pipeline_msg_rsp_table_rule_stats_read {
- struct rte_table_action_stats_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_mtr_read {
- struct rte_table_action_mtr_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_ttl_read {
- struct rte_table_action_ttl_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_time_read {
- uint64_t timestamp;
-};
-
-struct pipeline_msg_rsp {
- int status;
-
- union {
- struct pipeline_msg_rsp_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_rsp_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_rsp_table_stats_read table_stats_read;
- struct pipeline_msg_rsp_table_rule_add table_rule_add;
- struct pipeline_msg_rsp_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_rsp_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_rsp_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_rsp_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_rsp_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_rsp_table_rule_time_read table_rule_time_read;
- };
-};
-
-/**
- * Main thread
- */
-static struct pipeline_msg_req *
-pipeline_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct pipeline_msg_req),
- sizeof(struct pipeline_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-pipeline_msg_free(struct pipeline_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_send_recv(struct pipeline *p,
- struct pipeline_msg_req *req)
-{
- struct rte_ring *msgq_req = p->msgq_req;
- struct rte_ring *msgq_rsp = p->msgq_rsp;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_STATS_READ;
- req->id = port_id;
- req->port_in_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_enable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_ENABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_disable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_DISABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_out))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_OUT_STATS_READ;
- req->id = port_id;
- req->port_out_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_stats_read(p->p,
- table_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_STATS_READ;
- req->id = table_id;
- req->table_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static int
-match_check(struct table_rule_match *match,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table *table;
-
- if ((match == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
- if (match->match_type != table->params.match_type)
- return -1;
-
- switch (match->match_type) {
- case TABLE_ACL:
- {
- struct table_acl_params *t = &table->params.match.acl;
- struct table_rule_match_acl *r = &match->match.acl;
-
- if ((r->ip_version && (t->ip_version == 0)) ||
- ((r->ip_version == 0) && t->ip_version))
- return -1;
-
- if (r->ip_version) {
- if ((r->sa_depth > 32) ||
- (r->da_depth > 32))
- return -1;
- } else {
- if ((r->sa_depth > 128) ||
- (r->da_depth > 128))
- return -1;
- }
- return 0;
- }
-
- case TABLE_ARRAY:
- return 0;
-
- case TABLE_HASH:
- return 0;
-
- case TABLE_LPM:
- {
- struct table_lpm_params *t = &table->params.match.lpm;
- struct table_rule_match_lpm *r = &match->match.lpm;
-
- if ((r->ip_version && (t->key_size != 4)) ||
- ((r->ip_version == 0) && (t->key_size != 16)))
- return -1;
-
- if (r->ip_version) {
- if (r->depth > 32)
- return -1;
- } else {
- if (r->depth > 128)
- return -1;
- }
- return 0;
- }
-
- case TABLE_STUB:
- return -1;
-
- default:
- return -1;
- }
-}
-
-static int
-action_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table_action_profile *ap;
-
- if ((action == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- ap = p->table[table_id].ap;
- if (action->action_mask != ap->params.action_mask)
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- uint32_t tc_mask0 = (1 << ap->params.mtr.n_tc) - 1;
- uint32_t tc_mask1 = action->mtr.tc_mask;
-
- if (tc_mask1 != tc_mask0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- uint32_t n_subports_per_port =
- ap->params.tm.n_subports_per_port;
- uint32_t n_pipes_per_subport =
- ap->params.tm.n_pipes_per_subport;
- uint32_t subport_id = action->tm.subport_id;
- uint32_t pipe_id = action->tm.pipe_id;
-
- if ((subport_id >= n_subports_per_port) ||
- (pipe_id >= n_pipes_per_subport))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- uint64_t encap_mask = ap->params.encap.encap_mask;
- enum rte_table_action_encap_type type = action->encap.type;
-
- if ((encap_mask & (1LLU << type)) == 0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- int ip_version0 = ap->params.common.ip_version;
- int ip_version1 = action->nat.ip_version;
-
- if ((ip_version1 && (ip_version0 == 0)) ||
- ((ip_version1 == 0) && ip_version0))
- return -1;
- }
-
- return 0;
-}
-
-static int
-action_default_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- if ((action == NULL) ||
- (action->action_mask != (1LLU << RTE_TABLE_ACTION_FWD)) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- return 0;
-}
-
-union table_rule_match_low_level {
- struct rte_table_acl_rule_add_params acl_add;
- struct rte_table_acl_rule_delete_params acl_delete;
- struct rte_table_array_key array;
- uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
- struct rte_table_lpm_key lpm_ipv4;
- struct rte_table_lpm_ipv6_key lpm_ipv6;
-};
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add);
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data);
-
-struct table_ll {
- struct rte_pipeline *p;
- int table_id;
- struct rte_table_action *a;
- int bulk_supported;
-};
-
-static int
-table_rule_add_bulk_ll(struct table_ll *table,
- struct table_rule_list *list,
- uint32_t *n_rules)
-{
- union table_rule_match_low_level *match_ll = NULL;
- uint8_t *action_ll = NULL;
- void **match_ll_ptr = NULL;
- struct rte_pipeline_table_entry **action_ll_ptr = NULL;
- struct rte_pipeline_table_entry **entries_ptr = NULL;
- int *found = NULL;
- struct table_rule *rule;
- uint32_t n, i;
- int status = 0;
-
- n = 0;
- TAILQ_FOREACH(rule, list, node)
- n++;
-
- /* Memory allocation */
- match_ll = calloc(n, sizeof(union table_rule_match_low_level));
- action_ll = calloc(n, TABLE_RULE_ACTION_SIZE_MAX);
-
- match_ll_ptr = calloc(n, sizeof(void *));
- action_ll_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
-
- entries_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
- found = calloc(n, sizeof(int));
-
- if (match_ll == NULL ||
- action_ll == NULL ||
- match_ll_ptr == NULL ||
- action_ll_ptr == NULL ||
- entries_ptr == NULL ||
- found == NULL) {
- status = -ENOMEM;
- goto table_rule_add_bulk_ll_free;
- }
-
- /* Init */
- for (i = 0; i < n; i++) {
- match_ll_ptr[i] = (void *)&match_ll[i];
- action_ll_ptr[i] = (struct rte_pipeline_table_entry *)
- &action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
- }
-
- /* Rule (match, action) conversion */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- status = match_convert(&rule->match, match_ll_ptr[i], 1);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- status = action_convert(table->a, &rule->action, action_ll_ptr[i]);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- i++;
- }
-
- /* Add rule (match, action) to table */
- if (table->bulk_supported) {
- status = rte_pipeline_table_entry_add_bulk(table->p,
- table->table_id,
- match_ll_ptr,
- action_ll_ptr,
- n,
- found,
- entries_ptr);
- if (status)
- goto table_rule_add_bulk_ll_free;
- } else
- for (i = 0; i < n; i++) {
- status = rte_pipeline_table_entry_add(table->p,
- table->table_id,
- match_ll_ptr[i],
- action_ll_ptr[i],
- &found[i],
- &entries_ptr[i]);
- if (status) {
- if (i == 0)
- goto table_rule_add_bulk_ll_free;
-
- /* No roll-back. */
- status = 0;
- n = i;
- break;
- }
- }
-
- /* Write back to the rule list. */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- if (i >= n)
- break;
-
- rule->data = entries_ptr[i];
-
- i++;
- }
-
- *n_rules = n;
-
- /* Free */
-table_rule_add_bulk_ll_free:
- free(found);
- free(entries_ptr);
- free(action_ll_ptr);
- free(match_ll_ptr);
- free(action_ll);
- free(match_ll);
-
- return status;
-}
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id) ||
- action_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->match, match, sizeof(*match));
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- struct rte_pipeline_table_entry *data_in, *data_out;
- int key_found;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Table match-action rule conversion */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- status = action_convert(table->a, action, data_in);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Add rule (match, action) to table */
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD;
- req->id = table_id;
- memcpy(&req->table_rule_add.match, match, sizeof(*match));
- memcpy(&req->table_rule_add.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add.data;
- table_rule_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- action_default_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Apply actions */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_default_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT;
- req->id = table_id;
- memcpy(&req->table_rule_add_default.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add_default.data;
- table_rule_default_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static uint32_t
-table_rule_list_free(struct table_rule_list *list)
-{
- uint32_t n = 0;
-
- if (!list)
- return 0;
-
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- n++;
- }
-
- free(list);
- return n;
-}
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status = 0;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (list == NULL) ||
- TAILQ_EMPTY(list) ||
- (n_rules_added == NULL) ||
- (n_rules_not_added == NULL)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- table = &p->table[table_id];
-
- TAILQ_FOREACH(rule, list, node)
- if (match_check(&rule->match, p, table_id) ||
- action_check(&rule->action, p, table_id)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- if (!pipeline_is_running(p)) {
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = table->a,
- .bulk_supported = table->params.match_type == TABLE_ACL,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, n_rules_added);
- if (status) {
- table_rule_list_free(list);
- return status;
- }
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- table_rule_list_free(list);
- return -ENOMEM;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;
- req->id = table_id;
- req->table_rule_add_bulk.list = list;
- req->table_rule_add_bulk.bulk = table->params.match_type == TABLE_ACL;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- *n_rules_added = rsp->table_rule_add_bulk.n_rules;
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- } else
- table_rule_list_free(list);
-
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- int key_found;
-
- status = match_convert(match, &match_ll, 0);
- if (status)
- return -1;
-
- status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- if (status == 0)
- table_rule_delete(table, match);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE;
- req->id = table_id;
- memcpy(&req->table_rule_delete.match, match, sizeof(*match));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_delete(table, match);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- if (status == 0)
- table_rule_default_delete(table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT;
- req->id = table_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_default_delete(table);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_stats_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_STATS_READ;
- req->id = table_id;
- req->table_rule_stats_read.data = rule->data;
- req->table_rule_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (profile == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
- req->id = table_id;
- req->table_mtr_profile_add.meter_profile_id = meter_profile_id;
- memcpy(&req->table_mtr_profile_add.profile, profile, sizeof(*profile));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE;
- req->id = table_id;
- req->table_mtr_profile_delete.meter_profile_id = meter_profile_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- uint32_t tc_mask;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- tc_mask = (1 << table->ap->params.mtr.n_tc) - 1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_meter_read(table->a,
- rule->data,
- tc_mask,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_MTR_READ;
- req->id = table_id;
- req->table_rule_mtr_read.data = rule->data;
- req->table_rule_mtr_read.tc_mask = tc_mask;
- req->table_rule_mtr_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_mtr_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (dscp_table == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE;
- req->id = table_id;
- req->table_dscp_table_update.dscp_mask = dscp_mask;
- memcpy(&req->table_dscp_table_update.dscp_table,
- dscp_table, sizeof(*dscp_table));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- if (!table->ap->params.ttl.n_packets_enabled)
- return -1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_ttl_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TTL_READ;
- req->id = table_id;
- req->table_rule_ttl_read.data = rule->data;
- req->table_rule_ttl_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (timestamp == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_time_read(table->a,
- rule->data,
- timestamp);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TIME_READ;
- req->id = table_id;
- req->table_rule_time_read.data = rule->data;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- *timestamp = rsp->table_rule_time_read.timestamp;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct pipeline_msg_req *
-pipeline_msg_recv(struct rte_ring *msgq_req)
-{
- struct pipeline_msg_req *req;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-pipeline_msg_send(struct rte_ring *msgq_rsp,
- struct pipeline_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_in_stats_read.clear;
-
- rsp->status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- &rsp->port_in_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_enable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_enable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_disable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_disable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_out_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_out_stats_read.clear;
-
- rsp->status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- &rsp->port_out_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->table_stats_read.clear;
-
- rsp->status = rte_pipeline_table_stats_read(p->p,
- port_id,
- &rsp->table_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static int
-match_convert_ipv6_depth(uint32_t depth, uint32_t *depth32)
-{
- if (depth > 128)
- return -1;
-
- switch (depth / 32) {
- case 0:
- depth32[0] = depth;
- depth32[1] = 0;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 1:
- depth32[0] = 32;
- depth32[1] = depth - 32;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 2:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = depth - 64;
- depth32[3] = 0;
- return 0;
-
- case 3:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = depth - 96;
- return 0;
-
- case 4:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = 32;
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add)
-{
- memset(ml, 0, sizeof(*ml));
-
- switch (mh->match_type) {
- case TABLE_ACL:
- if (mh->match.acl.ip_version)
- if (add) {
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_add.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_add.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_add.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_add.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_delete.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_delete.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_delete.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_delete.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
- }
- else
- if (add) {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_add.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_add.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_add.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_add.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_add.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_add.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_add.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_add.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_add.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_add.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_add.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_add.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_add.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_add.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_add.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_add.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_delete.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_delete.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_delete.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_delete.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_delete.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_delete.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_delete.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_delete.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_delete.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_delete.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_delete.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_delete.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_delete.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_delete.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_delete.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_delete.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
- }
- return 0;
-
- case TABLE_ARRAY:
- ml->array.pos = mh->match.array.pos;
- return 0;
-
- case TABLE_HASH:
- memcpy(ml->hash, mh->match.hash.key, sizeof(ml->hash));
- return 0;
-
- case TABLE_LPM:
- if (mh->match.lpm.ip_version) {
- ml->lpm_ipv4.ip = mh->match.lpm.ipv4;
- ml->lpm_ipv4.depth = mh->match.lpm.depth;
- } else {
- ml->lpm_ipv6.ip = mh->match.lpm.ipv6;
- ml->lpm_ipv6.depth = mh->match.lpm.depth;
- }
-
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data)
-{
- int status;
-
- /* Apply actions */
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_FWD,
- &action->fwd);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_LB,
- &action->lb);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_MTR,
- &action->mtr);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TM,
- &action->tm);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_ENCAP,
- &action->encap);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_NAT,
- &action->nat);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TTL,
- &action->ttl);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_STATS,
- &action->stats);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TIME,
- &action->time);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- &action->sym_crypto);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TAG,
- &action->tag);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_DECAP,
- &action->decap);
-
- if (status)
- return status;
- }
-
- return 0;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_add.match;
- struct table_rule_action *action = &req->table_rule_add.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int key_found, status;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = action_convert(a, action, data_in);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_action *action = &req->table_rule_add_default.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int status;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_default.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
-
- uint32_t table_id = req->id;
- struct table_rule_list *list = req->table_rule_add_bulk.list;
- uint32_t bulk = req->table_rule_add_bulk.bulk;
-
- uint32_t n_rules_added;
- int status;
-
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = p->table_data[table_id].a,
- .bulk_supported = bulk,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, &n_rules_added);
- if (status) {
- rsp->status = -1;
- rsp->table_rule_add_bulk.n_rules = 0;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_bulk.n_rules = n_rules_added;
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_delete.match;
- uint32_t table_id = req->id;
- int key_found, status;
-
- status = match_convert(match, &match_ll, 0);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_stats_read.data;
- int clear = req->table_rule_stats_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_stats_read(a,
- data,
- &rsp->table_rule_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id = req->table_mtr_profile_add.meter_profile_id;
- struct rte_table_action_meter_profile *profile =
- &req->table_mtr_profile_add.profile;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id =
- req->table_mtr_profile_delete.meter_profile_id;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_mtr_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_mtr_read.data;
- uint32_t tc_mask = req->table_rule_mtr_read.tc_mask;
- int clear = req->table_rule_mtr_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_read(a,
- data,
- tc_mask,
- &rsp->table_rule_mtr_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_dscp_table_update(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint64_t dscp_mask = req->table_dscp_table_update.dscp_mask;
- struct rte_table_action_dscp_table *dscp_table =
- &req->table_dscp_table_update.dscp_table;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_ttl_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_ttl_read.data;
- int clear = req->table_rule_ttl_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_ttl_read(a,
- data,
- &rsp->table_rule_ttl_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_time_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_time_read.data;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_time_read(a,
- data,
- &rsp->table_rule_time_read.timestamp);
-
- return rsp;
-}
-
-static void
-pipeline_msg_handle(struct pipeline_data *p)
-{
- for ( ; ; ) {
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
-
- req = pipeline_msg_recv(p->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case PIPELINE_REQ_PORT_IN_STATS_READ:
- rsp = pipeline_msg_handle_port_in_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_ENABLE:
- rsp = pipeline_msg_handle_port_in_enable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_DISABLE:
- rsp = pipeline_msg_handle_port_in_disable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_OUT_STATS_READ:
- rsp = pipeline_msg_handle_port_out_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_STATS_READ:
- rsp = pipeline_msg_handle_table_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD:
- rsp = pipeline_msg_handle_table_rule_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_add_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_BULK:
- rsp = pipeline_msg_handle_table_rule_add_bulk(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE:
- rsp = pipeline_msg_handle_table_rule_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_delete_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_STATS_READ:
- rsp = pipeline_msg_handle_table_rule_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_ADD:
- rsp = pipeline_msg_handle_table_mtr_profile_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE:
- rsp = pipeline_msg_handle_table_mtr_profile_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_MTR_READ:
- rsp = pipeline_msg_handle_table_rule_mtr_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE:
- rsp = pipeline_msg_handle_table_dscp_table_update(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TTL_READ:
- rsp = pipeline_msg_handle_table_rule_ttl_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TIME_READ:
- rsp = pipeline_msg_handle_table_rule_time_read(p, req);
- break;
-
- default:
- rsp = (struct pipeline_msg_rsp *) req;
- rsp->status = -1;
- }
-
- pipeline_msg_send(p->msgq_rsp, rsp);
- }
-}
-
-/**
- * Data plane threads: main
- */
-int
-thread_main(void *arg __rte_unused)
-{
- struct thread_data *t;
- uint32_t thread_id, i;
-
- thread_id = rte_lcore_id();
- t = &thread_data[thread_id];
-
- /* Dispatch loop */
- for (i = 0; ; i++) {
- uint32_t j;
-
- /* Data Plane */
- for (j = 0; j < t->n_pipelines; j++)
- rte_pipeline_run(t->p[j]);
-
- /* Control Plane */
- if ((i & 0xF) == 0) {
- uint64_t time = rte_get_tsc_cycles();
- uint64_t time_next_min = UINT64_MAX;
-
- if (time < t->time_next_min)
- continue;
-
- /* Pipeline message queues */
- for (j = 0; j < t->n_pipelines; j++) {
- struct pipeline_data *p =
- &t->pipeline_data[j];
- uint64_t time_next = p->time_next;
-
- if (time_next <= time) {
- pipeline_msg_handle(p);
- rte_pipeline_flush(p->p);
- time_next = time + p->timer_period;
- p->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- /* Thread message queues */
- {
- uint64_t time_next = t->time_next;
-
- if (time_next <= time) {
- thread_msg_handle(t);
- time_next = time + t->timer_period;
- t->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- t->time_next_min = time_next_min;
- }
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h
deleted file mode 100644
index facdf004eb..0000000000
--- a/examples/ip_pipeline/thread.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_THREAD_H_
-#define _INCLUDE_THREAD_H_
-
-#include <stdint.h>
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_init(void);
-
-int
-thread_main(void *arg);
-
-#endif /* _INCLUDE_THREAD_H_ */
diff --git a/examples/ip_pipeline/tmgr.c b/examples/ip_pipeline/tmgr.c
deleted file mode 100644
index 2432b56aee..0000000000
--- a/examples/ip_pipeline/tmgr.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_string_fns.h>
-
-#include "tmgr.h"
-
-static struct rte_sched_subport_profile_params
- subport_profile[TMGR_SUBPORT_PROFILE_MAX];
-
-static uint32_t n_subport_profiles;
-
-static struct rte_sched_pipe_params
- pipe_profile[TMGR_PIPE_PROFILE_MAX];
-
-static uint32_t n_pipe_profiles;
-
-static const struct rte_sched_subport_params subport_params_default = {
- .n_pipes_per_subport_enabled = 0, /* filled at runtime */
- .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
- .pipe_profiles = pipe_profile,
- .n_pipe_profiles = 0, /* filled at run time */
- .n_max_pipe_profiles = RTE_DIM(pipe_profile),
- .cman_params = NULL,
-};
-
-static struct tmgr_port_list tmgr_port_list;
-
-int
-tmgr_init(void)
-{
- TAILQ_INIT(&tmgr_port_list);
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_find(const char *name)
-{
- struct tmgr_port *tmgr_port;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tmgr_port, &tmgr_port_list, node)
- if (strcmp(tmgr_port->name, name) == 0)
- return tmgr_port;
-
- return NULL;
-}
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *params)
-{
- /* Check input params */
- if (params == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&subport_profile[n_subport_profiles],
- params,
- sizeof(*params));
-
- n_subport_profiles++;
-
- return 0;
-}
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p)
-{
- /* Check input params */
- if (p == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&pipe_profile[n_pipe_profiles],
- p,
- sizeof(*p));
-
- n_pipe_profiles++;
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params)
-{
- struct rte_sched_subport_params subport_params;
- struct rte_sched_port_params p;
- struct tmgr_port *tmgr_port;
- struct rte_sched_port *s;
- uint32_t i, j;
-
- /* Check input params */
- if ((name == NULL) ||
- tmgr_port_find(name) ||
- (params == NULL) ||
- (params->n_subports_per_port == 0) ||
- (params->n_pipes_per_subport == 0) ||
- (params->cpu_id >= RTE_MAX_NUMA_NODES) ||
- (n_subport_profiles == 0) ||
- (n_pipe_profiles == 0))
- return NULL;
-
- /* Resource create */
- p.name = name;
- p.socket = (int) params->cpu_id;
- p.rate = params->rate;
- p.mtu = params->mtu;
- p.frame_overhead = params->frame_overhead;
- p.n_subports_per_port = params->n_subports_per_port;
- p.n_subport_profiles = n_subport_profiles;
- p.subport_profiles = subport_profile;
- p.n_max_subport_profiles = TMGR_SUBPORT_PROFILE_MAX;
- p.n_pipes_per_subport = params->n_pipes_per_subport;
-
-
- s = rte_sched_port_config(&p);
- if (s == NULL)
- return NULL;
-
- memcpy(&subport_params, &subport_params_default,
- sizeof(subport_params_default));
-
- subport_params.n_pipe_profiles = n_pipe_profiles;
- subport_params.n_pipes_per_subport_enabled =
- params->n_pipes_per_subport;
-
- for (i = 0; i < params->n_subports_per_port; i++) {
- int status;
-
- status = rte_sched_subport_config(
- s,
- i,
- &subport_params,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- for (j = 0; j < params->n_pipes_per_subport; j++) {
-
- status = rte_sched_pipe_config(
- s,
- i,
- j,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
- }
- }
-
- /* Node allocation */
- tmgr_port = calloc(1, sizeof(struct tmgr_port));
- if (tmgr_port == NULL) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(tmgr_port->name, name, sizeof(tmgr_port->name));
- tmgr_port->s = s;
- tmgr_port->n_subports_per_port = params->n_subports_per_port;
- tmgr_port->n_pipes_per_subport = params->n_pipes_per_subport;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tmgr_port_list, tmgr_port, node);
-
- return tmgr_port;
-}
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id)
-{
- struct tmgr_port *port;
- int status;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (subport_profile_id >= n_subport_profiles))
- return -1;
-
- /* Resource config */
- status = rte_sched_subport_config(
- port->s,
- subport_id,
- NULL,
- subport_profile_id);
-
- return status;
-}
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id)
-{
- struct tmgr_port *port;
- uint32_t i;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (pipe_id_first >= port->n_pipes_per_subport) ||
- (pipe_id_last >= port->n_pipes_per_subport) ||
- (pipe_id_first > pipe_id_last) ||
- (pipe_profile_id >= n_pipe_profiles))
- return -1;
-
- /* Resource config */
- for (i = pipe_id_first; i <= pipe_id_last; i++) {
- int status;
-
- status = rte_sched_pipe_config(
- port->s,
- subport_id,
- i,
- (int) pipe_profile_id);
-
- if (status)
- return status;
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/tmgr.h b/examples/ip_pipeline/tmgr.h
deleted file mode 100644
index 1994c55bcc..0000000000
--- a/examples/ip_pipeline/tmgr.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TMGR_H_
-#define _INCLUDE_TMGR_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_sched.h>
-#include <rte_red.h>
-
-#include "common.h"
-
-#ifndef TMGR_PIPE_SUBPORT_MAX
-#define TMGR_PIPE_SUBPORT_MAX 4096
-#endif
-
-#ifndef TMGR_SUBPORT_PROFILE_MAX
-#define TMGR_SUBPORT_PROFILE_MAX 256
-#endif
-
-#ifndef TMGR_PIPE_PROFILE_MAX
-#define TMGR_PIPE_PROFILE_MAX 256
-#endif
-
-struct tmgr_port {
- TAILQ_ENTRY(tmgr_port) node;
- char name[NAME_SIZE];
- struct rte_sched_port *s;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
-};
-
-TAILQ_HEAD(tmgr_port_list, tmgr_port);
-
-int
-tmgr_init(void);
-
-struct tmgr_port *
-tmgr_port_find(const char *name);
-
-struct tmgr_port_params {
- uint64_t rate;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
- uint32_t frame_overhead;
- uint32_t mtu;
- uint32_t cpu_id;
-};
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *sp);
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p);
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params);
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id);
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id);
-
-#endif /* _INCLUDE_TMGR_H_ */
diff --git a/examples/meson.build b/examples/meson.build
index 25d9c88457..544ec5eadd 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -19,7 +19,6 @@ all_examples = [
'flow_filtering',
'helloworld',
'ip_fragmentation',
- 'ip_pipeline',
'ip_reassembly',
'ipsec-secgw',
'ipv4_multicast',
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v3 4/6] pipeline: remove legacy API
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
` (2 preceding siblings ...)
2026-07-28 14:20 ` [PATCH v3 3/6] examples/ip_pipeline: remove example Stephen Hemminger
@ 2026-07-28 14:20 ` Stephen Hemminger
2026-07-28 14:20 ` [PATCH v3 6/6] port: " Stephen Hemminger
2026-07-28 14:48 ` [PATCH v3 0/6] remove legacy packet framework David Marchand
5 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 14:20 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy pipeline API (rte_pipeline_*) together with the
port and table action APIs built on top of it, as announced for
removal in the 24.11 release. The SWX pipeline API remains.
The sched dependency was only used by the table action API,
so drop it.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
devtools/cocci/nullfree.cocci | 12 -
doc/api/doxy-api-index.md | 3 -
doc/guides/prog_guide/packet_framework.rst | 203 --
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 4 +
lib/pipeline/meson.build | 8 +-
lib/pipeline/rte_pipeline.c | 1640 ---------
lib/pipeline/rte_pipeline.h | 840 -----
lib/pipeline/rte_port_in_action.c | 539 ---
lib/pipeline/rte_port_in_action.h | 311 --
lib/pipeline/rte_table_action.c | 3483 --------------------
lib/pipeline/rte_table_action.h | 1137 -------
12 files changed, 5 insertions(+), 8180 deletions(-)
delete mode 100644 lib/pipeline/rte_pipeline.c
delete mode 100644 lib/pipeline/rte_pipeline.h
delete mode 100644 lib/pipeline/rte_port_in_action.c
delete mode 100644 lib/pipeline/rte_port_in_action.h
delete mode 100644 lib/pipeline/rte_table_action.c
delete mode 100644 lib/pipeline/rte_table_action.h
diff --git a/devtools/cocci/nullfree.cocci b/devtools/cocci/nullfree.cocci
index e7417b69ff..acf26f45f6 100644
--- a/devtools/cocci/nullfree.cocci
+++ b/devtools/cocci/nullfree.cocci
@@ -91,12 +91,6 @@ expression E;
- if (E != NULL) rte_ring_free(E);
+ rte_ring_free(E);
|
-- if (E != NULL) rte_port_in_action_free(E);
-+ rte_port_in_action_free(E);
-|
-- if (E != NULL) rte_port_in_action_profile_free(E);
-+ rte_port_in_action_profile_free(E);
-|
- if (E != NULL) rte_sched_port_free(E);
+ rte_sched_port_free(E);
|
@@ -118,12 +112,6 @@ expression E;
- if (E != NULL) rte_swx_table_selector_free(E);
+ rte_swx_table_selector_free(E);
|
-- if (E != NULL) rte_table_action_free(E);
-+ rte_table_action_free(E);
-|
-- if (E != NULL) rte_table_action_profile_free(E);
-+ rte_table_action_profile_free(E);
-|
- if (E != NULL) rte_tel_data_free(E);
+ rte_tel_data_free(E);
|
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 9296042119..17c15027b8 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -196,9 +196,6 @@ The public API headers are grouped by topics:
[hash](@ref rte_table_hash.h),
[array](@ref rte_table_array.h),
[stub](@ref rte_table_stub.h)
- * [pipeline](@ref rte_pipeline.h)
- [port_in_action](@ref rte_port_in_action.h)
- [table_action](@ref rte_table_action.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index ac302938dc..9eb2c5d3de 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -942,209 +942,6 @@ Additional notes:
This does not impact the performance of the key lookup operation,
as the probability of having the bucket in extended state is relatively small.
-Pipeline Library Design
------------------------
-
-A pipeline is defined by:
-
-#. The set of input ports;
-
-#. The set of output ports;
-
-#. The set of tables;
-
-#. The set of actions.
-
-The input ports are connected with the output ports through tree-like topologies of interconnected tables.
-The table entries contain the actions defining the operations to be executed on the input packets and the packet flow within the pipeline.
-
-Connectivity of Ports and Tables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To avoid any dependencies on the order in which pipeline elements are created,
-the connectivity of pipeline elements is defined after all the pipeline input ports,
-output ports and tables have been created.
-
-General connectivity rules:
-
-#. Each input port is connected to a single table. No input port should be left unconnected;
-
-#. The table connectivity to other tables or to output ports is regulated by the next hop actions of each table entry and the default table entry.
- The table connectivity is fluid, as the table entries and the default table entry can be updated during run-time.
-
- * A table can have multiple entries (including the default entry) connected to the same output port.
- A table can have different entries connected to different output ports.
- Different tables can have entries (including default table entry) connected to the same output port.
-
- * A table can have multiple entries (including the default entry) connected to another table,
- in which case all these entries have to point to the same table.
- This constraint is enforced by the API and prevents tree-like topologies from being created (allowing table chaining only),
- with the purpose of simplifying the implementation of the pipeline run-time execution engine.
-
-Port Actions
-~~~~~~~~~~~~
-
-Port Action Handler
-^^^^^^^^^^^^^^^^^^^
-
-An action handler can be assigned to each input/output port to define actions to be executed on each input packet that is received by the port.
-Defining the action handler for a specific input/output port is optional (i.e. the action handler can be disabled).
-
-For input ports, the action handler is executed after RX function. For output ports, the action handler is executed before the TX function.
-
-The action handler can decide to drop packets.
-
-Table Actions
-~~~~~~~~~~~~~
-
-Table Action Handler
-^^^^^^^^^^^^^^^^^^^^
-
-An action handler to be executed on each input packet can be assigned to each table.
-Defining the action handler for a specific table is optional (i.e. the action handler can be disabled).
-
-The action handler is executed after the table lookup operation is performed and the table entry associated with each input packet is identified.
-The action handler can only handle the user-defined actions, while the reserved actions (e.g. the next hop actions) are handled by the Packet Framework.
-The action handler can decide to drop the input packet.
-
-Reserved Actions
-^^^^^^^^^^^^^^^^
-
-The reserved actions are handled directly by the Packet Framework without the user being able to change their meaning
-through the table action handler configuration.
-A special category of the reserved actions is represented by the next hop actions, which regulate the packet flow between input ports,
-tables and output ports through the pipeline.
-:numref:`packet_framework_table_qos_33` lists the next hop actions.
-
-.. _packet_framework_table_qos_33:
-
-.. table:: Next Hop Actions (Reserved)
-
- +---+---------------------+-----------------------------------------------------------------------------------+
- | # | Next hop action | Description |
- | | | |
- +===+=====================+===================================================================================+
- | 1 | Drop | Drop the current packet. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 2 | Send to output port | Send the current packet to specified output port. The output port ID is metadata |
- | | | stored in the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 3 | Send to table | Send the current packet to specified table. The table ID is metadata stored in |
- | | | the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
-
-User Actions
-^^^^^^^^^^^^
-
-For each table, the meaning of user actions is defined through the configuration of the table action handler.
-Different tables can be configured with different action handlers, therefore the meaning of the user actions
-and their associated meta-data is private to each table.
-Within the same table, all the table entries (including the table default entry) share the same definition
-for the user actions and their associated meta-data,
-with each table entry having its own set of enabled user actions and its own copy of the action meta-data.
-:numref:`packet_framework_table_qos_34` contains a non-exhaustive list of user action examples.
-
-.. _packet_framework_table_qos_34:
-
-.. table:: User Action Examples
-
- +---+-----------------------------------+---------------------------------------------------------------------+
- | # | User action | Description |
- | | | |
- +===+===================================+=====================================================================+
- | 1 | Metering | Per flow traffic metering using the srTCM and trTCM algorithms. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 2 | Statistics | Update the statistics counters maintained per flow. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 3 | App ID | Per flow state machine fed by variable length sequence of packets |
- | | | at the flow initialization with the purpose of identifying the |
- | | | traffic type and application. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 4 | Push/pop labels | Push/pop VLAN/MPLS labels to/from the current packet. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 5 | Network Address Translation (NAT) | Translate between the internal (LAN) and external (WAN) IP |
- | | | destination/source address and/or L4 protocol destination/source |
- | | | port. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 6 | TTL update | Decrement IP TTL and, in case of IPv4 packets, update the IP |
- | | | checksum. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 7 | Sym Crypto | Generate Cryptodev session based on the user-specified algorithm |
- | | | and key(s), and assemble the cryptodev operation based on the |
- | | | predefined offsets. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
-
-Multicore Scaling
------------------
-
-A complex application is typically split across multiple cores, with cores communicating through SW queues.
-There is usually a performance limit on the number of table lookups
-and actions that can be fitted on the same CPU core due to HW constraints like:
-available CPU cycles, cache memory size, cache transfer BW, memory transfer BW, etc.
-
-As the application is split across multiple CPU cores, the Packet Framework facilitates the creation of several pipelines,
-the assignment of each such pipeline to a different CPU core
-and the interconnection of all CPU core-level pipelines into a single application-level complex pipeline.
-For example, if CPU core A is assigned to run pipeline P1 and CPU core B pipeline P2,
-then the interconnection of P1 with P2 could be achieved by having the same set of SW queues act like output ports
-for P1 and input ports for P2.
-
-This approach enables the application development using the pipeline, run-to-completion (clustered) or hybrid (mixed) models.
-
-It is allowed for the same core to run several pipelines, but it is not allowed for several cores to run the same pipeline.
-
-Shared Data Structures
-~~~~~~~~~~~~~~~~~~~~~~
-
-The threads performing table lookup are actually table writers rather than just readers.
-Even if the specific table lookup algorithm is thread-safe for multiple readers
-(e. g. read-only access of the search algorithm data structures is enough to conduct the lookup operation),
-once the table entry for the current packet is identified, the thread is typically expected to update the action meta-data stored in the table entry
-(e.g. increment the counter tracking the number of packets that hit this table entry), and thus modify the table entry.
-During the time this thread is accessing this table entry (either writing or reading; duration is application specific),
-for data consistency reasons, no other threads (threads performing table lookup or entry add/delete operations) are allowed to modify this table entry.
-
-Mechanisms to share the same table between multiple threads:
-
-#. **Multiple writer threads.**
- Threads need to use synchronization primitives like semaphores (distinct semaphore per table entry) or atomic instructions.
- The cost of semaphores is usually high, even when the semaphore is free.
- The cost of atomic instructions is normally higher than the cost of regular instructions.
-
-#. **Multiple writer threads, with single thread performing table lookup operations and multiple threads performing table entry add/delete operations.**
- The threads performing table entry add/delete operations send table update requests to the reader (typically through message passing queues),
- which does the actual table updates and then sends the response back to the request initiator.
-
-#. **Single writer thread performing table entry add/delete operations and multiple reader threads that perform table lookup operations with read-only access to the table entries.**
- The reader threads use the main table copy while the writer is updating the mirror copy.
- Once the writer update is done, the writer can signal to the readers and busy wait until all readers swap between the main copy (which now becomes the mirror copy) and
- the mirror copy (which now becomes the main copy).
-
-Interfacing with Accelerators
------------------------------
-
-The presence of accelerators is usually detected during the initialization phase by inspecting the HW devices that are part of the system (e.g. by PCI bus enumeration).
-Typical devices with acceleration capabilities are:
-
-* Inline accelerators: NICs, switches, FPGAs, etc;
-
-* Look-aside accelerators: chipsets, FPGAs, Intel QuickAssist, etc.
-
-Usually, to support a specific functional block, specific implementation of Packet Framework tables and/or ports and/or actions has to be provided for each accelerator,
-with all the implementations sharing the same API: pure SW implementation (no acceleration), implementation using accelerator A, implementation using accelerator B, etc.
-The selection between these implementations could be done at build time or at run-time (recommended), based on which accelerators are present in the system,
-with no application changes required.
-
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 6ad7698c6b..758652a492 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* 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_*)
- will gradually transition from experimental to stable status.
-
* table: The table library legacy API (functions rte_table_*)
will be deprecated and subsequently removed in DPDK 24.11 release.
Before this, the new table library API (functions rte_swx_table_*)
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index fc84ba367e..f7d34aa1ee 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -84,6 +84,10 @@ Removed Items
the legacy pipeline library API.
The ``pipeline`` example application covers the SWX pipeline API.
+* Removed the legacy pipeline library API: ``rte_pipeline_*``,
+ ``rte_port_in_action_*`` and ``rte_table_action_*`` functions.
+ The SWX pipeline API (``rte_swx_pipeline_*``) remains.
+
API Changes
-----------
diff --git a/lib/pipeline/meson.build b/lib/pipeline/meson.build
index 823c7929a7..997ded6792 100644
--- a/lib/pipeline/meson.build
+++ b/lib/pipeline/meson.build
@@ -10,21 +10,15 @@ endif
cflags += no_wvla_cflag
sources = files(
- 'rte_pipeline.c',
- 'rte_port_in_action.c',
- 'rte_table_action.c',
'rte_swx_ipsec.c',
'rte_swx_pipeline.c',
'rte_swx_pipeline_spec.c',
'rte_swx_ctl.c',
)
headers = files(
- 'rte_pipeline.h',
- 'rte_port_in_action.h',
- 'rte_table_action.h',
'rte_swx_ipsec.h',
'rte_swx_pipeline.h',
'rte_swx_extern.h',
'rte_swx_ctl.h',
)
-deps += ['port', 'table', 'meter', 'sched', 'cryptodev', 'ipsec']
+deps += ['port', 'table', 'meter', 'cryptodev', 'ipsec']
diff --git a/lib/pipeline/rte_pipeline.c b/lib/pipeline/rte_pipeline.c
deleted file mode 100644
index fa3c8b77ee..0000000000
--- a/lib/pipeline/rte_pipeline.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-
-#include "rte_pipeline.h"
-
-RTE_LOG_REGISTER_DEFAULT(pipeline_logtype, INFO);
-#define RTE_LOGTYPE_PIPELINE pipeline_logtype
-
-#define PIPELINE_LOG(level, ...) \
- RTE_LOG_LINE(level, PIPELINE, "" __VA_ARGS__)
-
-#define RTE_TABLE_INVALID UINT32_MAX
-
-#ifdef RTE_PIPELINE_STATS_COLLECT
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask) \
- __extension__ ({ (p)->n_pkts_ah_drop = rte_popcount64(mask); })
-
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter) \
- __extension__ ({ (counter) += (p)->n_pkts_ah_drop; (p)->n_pkts_ah_drop = 0; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p) \
- __extension__ ({ (p)->pkts_drop_mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter) \
-__extension__ ({ \
- uint64_t mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; \
- mask ^= (p)->pkts_drop_mask; \
- (counter) += rte_popcount64(mask); \
-})
-
-#else
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask)
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter)
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p)
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter)
-
-#endif
-
-struct rte_port_in {
- /* Input parameters */
- struct rte_port_in_ops ops;
- rte_pipeline_port_in_action_handler f_action;
- void *arg_ah;
- uint32_t burst_size;
-
- /* The table to which this port is connected */
- uint32_t table_id;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* List of enabled ports */
- struct rte_port_in *next;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_port_out {
- /* Input parameters */
- struct rte_port_out_ops ops;
- rte_pipeline_port_out_action_handler f_action;
- void *arg_ah;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_table {
- /* Input parameters */
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action_hit;
- rte_pipeline_table_action_handler_miss f_action_miss;
- void *arg_ah;
- struct rte_pipeline_table_entry *default_entry;
- uint32_t entry_size;
-
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
-
- /* Handle to the low-level table object */
- void *h_table;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
- uint64_t n_pkts_dropped_lkp_hit;
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct __rte_cache_aligned rte_pipeline {
- /* Input parameters */
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- int socket_id;
- uint32_t offset_port_id;
-
- /* Internal tables */
- struct rte_port_in ports_in[RTE_PIPELINE_PORT_IN_MAX];
- struct rte_port_out ports_out[RTE_PIPELINE_PORT_OUT_MAX];
- struct rte_table tables[RTE_PIPELINE_TABLE_MAX];
-
- /* Occupancy of internal tables */
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
-
- /* List of enabled ports */
- uint64_t enabled_port_in_mask;
- struct rte_port_in *port_in_next;
-
- /* Pipeline run structures */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_pipeline_table_entry *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t action_mask0[RTE_PIPELINE_ACTIONS];
- uint64_t action_mask1[RTE_PIPELINE_ACTIONS];
- uint64_t pkts_mask;
- uint64_t n_pkts_ah_drop;
- uint64_t pkts_drop_mask;
-};
-
-static inline uint32_t
-rte_mask_get_next(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask << ((63 - pos) & 0x3F)) |
- (mask >> ((pos + 1) & 0x3F));
- return (rte_ctz64(mask_rot) - (63 - pos)) & 0x3F;
-}
-
-static inline uint32_t
-rte_mask_get_prev(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask >> (pos & 0x3F)) |
- (mask << ((64 - pos) & 0x3F));
- return ((63 - rte_clz64(mask_rot)) + pos) & 0x3F;
-}
-
-static void
-rte_pipeline_table_free(struct rte_table *table);
-
-static void
-rte_pipeline_port_in_free(struct rte_port_in *port);
-
-static void
-rte_pipeline_port_out_free(struct rte_port_out *port);
-
-/*
- * Pipeline
- */
-static int
-rte_pipeline_check_params(struct rte_pipeline_params *params)
-{
- if (params == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter params", __func__);
- return -EINVAL;
- }
-
- /* name */
- if (params->name == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter name", __func__);
- return -EINVAL;
- }
-
- /* socket */
- if (params->socket_id < 0) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter socket_id",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_create)
-struct rte_pipeline *
-rte_pipeline_create(struct rte_pipeline_params *params)
-{
- struct rte_pipeline *p;
- int status;
-
- /* Check input parameters */
- status = rte_pipeline_check_params(params);
- if (status != 0) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline params check failed (%d)",
- __func__, status);
- return NULL;
- }
-
- /* Allocate memory for the pipeline on requested socket */
- p = rte_zmalloc_socket("PIPELINE", sizeof(struct rte_pipeline),
- RTE_CACHE_LINE_SIZE, params->socket_id);
-
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline memory allocation failed", __func__);
- return NULL;
- }
-
- /* Save input parameters */
- strlcpy(p->name, params->name, RTE_PIPELINE_MAX_NAME_SZ);
- p->socket_id = params->socket_id;
- p->offset_port_id = params->offset_port_id;
-
- /* Initialize pipeline internal data structure */
- p->num_ports_in = 0;
- p->num_ports_out = 0;
- p->num_tables = 0;
- p->enabled_port_in_mask = 0;
- p->port_in_next = NULL;
- p->pkts_mask = 0;
- p->n_pkts_ah_drop = 0;
-
- return p;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_free)
-int
-rte_pipeline_free(struct rte_pipeline *p)
-{
- uint32_t i;
-
- /* Check input parameters */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: rte_pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free input ports */
- for (i = 0; i < p->num_ports_in; i++) {
- struct rte_port_in *port = &p->ports_in[i];
-
- rte_pipeline_port_in_free(port);
- }
-
- /* Free tables */
- for (i = 0; i < p->num_tables; i++) {
- struct rte_table *table = &p->tables[i];
-
- rte_pipeline_table_free(table);
- }
-
- /* Free output ports */
- for (i = 0; i < p->num_ports_out; i++) {
- struct rte_port_out *port = &p->ports_out[i];
-
- rte_pipeline_port_out_free(port);
- }
-
- /* Free pipeline memory */
- rte_free(p);
-
- return 0;
-}
-
-/*
- * Table
- */
-static int
-rte_table_check_params(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (table_id == NULL) {
- PIPELINE_LOG(ERR, "%s: table_id parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_lookup == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_lookup function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- /* De we have room for one more table? */
- if (p->num_tables == RTE_PIPELINE_TABLE_MAX) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for num_tables parameter",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_create)
-int
-rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- struct rte_table *table;
- struct rte_pipeline_table_entry *default_entry;
- void *h_table;
- uint32_t entry_size, id;
- int status;
-
- /* Check input arguments */
- status = rte_table_check_params(p, params, table_id);
- if (status != 0)
- return status;
-
- id = p->num_tables;
- table = &p->tables[id];
-
- /* Allocate space for the default table entry */
- entry_size = sizeof(struct rte_pipeline_table_entry) +
- params->action_data_size;
- default_entry = rte_zmalloc_socket(
- "PIPELINE", entry_size, RTE_CACHE_LINE_SIZE, p->socket_id);
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Failed to allocate default entry", __func__);
- return -EINVAL;
- }
-
- /* Create the table */
- h_table = params->ops->f_create(params->arg_create, p->socket_id,
- entry_size);
- if (h_table == NULL) {
- rte_free(default_entry);
- PIPELINE_LOG(ERR, "%s: Table creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_tables++;
- *table_id = id;
-
- /* Save input parameters */
- table->ops = *params->ops;
- table->f_action_hit = params->f_action_hit;
- table->f_action_miss = params->f_action_miss;
- table->arg_ah = params->arg_ah;
- table->entry_size = entry_size;
-
- /* Clear the lookup miss actions (to be set later through API) */
- table->default_entry = default_entry;
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- /* Initialize table internal data structure */
- table->h_table = h_table;
- table->table_next_id = 0;
- table->table_next_id_valid = 0;
-
- return 0;
-}
-
-void
-rte_pipeline_table_free(struct rte_table *table)
-{
- if (table->ops.f_free != NULL)
- table->ops.f_free(table->h_table);
-
- rte_free(table->default_entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_add)
-int
-rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: default_entry parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (default_entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Set the lookup miss actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = default_entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- memcpy(table->default_entry, default_entry, table->entry_size);
-
- *default_entry_ptr = table->default_entry;
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_delete)
-int
-rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- /* Save the current contents of the default entry */
- if (entry)
- memcpy(entry, table->default_entry, table->entry_size);
-
- /* Clear the lookup miss actions */
- memset(table->default_entry, 0, table->entry_size);
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add)
-int
-rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entry == NULL) {
- PIPELINE_LOG(ERR, "%s: entry parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Add entry */
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- return (table->ops.f_add)(table->h_table, key, (void *) entry,
- key_found, (void **) entry_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete)
-int
-rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete)(table->h_table, key, key_found, entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add_bulk)
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr)
-{
- struct rte_table *table;
- uint32_t i;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: keys parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entries == NULL) {
- PIPELINE_LOG(ERR, "%s: entries parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add_bulk == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add_bulk function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entries[i]->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
- }
-
- /* Add entry */
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entries[i]->table_id;
- table->table_next_id_valid = 1;
- }
- }
-
- return (table->ops.f_add_bulk)(table->h_table, keys, (void **) entries,
- n_keys, key_found, (void **) entries_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete_bulk)
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete_bulk)(table->h_table, keys, n_keys, key_found,
- (void **) entries);
-}
-
-/*
- * Port
- */
-static int
-rte_pipeline_port_in_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_rx == NULL) {
- PIPELINE_LOG(ERR, "%s: f_rx function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- /* burst_size */
- if ((params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PIPELINE_LOG(ERR, "%s: invalid value for burst_size",
- __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_in == RTE_PIPELINE_PORT_IN_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_in", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-rte_pipeline_port_out_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx_bulk function pointer NULL", __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_out == RTE_PIPELINE_PORT_OUT_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_out", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_create)
-int
-rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- struct rte_port_in *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_in_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_in;
- port = &p->ports_in[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_in++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
- port->burst_size = params->burst_size;
-
- /* Initialize port internal data structure */
- port->table_id = RTE_TABLE_INVALID;
- port->h_port = h_port;
- port->next = NULL;
-
- return 0;
-}
-
-void
-rte_pipeline_port_in_free(struct rte_port_in *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_create)
-int
-rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- struct rte_port_out *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_out_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_out;
- port = &p->ports_out[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_out++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
-
- /* Initialize port internal data structure */
- port->h_port = h_port;
-
- return 0;
-}
-
-void
-rte_pipeline_port_out_free(struct rte_port_out *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_connect_to_table)
-int
-rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct rte_port_in *port;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: Table ID %u is out of range",
- __func__, table_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
- port->table_id = table_id;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_enable)
-int
-rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already enabled */
- port_mask = 1LLU << port_id;
- if (p->enabled_port_in_mask & port_mask)
- return 0;
-
- p->enabled_port_in_mask |= port_mask;
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port;
- port->next = port_next;
-
- /* Check if list of enabled ports was previously empty */
- if (p->enabled_port_in_mask == port_mask)
- p->port_in_next = port;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_disable)
-int
-rte_pipeline_port_in_disable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR, "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already disabled */
- port_mask = 1LLU << port_id;
- if ((p->enabled_port_in_mask & port_mask) == 0)
- return 0;
-
- p->enabled_port_in_mask &= ~port_mask;
-
- /* Return if no other enabled ports */
- if (p->enabled_port_in_mask == 0) {
- p->port_in_next = NULL;
-
- return 0;
- }
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port_next;
-
- /* Check if the port which has just been disabled is next to serve */
- if (port == p->port_in_next)
- p->port_in_next = port_next;
-
- return 0;
-}
-
-/*
- * Pipeline run-time
- */
-RTE_EXPORT_SYMBOL(rte_pipeline_check)
-int
-rte_pipeline_check(struct rte_pipeline *p)
-{
- uint32_t port_in_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* Check that pipeline has at least one input port, one table and one
- output port */
- if (p->num_ports_in == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 input port",
- __func__);
- return -EINVAL;
- }
- if (p->num_tables == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 table",
- __func__);
- return -EINVAL;
- }
- if (p->num_ports_out == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 output port",
- __func__);
- return -EINVAL;
- }
-
- /* Check that all input ports are connected */
- for (port_in_id = 0; port_in_id < p->num_ports_in; port_in_id++) {
- struct rte_port_in *port_in = &p->ports_in[port_in_id];
-
- if (port_in->table_id == RTE_TABLE_INVALID) {
- PIPELINE_LOG(ERR,
- "%s: Port IN ID %u is not connected",
- __func__, port_in_id);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static inline void
-rte_pipeline_compute_masks(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->action_mask1[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos = p->entries[i]->action;
-
- p->action_mask1[pos] |= pkt_mask;
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pos = p->entries[i]->action;
- p->action_mask1[pos] |= pkt_mask;
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_bulk(struct rte_pipeline *p,
- uint64_t pkts_mask, uint32_t port_id)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- p->pkts_mask = pkts_mask;
-
- /* Output port user actions */
- if (port_out->f_action != NULL) {
- port_out->f_action(p, p->pkts, pkts_mask, port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
- }
-
- /* Output port TX */
- if (p->pkts_mask != 0)
- port_out->ops.f_tx_bulk(port_out->h_port,
- p->pkts,
- p->pkts_mask);
-}
-
-static inline void
-rte_pipeline_action_handler_port(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id = p->entries[i]->port_id;
- struct rte_port_out *port_out =
- &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = p->entries[i]->port_id;
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_meta(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id =
- RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- struct rte_port_out *port_out = &p->ports_out[
- port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_drop(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- rte_pktmbuf_free(p->pkts[i]);
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- rte_pktmbuf_free(p->pkts[i]);
- }
- }
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_run)
-int
-rte_pipeline_run(struct rte_pipeline *p)
-{
- struct rte_port_in *port_in = p->port_in_next;
- uint32_t n_pkts, table_id;
-
- if (port_in == NULL)
- return 0;
-
- /* Input port RX */
- n_pkts = port_in->ops.f_rx(port_in->h_port, p->pkts,
- port_in->burst_size);
- if (n_pkts == 0) {
- p->port_in_next = port_in->next;
- return 0;
- }
-
- p->pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- /* Input port user actions */
- if (port_in->f_action != NULL) {
- port_in->f_action(p, p->pkts, n_pkts, port_in->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_in->n_pkts_dropped_by_ah);
- }
-
- /* Table */
- for (table_id = port_in->table_id; p->pkts_mask != 0; ) {
- struct rte_table *table;
- uint64_t lookup_hit_mask, lookup_miss_mask;
-
- /* Lookup */
- table = &p->tables[table_id];
- table->ops.f_lookup(table->h_table, p->pkts, p->pkts_mask,
- &lookup_hit_mask, (void **) p->entries);
- lookup_miss_mask = p->pkts_mask & (~lookup_hit_mask);
-
- /* Lookup miss */
- if (lookup_miss_mask != 0) {
- struct rte_pipeline_table_entry *default_entry =
- table->default_entry;
-
- p->pkts_mask = lookup_miss_mask;
-
- /* Table user actions */
- if (table->f_action_miss != NULL) {
- table->f_action_miss(p,
- p->pkts,
- lookup_miss_mask,
- default_entry,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_miss_ah);
- }
-
- /* Table reserved actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_PORT) &&
- (p->pkts_mask != 0))
- rte_pipeline_action_handler_port_bulk(p,
- p->pkts_mask,
- default_entry->port_id);
- else {
- uint32_t pos = default_entry->action;
-
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
-
- p->action_mask0[pos] |= p->pkts_mask;
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_miss);
- }
- }
-
- /* Lookup hit */
- if (lookup_hit_mask != 0) {
- p->pkts_mask = lookup_hit_mask;
-
- /* Table user actions */
- if (table->f_action_hit != NULL) {
- table->f_action_hit(p,
- p->pkts,
- lookup_hit_mask,
- p->entries,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_hit_ah);
- }
-
- /* Table reserved actions */
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
- rte_pipeline_compute_masks(p, p->pkts_mask);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_DROP];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT_META];
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_TABLE];
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_hit);
- }
-
- /* Prepare for next iteration */
- p->pkts_mask = p->action_mask0[RTE_PIPELINE_ACTION_TABLE];
- table_id = table->table_next_id;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
- }
-
- /* Table reserved action PORT */
- rte_pipeline_action_handler_port(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT]);
-
- /* Table reserved action PORT META */
- rte_pipeline_action_handler_port_meta(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
-
- /* Table reserved action DROP */
- rte_pipeline_action_handler_drop(p,
- p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
-
- /* Pick candidate for next port IN to serve */
- p->port_in_next = port_in->next;
-
- return (int) n_pkts;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_flush)
-int
-rte_pipeline_flush(struct rte_pipeline *p)
-{
- uint32_t port_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- for (port_id = 0; port_id < p->num_ports_out; port_id++) {
- struct rte_port_out *port = &p->ports_out[port_id];
-
- if (port->ops.f_flush != NULL)
- port->ops.f_flush(port->h_port);
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_packet_insert)
-int
-rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id, struct rte_mbuf *pkt)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- port_out->ops.f_tx(port_out->h_port, pkt); /* Output port TX */
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_hijack)
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_drop)
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
-
- RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_stats_read)
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear)
-{
- struct rte_port_in *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_stats_read)
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear)
-{
- struct rte_port_out *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_out) {
- PIPELINE_LOG(ERR,
- "%s: port OUT ID %u is out of range", __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_out[port_id];
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_stats_read)
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear)
-{
- struct rte_table *table;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table %u is out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
- if (table->ops.f_stats != NULL) {
- retval = table->ops.f_stats(table->h_table, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL) {
- stats->n_pkts_dropped_by_lkp_hit_ah =
- table->n_pkts_dropped_by_lkp_hit_ah;
- stats->n_pkts_dropped_by_lkp_miss_ah =
- table->n_pkts_dropped_by_lkp_miss_ah;
- stats->n_pkts_dropped_lkp_hit = table->n_pkts_dropped_lkp_hit;
- stats->n_pkts_dropped_lkp_miss = table->n_pkts_dropped_lkp_miss;
- }
-
- if (clear != 0) {
- table->n_pkts_dropped_by_lkp_hit_ah = 0;
- table->n_pkts_dropped_by_lkp_miss_ah = 0;
- table->n_pkts_dropped_lkp_hit = 0;
- table->n_pkts_dropped_lkp_miss = 0;
- }
-
- return 0;
-}
diff --git a/lib/pipeline/rte_pipeline.h b/lib/pipeline/rte_pipeline.h
deleted file mode 100644
index c9e7172453..0000000000
--- a/lib/pipeline/rte_pipeline.h
+++ /dev/null
@@ -1,840 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PIPELINE_H__
-#define __INCLUDE_RTE_PIPELINE_H__
-
-/**
- * @file
- * RTE Pipeline
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard methodology (logically similar to OpenFlow) for rapid development
- * of complex packet processing pipelines out of ports, tables and actions.
- *
- * <B>Basic operation.</B> A pipeline is constructed by connecting its input
- * ports to its output ports through a chain of lookup tables. As result of
- * lookup operation into the current table, one of the table entries (or the
- * default table entry, in case of lookup miss) is identified to provide the
- * actions to be executed on the current packet and the associated action
- * meta-data. The behavior of user actions is defined through the configurable
- * table action handler, while the reserved actions define the next hop for the
- * current packet (either another table, an output port or packet drop) and are
- * handled transparently by the framework.
- *
- * <B>Initialization and run-time flows.</B> Once all the pipeline elements
- * (input ports, tables, output ports) have been created, input ports connected
- * to tables, table action handlers configured, tables populated with the
- * initial set of entries (actions and action meta-data) and input ports
- * enabled, the pipeline runs automatically, pushing packets from input ports
- * to tables and output ports. At each table, the identified user actions are
- * being executed, resulting in action meta-data (stored in the table entry)
- * and packet meta-data (stored with the packet descriptor) being updated. The
- * pipeline tables can have further updates and input ports can be disabled or
- * enabled later on as required.
- *
- * <B>Multi-core scaling.</B> Typically, each CPU core will run its own
- * pipeline instance. Complex application-level pipelines can be implemented by
- * interconnecting multiple CPU core-level pipelines in tree-like topologies,
- * as the same port devices (e.g. SW rings) can serve as output ports for the
- * pipeline running on CPU core A, as well as input ports for the pipeline
- * running on CPU core B. This approach enables the application development
- * using the pipeline (CPU cores connected serially), cluster/run-to-completion
- * (CPU cores connected in parallel) or mixed (pipeline of CPU core clusters)
- * programming models.
- *
- * <B>Thread safety.</B> It is possible to have multiple pipelines running on
- * the same CPU core, but it is not allowed (for thread safety reasons) to have
- * multiple CPU cores running the same pipeline instance.
- */
-
-#include <stdint.h>
-
-#include <rte_port.h>
-#include <rte_table.h>
-#include <rte_common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_mbuf;
-
-/*
- * Pipeline
- */
-/** Opaque data type for pipeline */
-struct rte_pipeline;
-
-/** Parameters for pipeline creation */
-struct rte_pipeline_params {
- /** Pipeline name */
- const char *name;
-
- /** CPU socket ID where memory for the pipeline and its elements (ports
- and tables) should be allocated */
- int socket_id;
-
- /** Offset within packet meta-data to port_id to be used by action
- "Send packet to output port read from packet meta-data". Has to be
- 4-byte aligned. */
- uint32_t offset_port_id;
-};
-
-/** Pipeline port in stats. */
-struct rte_pipeline_port_in_stats {
- /** Port in stats. */
- struct rte_port_in_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-
-};
-
-/** Pipeline port out stats. */
-struct rte_pipeline_port_out_stats {
- /** Port out stats. */
- struct rte_port_out_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-/** Pipeline table stats. */
-struct rte_pipeline_table_stats {
- /** Table stats. */
- struct rte_table_stats stats;
-
- /** Number of packets dropped by lookup hit action handler. */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
-
- /** Number of packets dropped by lookup miss action handler. */
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_hit;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-/**
- * Pipeline create
- *
- * @param params
- * Parameters for pipeline creation
- * @return
- * Handle to pipeline instance on success or NULL otherwise
- */
-struct rte_pipeline *rte_pipeline_create(struct rte_pipeline_params *params);
-
-/**
- * Pipeline free
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_free(struct rte_pipeline *p);
-
-/**
- * Pipeline consistency check
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_check(struct rte_pipeline *p);
-
-/**
- * Pipeline run
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * Number of packets read and processed
- */
-int rte_pipeline_run(struct rte_pipeline *p);
-
-/**
- * Pipeline flush
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_flush(struct rte_pipeline *p);
-
-/*
- * Actions
- */
-/** Reserved actions */
-enum rte_pipeline_action {
- /** Drop the packet */
- RTE_PIPELINE_ACTION_DROP = 0,
-
- /** Send packet to output port */
- RTE_PIPELINE_ACTION_PORT,
-
- /** Send packet to output port read from packet meta-data */
- RTE_PIPELINE_ACTION_PORT_META,
-
- /** Send packet to table */
- RTE_PIPELINE_ACTION_TABLE,
-
- /** Number of reserved actions */
- RTE_PIPELINE_ACTIONS
-};
-
-/*
- * Table
- */
-/** Maximum number of tables allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_TABLE_MAX 64
-
-/**
- * Head format for the table entry of any pipeline table. For any given
- * pipeline table, all table entries should have the same size and format. For
- * any given pipeline table, the table entry has to start with a head of this
- * structure, which contains the reserved actions and their associated
- * meta-data, and then optionally continues with user actions and their
- * associated meta-data. As all the currently defined reserved actions are
- * mutually exclusive, only one reserved action can be set per table entry.
- */
-struct rte_pipeline_table_entry {
- /** Reserved action */
- enum rte_pipeline_action action;
-
- union {
- /** Output port ID (meta-data for "Send packet to output port"
- action) */
- uint32_t port_id;
- /** Table ID (meta-data for "Send packet to table" action) */
- uint32_t table_id;
- };
- /** Start of table entry area for user defined actions and meta-data */
- uint8_t action_data[];
-};
-
-/**
- * Pipeline table action handler on lookup hit
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet and element n of entries array is pointing to a valid table
- * entry associated with the packet, with the association typically done by
- * the table lookup operation. Otherwise, element n of pkts array and element
- * n of entries array will not be accessed.
- * @param entries
- * Set of table entries specified as array of up to 64 pointers to struct
- * rte_pipeline_table_entry
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_hit)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg);
-
-/**
- * Pipeline table action handler on lookup miss
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param entry
- * Single table entry associated with all the valid packets from the input
- * burst, specified as pointer to struct rte_pipeline_table_entry.
- * This entry is the pipeline table default entry that is associated by the
- * table lookup operation with the input packets that have resulted in lookup
- * miss.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_miss)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry *entry,
- void *arg);
-
-/** Parameters for pipeline table creation. Action handlers have to be either
- both enabled or both disabled (they can be disabled by setting them to
- NULL). */
-struct rte_pipeline_table_params {
- /** Table operations (specific to each table type) */
- struct rte_table_ops *ops;
- /** Opaque param to be passed to the table create operation when
- invoked */
- void *arg_create;
- /** Callback function to execute the user actions on input packets in
- case of lookup hit */
- rte_pipeline_table_action_handler_hit f_action_hit;
- /** Callback function to execute the user actions on input packets in
- case of lookup miss */
- rte_pipeline_table_action_handler_miss f_action_miss;
-
- /** Opaque parameter to be passed to lookup hit and/or lookup miss
- action handlers when invoked */
- void *arg_ah;
- /** Memory size to be reserved per table entry for storing the user
- actions and their meta-data */
- uint32_t action_data_size;
-};
-
-/**
- * Pipeline table create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline table creation
- * @param table_id
- * Table ID. Valid only within the scope of table IDs of the current
- * pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id);
-
-/**
- * Pipeline table default entry add
- *
- * The contents of the table default entry is updated with the provided actions
- * and meta-data. When the default entry is not configured (by using this
- * function), the built-in default entry has the action "Drop" and meta-data
- * set to all-zeros.
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param default_entry
- * New contents for the table default entry
- * @param default_entry_ptr
- * On successful invocation, pointer to the default table entry which can be
- * used for further read-write accesses to this table entry. This pointer
- * is valid until the default entry is deleted or re-added.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr);
-
-/**
- * Pipeline table default entry delete
- *
- * The new contents of the table default entry is set to reserved action "Drop
- * the packet" with meta-data cleared (i.e. set to all-zeros).
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param entry
- * On successful invocation, when entry points to a valid buffer, the
- * previous contents of the table default entry (as it was just before the
- * delete operation) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param entry
- * New contents for the table entry identified by key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * already present in the table before the add operation and to FALSE (value
- * 0) if not
- * @param entry_ptr
- * On successful invocation, pointer to the table entry associated with key.
- * This can be used for further read-write accesses to this table entry and
- * is valid until the key is deleted from the table or re-added (usually for
- * associating different actions and/or action meta-data to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr);
-
-/**
- * Pipeline table entry delete
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * found in the table before the delete operation and to FALSE (value 0) if
- * not
- * @param entry
- * On successful invocation, when key is found in the table and entry points
- * to a valid buffer, the table entry contents (as it was before the delete
- * was performed) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param entries
- * Array containing new contents for every table entry identified by key
- * @param n_keys
- * Number of keys to add
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was already present in the table
- * before the add operation and to FALSE (value 0) if not
- * @param entries_ptr
- * On successful invocation, array *entries_ptr stores pointer to every table
- * entry associated with key. This can be used for further read-write accesses
- * to this table entry and is valid until the key is deleted from the table or
- * re-added (usually for associating different actions and/or action meta-data
- * to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr);
-
-/**
- * Pipeline table entry delete bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param n_keys
- * Number of keys to delete
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was found in the table before the
- * delete operation and to FALSE (value 0) if not
- * @param entries
- * If entries pointer is NULL, this pointer is ignored for every entry found.
- * Else, after successful invocation, if specific key is found in the table
- * and entry points to a valid buffer, the table entry contents (as it was
- * before the delete was performed) is copied to this buffer.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries);
-
-/**
- * Read pipeline table stats.
- *
- * This function reads table statistics identified by *table_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param table_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear);
-
-/*
- * Port IN
- */
-/** Maximum number of input ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_IN_MAX 64
-
-/**
- * Pipeline input port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param n
- * Number of packets in the input burst. This parameter specifies that
- * elements 0 to (n-1) of pkts array are valid.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_in_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n,
- void *arg);
-
-/** Parameters for pipeline input port creation */
-struct rte_pipeline_port_in_params {
- /** Input port operations (specific to each table type) */
- struct rte_port_in_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function to execute the user actions on input packets.
- Disabled if set to NULL. */
- rte_pipeline_port_in_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-
- /** Recommended burst size for the RX operation(in number of pkts) */
- uint32_t burst_size;
-};
-
-/**
- * Pipeline input port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline input port creation
- * @param port_id
- * Input port ID. Valid only within the scope of input port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id);
-
-/**
- * Pipeline input port connect to table
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id);
-
-/**
- * Pipeline input port enable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_enable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Pipeline input port disable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_disable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Read pipeline port in stats.
- *
- * This function reads port in statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear);
-
-/*
- * Port OUT
- */
-/** Maximum number of output ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_OUT_MAX 64
-
-/**
- * Pipeline output port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_out_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- void *arg);
-
-/** Parameters for pipeline output port creation. The action handlers have to
-be either both enabled or both disabled (by setting them to NULL). When
-enabled, the pipeline selects between them at different moments, based on the
-number of packets that have to be sent to the same output port. */
-struct rte_pipeline_port_out_params {
- /** Output port operations (specific to each table type) */
- struct rte_port_out_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function executing the user actions on bust of input
- packets */
- rte_pipeline_port_out_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-};
-
-/**
- * Pipeline output port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline output port creation
- * @param port_id
- * Output port ID. Valid only within the scope of output port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id);
-
-/**
- * Read pipeline port out stats.
- *
- * This function reads port out statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear);
-
-/*
- * Functions to be called as part of the port IN/OUT or table action handlers
- */
-/**
- * Action handler packet insert to output port
- *
- * This function can be called by any input/output port or table action handler
- * to send a packet out through one of the pipeline output ports. This packet is
- * generated by the action handler, i.e. this packet is not part of the burst of
- * packets read from one of the pipeline input ports and currently processed by
- * the pipeline (this packet is not an element of the pkts array input parameter
- * of the action handler).
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Output port ID (returned by previous invocation of pipeline output port
- * create) to send the packet specified by pkt
- * @param pkt
- * New packet generated by the action handler
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id,
- struct rte_mbuf *pkt);
-
-#define rte_pipeline_ah_port_out_packet_insert \
- rte_pipeline_port_out_packet_insert
-
-/**
- * Action handler packet hijack
- *
- * This function can be called by any input/output port or table action handler
- * to hijack selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The hijacked
- * packets are removed from any further pipeline processing, with the action
- * handler now having the full ownership for these packets.
- *
- * The action handler can further send the hijacked packets out through any
- * pipeline output port by calling the rte_pipeline_ah_port_out_packet_insert()
- * function. The action handler can also drop these packets by calling the
- * rte_pktmbuf_free() function, although a better alternative is provided by
- * the action handler using the rte_pipeline_ah_packet_drop() function.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be hijacked by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is hijacked.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-/**
- * Action handler packet drop
- *
- * This function is called by the pipeline action handlers (port in/out, table)
- * to drop the packets selected using packet mask.
- *
- * This function can be called by any input/output port or table action handler
- * to drop selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The dropped
- * packets are removed from any further pipeline processing and the packet
- * buffers are eventually freed to their buffer pool.
- *
- * This function updates the drop statistics counters correctly, therefore the
- * recommended approach for dropping packets by the action handlers is to call
- * this function as opposed to the action handler hijacking the packets first
- * and then dropping them invisibly to the pipeline (by using the
- * rte_pktmbuf_free() function).
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be dropped by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is dropped.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/pipeline/rte_port_in_action.c b/lib/pipeline/rte_port_in_action.c
deleted file mode 100644
index 2378e64de9..0000000000
--- a/lib/pipeline/rte_port_in_action.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_in_action.h"
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-static int
-fltr_cfg_check(struct rte_port_in_action_fltr_config *cfg)
-{
- if (cfg == NULL)
- return -1;
-
- return 0;
-}
-
-struct fltr_data {
- uint32_t port_id;
-};
-
-static void
-fltr_init(struct fltr_data *data,
- struct rte_port_in_action_fltr_config *cfg)
-{
- data->port_id = cfg->port_id;
-}
-
-static int
-fltr_apply(struct fltr_data *data,
- struct rte_port_in_action_fltr_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- data->port_id = p->port_id;
-
- return 0;
-}
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_port_in_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct lb_data {
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-static void
-lb_init(struct lb_data *data,
- struct rte_port_in_action_lb_config *cfg)
-{
- memcpy(data->port_id, cfg->port_id, sizeof(cfg->port_id));
-}
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_port_in_action_lb_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- memcpy(data->port_id, p->port_id, sizeof(p->port_id));
-
- return 0;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- case RTE_PORT_IN_ACTION_LB:
- return 1;
- default:
- return 0;
- }
-}
-
-#define RTE_PORT_IN_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-static size_t
-action_cfg_size(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct rte_port_in_action_fltr_config);
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct rte_port_in_action_lb_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_port_in_action_type type)
-{
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return &ap_config->fltr;
-
- case RTE_PORT_IN_ACTION_LB:
- return &ap_config->lb;
-
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_port_in_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_PORT_IN_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_port_in_action_type action,
- struct ap_config *ap_config __rte_unused)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct fltr_data);
-
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct lb_data);
-
- default:
- return 0;
- }
-}
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_PORT_IN_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_port_in_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_port_in_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_create, 18.05)
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id)
-{
- struct rte_port_in_action_profile *ap;
-
- /* Memory allocation */
- ap = rte_zmalloc_socket(NULL,
- sizeof(struct rte_port_in_action_profile),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (ap == NULL)
- return NULL;
-
- return ap;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_action_register, 18.05)
-int
-rte_port_in_action_profile_action_register(struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- status = fltr_cfg_check(action_config);
- break;
-
- case RTE_PORT_IN_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_freeze, 18.05)
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_free, 18.05)
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-struct rte_port_in_action {
- struct ap_config cfg;
- struct ap_data data;
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static __rte_always_inline void *
-action_data_get(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- size_t offset = action->data.offset[type];
-
- return &action->memory[offset];
-}
-
-static void
-action_data_init(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- void *data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- fltr_init(data, &action->cfg.fltr);
- return;
-
- case RTE_PORT_IN_ACTION_LB:
- lb_init(data, &action->cfg.lb);
- return;
-
- default:
- return;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_create, 18.05)
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_port_in_action *action;
- size_t size;
- uint32_t i;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- size = sizeof(struct rte_port_in_action) + profile->data.total_size;
- size = RTE_CACHE_LINE_ROUNDUP(size);
-
- action = rte_zmalloc_socket(NULL,
- size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- for (i = 0; i < RTE_PORT_IN_ACTION_MAX; i++)
- if (action->cfg.action_mask & (1LLU << i))
- action_data_init(action,
- (enum rte_port_in_action_type)i);
-
- return action;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_apply, 18.05)
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return fltr_apply(action_data,
- action_params);
-
- case RTE_PORT_IN_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-ah_filter_on_match(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or == 0) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_filter_on_mismatch(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_lb(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_lb_config *cfg = &action->cfg.lb;
- struct lb_data *data = action_data_get(action, RTE_PORT_IN_ACTION_LB);
- uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- uint32_t i;
-
- rte_pipeline_ah_packet_hijack(p, pkt_mask);
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(pkt,
- cfg->key_offset);
-
- uint64_t digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- uint64_t pos = digest & (RTE_PORT_IN_ACTION_LB_TABLE_SIZE - 1);
- uint32_t port_id = data->port_id[pos];
-
- rte_pipeline_port_out_packet_insert(p, port_id, pkt);
- }
-
- return 0;
-}
-
-static rte_pipeline_port_in_action_handler
-ah_selector(struct rte_port_in_action *action)
-{
- if (action->cfg.action_mask == 0)
- return NULL;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_FLTR)
- return (action->cfg.fltr.filter_on_match) ?
- ah_filter_on_match : ah_filter_on_mismatch;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_LB)
- return ah_lb;
-
- return NULL;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_params_get, 18.05)
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params)
-{
- rte_pipeline_port_in_action_handler f_action;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action = ah_selector(action);
-
- /* Fill in params */
- params->f_action = f_action;
- params->arg_ah = (f_action) ? action : NULL;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_free, 18.05)
-int
-rte_port_in_action_free(struct rte_port_in_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_port_in_action.h b/lib/pipeline/rte_port_in_action.h
deleted file mode 100644
index 9d17bae988..0000000000
--- a/lib/pipeline/rte_port_in_action.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IN_ACTION_H__
-#define __INCLUDE_RTE_PORT_IN_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Input Port Actions
- *
- * This API provides a common set of actions for pipeline input ports to speed
- * up application development.
- *
- * Each pipeline input port can be assigned an action handler to be executed
- * on every input packet during the pipeline execution. The pipeline library
- * allows the user to define his own input port actions by providing customized
- * input port action handler. While the user can still follow this process, this
- * API is intended to provide a quicker development alternative for a set of
- * predefined actions.
- *
- * The typical steps to use this API are:
- * - Define an input port action profile. This is a configuration template that
- * can potentially be shared by multiple input ports from the same or
- * different pipelines, with different input ports from the same pipeline
- * able to use different action profiles. For every input port using a given
- * action profile, the profile defines the set of actions and the action
- * configuration to be executed by the input port. API functions:
- * rte_port_in_action_profile_create(),
- * rte_port_in_action_profile_action_register(),
- * rte_port_in_action_profile_freeze().
- *
- * - Instantiate the input port action profile to create input port action
- * objects. Each pipeline input port has its own action object.
- * API functions: rte_port_in_action_create().
- *
- * - Use the input port action object to generate the input port action handler
- * invoked by the pipeline. API functions:
- * rte_port_in_action_params_get().
- *
- * - Use the input port action object to generate the internal data structures
- * used by the input port action handler based on given action parameters.
- * API functions: rte_port_in_action_apply().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Input port actions. */
-enum rte_port_in_action_type {
- /** Filter selected input packets. */
- RTE_PORT_IN_ACTION_FLTR = 0,
-
- /** Load balance. */
- RTE_PORT_IN_ACTION_LB,
-};
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-/** Filter key size (number of bytes) */
-#define RTE_PORT_IN_ACTION_FLTR_KEY_SIZE 16
-
-/** Filter action configuration (per action profile). */
-struct rte_port_in_action_fltr_config {
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask. */
- uint8_t key_mask[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** Key value. */
- uint8_t key[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** When non-zero, all the input packets that match the *key* (with the
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- * When zero, all the input packets that do NOT match the *key* (with
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- */
- int filter_on_match;
-
- /** Pipeline output port ID to send the filtered input packets to.
- * Can be updated later.
- *
- * @see struct rte_port_in_action_fltr_params
- */
- uint32_t port_id;
-};
-
-/** Filter action parameters (per action). */
-struct rte_port_in_action_fltr_params {
- /** Pipeline output port ID to send the filtered input packets to. */
- uint32_t port_id;
-};
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_PORT_IN_ACTION_LB_TABLE_SIZE 16
-
-/** Load balance action configuration (per action profile). */
-struct rte_port_in_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask(*key_size* bytes are valid). */
- uint8_t key_mask[RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table. Can be updated later.
- *
- * @see struct rte_port_in_action_lb_params
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/** Load balance action parameters (per action). */
-struct rte_port_in_action_lb_params {
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table.
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * Input port action profile.
- */
-struct rte_port_in_action_profile;
-
-/**
- * Input port action profile create.
- *
- * @param[in] socket_id
- * CPU socket ID for the internal data structures memory allocation.
- * @return
- * Input port action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id);
-
-/**
- * Input port action profile free.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid).
- * If profile is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action profile action register.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid and not in frozen
- * state).
- * @param[in] type
- * Specific input port action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_port_in_action_*type*_config is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_action_register(
- struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config);
-
-/**
- * Input port action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * input port action objects.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and not in frozen
- * state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_port_in_action_create()
- */
-__rte_experimental
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action.
- */
-struct rte_port_in_action;
-
-/**
- * Input port action create.
- *
- * Instantiates the given input port action profile to create an input port
- * action object.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new input
- * port action object should be allocated.
- * @return
- * Handle to input port action object on success, NULL on error.
- */
-__rte_experimental
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Input port action free.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * If action is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_free(struct rte_port_in_action *action);
-
-/**
- * Input port params get.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[inout] params
- * Pipeline input port parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params);
-
-/**
- * Input port action apply.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[in] type
- * Specific input port action previously registered for the input port action
- * profile of the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_port_in_action_*type*_params is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_PORT_IN_ACTION_H__ */
diff --git a/lib/pipeline/rte_table_action.c b/lib/pipeline/rte_table_action.c
deleted file mode 100644
index c990d7eb56..0000000000
--- a/lib/pipeline/rte_table_action.c
+++ /dev/null
@@ -1,3483 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_cycles.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_udp.h>
-#include <rte_vxlan.h>
-#include <rte_cryptodev.h>
-
-#include "rte_table_action.h"
-
-#define rte_htons rte_cpu_to_be_16
-#define rte_htonl rte_cpu_to_be_32
-
-#define rte_ntohs rte_be_to_cpu_16
-#define rte_ntohl rte_be_to_cpu_32
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-#define fwd_data rte_pipeline_table_entry
-
-static int
-fwd_apply(struct fwd_data *data,
- struct rte_table_action_fwd_params *p)
-{
- data->action = p->action;
-
- if (p->action == RTE_PIPELINE_ACTION_PORT)
- data->port_id = p->id;
-
- if (p->action == RTE_PIPELINE_ACTION_TABLE)
- data->table_id = p->id;
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_table_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_TABLE_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_TABLE_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct __rte_packed_begin lb_data {
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-} __rte_packed_end;
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_table_action_lb_params *p)
-{
- memcpy(data->out, p->out, sizeof(data->out));
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_lb(struct rte_mbuf *mbuf,
- struct lb_data *data,
- struct rte_table_action_lb_config *cfg)
-{
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->key_offset);
- uint32_t *out = RTE_MBUF_METADATA_UINT32_PTR(mbuf, cfg->out_offset);
- uint64_t digest, pos;
- uint32_t out_val;
-
- digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- pos = digest & (RTE_TABLE_ACTION_LB_TABLE_SIZE - 1);
- out_val = data->out[pos];
-
- *out = out_val;
-}
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-static int
-mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
-{
- if ((mtr->alg == RTE_TABLE_ACTION_METER_SRTCM) ||
- ((mtr->n_tc != 1) && (mtr->n_tc != 4)) ||
- (mtr->n_bytes_enabled != 0))
- return -ENOTSUP;
- return 0;
-}
-
-struct mtr_trtcm_data {
- struct rte_meter_trtcm trtcm;
- uint64_t stats[RTE_COLORS];
-};
-
-#define MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data) \
- (((data)->stats[RTE_COLOR_GREEN] & 0xF8LLU) >> 3)
-
-static void
-mtr_trtcm_data_meter_profile_id_set(struct mtr_trtcm_data *data,
- uint32_t profile_id)
-{
- data->stats[RTE_COLOR_GREEN] &= ~0xF8LLU;
- data->stats[RTE_COLOR_GREEN] |= (profile_id % 32) << 3;
-}
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color)\
- (((data)->stats[(color)] & 4LLU) >> 2)
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color)\
- ((enum rte_color)((data)->stats[(color)] & 3LLU))
-
-static void
-mtr_trtcm_data_policer_action_set(struct mtr_trtcm_data *data,
- enum rte_color color,
- enum rte_table_action_policer action)
-{
- if (action == RTE_TABLE_ACTION_POLICER_DROP) {
- data->stats[color] |= 4LLU;
- } else {
- data->stats[color] &= ~7LLU;
- data->stats[color] |= color & 3LLU;
- }
-}
-
-static uint64_t
-mtr_trtcm_data_stats_get(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- return data->stats[color] >> 8;
-}
-
-static void
-mtr_trtcm_data_stats_reset(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- data->stats[color] &= 0xFFLU;
-}
-
-#define MTR_TRTCM_DATA_STATS_INC(data, color) \
- ((data)->stats[(color)] += (1LLU << 8))
-
-static size_t
-mtr_data_size(struct rte_table_action_mtr_config *mtr)
-{
- return mtr->n_tc * sizeof(struct mtr_trtcm_data);
-}
-
-struct dscp_table_entry_data {
- enum rte_color color;
- uint16_t tc;
- uint16_t tc_queue;
-};
-
-struct dscp_table_data {
- struct dscp_table_entry_data entry[64];
-};
-
-struct meter_profile_data {
- struct rte_meter_trtcm_profile profile;
- uint32_t profile_id;
- int valid;
-};
-
-static struct meter_profile_data *
-meter_profile_data_find(struct meter_profile_data *mp,
- uint32_t mp_size,
- uint32_t profile_id)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (mp_data->valid && (mp_data->profile_id == profile_id))
- return mp_data;
- }
-
- return NULL;
-}
-
-static struct meter_profile_data *
-meter_profile_data_find_unused(struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (!mp_data->valid)
- return mp_data;
- }
-
- return NULL;
-}
-
-static int
-mtr_apply_check(struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- if (p->tc_mask > RTE_LEN2MASK(cfg->n_tc, uint32_t))
- return -EINVAL;
-
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-mtr_apply(struct mtr_trtcm_data *data,
- struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
- int status;
-
- /* Check input arguments */
- status = mtr_apply_check(p, cfg, mp, mp_size);
- if (status)
- return status;
-
- /* Apply */
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct mtr_trtcm_data *data_tc = &data[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- /* Find profile */
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
-
- memset(data_tc, 0, sizeof(*data_tc));
-
- /* Meter object */
- status = rte_meter_trtcm_config(&data_tc->trtcm,
- &mp_data->profile);
- if (status)
- return status;
-
- /* Meter profile */
- mtr_trtcm_data_meter_profile_id_set(data_tc,
- mp_data - mp);
-
- /* Policer actions */
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_GREEN,
- p_tc->policer[RTE_COLOR_GREEN]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_YELLOW,
- p_tc->policer[RTE_COLOR_YELLOW]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_RED,
- p_tc->policer[RTE_COLOR_RED]);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_mtr(struct rte_mbuf *mbuf,
- struct mtr_trtcm_data *data,
- struct dscp_table_data *dscp_table,
- struct meter_profile_data *mp,
- uint64_t time,
- uint32_t dscp,
- uint16_t total_length)
-{
- uint64_t drop_mask;
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- enum rte_color color_in, color_meter, color_policer;
- uint32_t tc, mp_id;
-
- tc = dscp_entry->tc;
- color_in = dscp_entry->color;
- data += tc;
- mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
-
- /* Meter */
- color_meter = rte_meter_trtcm_color_aware_check(
- &data->trtcm,
- &mp[mp_id].profile,
- time,
- total_length,
- color_in);
-
- /* Stats */
- MTR_TRTCM_DATA_STATS_INC(data, color_meter);
-
- /* Police */
- drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
- color_policer =
- MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- rte_mbuf_sched_color_set(mbuf, (uint8_t)color_policer);
-
- return drop_mask;
-}
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-static int
-tm_cfg_check(struct rte_table_action_tm_config *tm)
-{
- if ((tm->n_subports_per_port == 0) ||
- (rte_is_power_of_2(tm->n_subports_per_port) == 0) ||
- (tm->n_subports_per_port > UINT16_MAX) ||
- (tm->n_pipes_per_subport == 0) ||
- (rte_is_power_of_2(tm->n_pipes_per_subport) == 0))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin tm_data {
- uint32_t queue_id;
- uint32_t reserved;
-} __rte_packed_end;
-
-static int
-tm_apply_check(struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- if ((p->subport_id >= cfg->n_subports_per_port) ||
- (p->pipe_id >= cfg->n_pipes_per_subport))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-tm_apply(struct tm_data *data,
- struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = tm_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- data->queue_id = p->subport_id <<
- (rte_ctz32(cfg->n_pipes_per_subport) + 4) |
- p->pipe_id << 4;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tm(struct rte_mbuf *mbuf,
- struct tm_data *data,
- struct dscp_table_data *dscp_table,
- uint32_t dscp)
-{
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- uint32_t queue_id = data->queue_id |
- dscp_entry->tc_queue;
- rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc,
- (uint8_t)dscp_entry->color);
-}
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-static int
-encap_valid(enum rte_table_action_encap_type encap)
-{
- switch (encap) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 1;
- default:
- return 0;
- }
-}
-
-static int
-encap_cfg_check(struct rte_table_action_encap_config *encap)
-{
- if ((encap->encap_mask == 0) ||
- (rte_popcount64(encap->encap_mask) != 1))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct encap_ether_data {
- struct rte_ether_hdr ether;
-};
-
-#define VLAN(pcp, dei, vid) \
- ((uint16_t)((((uint64_t)(pcp)) & 0x7LLU) << 13) | \
- ((((uint64_t)(dei)) & 0x1LLU) << 12) | \
- (((uint64_t)(vid)) & 0xFFFLLU)) \
-
-struct encap_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
-};
-
-struct encap_qinq_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
-};
-
-#define ETHER_TYPE_MPLS_UNICAST 0x8847
-
-#define ETHER_TYPE_MPLS_MULTICAST 0x8848
-
-#define MPLS(label, tc, s, ttl) \
- ((uint32_t)(((((uint64_t)(label)) & 0xFFFFFLLU) << 12) |\
- ((((uint64_t)(tc)) & 0x7LLU) << 9) | \
- ((((uint64_t)(s)) & 0x1LLU) << 8) | \
- (((uint64_t)(ttl)) & 0xFFLLU)))
-
-struct __rte_aligned(2) __rte_packed_begin encap_mpls_data {
- struct rte_ether_hdr ether;
- uint32_t mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
- uint32_t mpls_count;
-} __rte_packed_end;
-
-#define PPP_PROTOCOL_IP 0x0021
-
-struct pppoe_ppp_hdr {
- uint16_t ver_type_code;
- uint16_t session_id;
- uint16_t length;
- uint16_t protocol;
-};
-
-struct encap_pppoe_data {
- struct rte_ether_hdr ether;
- struct pppoe_ppp_hdr pppoe_ppp;
-};
-
-#define IP_PROTO_UDP 17
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_data {
- struct rte_ether_hdr ether;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_data {
- struct rte_ether_hdr ether;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_qinq_pppoe_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
- struct pppoe_ppp_hdr pppoe_ppp;
-} __rte_packed_end;
-
-static size_t
-encap_data_size(struct rte_table_action_encap_config *encap)
-{
- switch (encap->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- return sizeof(struct encap_ether_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- return sizeof(struct encap_vlan_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- return sizeof(struct encap_qinq_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- return sizeof(struct encap_mpls_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- return sizeof(struct encap_pppoe_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- if (encap->vxlan.ip_version)
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv4_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv4_data);
- else
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv6_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv6_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return sizeof(struct encap_qinq_pppoe_data);
-
- default:
- return 0;
- }
-}
-
-static int
-encap_apply_check(struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((encap_valid(p->type) == 0) ||
- ((cfg->encap_mask & (1LLU << p->type)) == 0))
- return -EINVAL;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- if ((p->mpls.mpls_count == 0) ||
- (p->mpls.mpls_count > RTE_TABLE_ACTION_MPLS_LABELS_MAX))
- return -EINVAL;
-
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-encap_ether_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_ether_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->ether.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->ether.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_vlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_vlan_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vlan.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vlan.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vlan.vlan.pcp,
- p->vlan.vlan.dei,
- p->vlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_qinq_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_QINQ);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_qinq_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->qinq_pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_mpls_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_mpls_data *d = data;
- uint16_t ethertype = (p->mpls.unicast) ?
- ETHER_TYPE_MPLS_UNICAST :
- ETHER_TYPE_MPLS_MULTICAST;
- uint32_t i;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->mpls.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->mpls.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- /* MPLS */
- for (i = 0; i < p->mpls.mpls_count - 1; i++)
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 0,
- p->mpls.mpls[i].ttl));
-
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 1,
- p->mpls.mpls[i].ttl));
-
- d->mpls_count = p->mpls.mpls_count;
- return 0;
-}
-
-static int
-encap_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->pppoe.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->pppoe.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_vxlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((p->vxlan.vxlan.vni > 0xFFFFFF) ||
- (cfg->vxlan.ip_version && (p->vxlan.ipv4.dscp > 0x3F)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.flow_label > 0xFFFFF)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.dscp > 0x3F)) ||
- (cfg->vxlan.vlan && (p->vxlan.vlan.vid > 0xFFF)))
- return -1;
-
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv4_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv4_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
- else
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv6_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv6_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
-}
-
-static int
-encap_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg,
- struct rte_table_action_common_config *common_cfg)
-{
- int status;
-
- /* Check input arguments */
- status = encap_apply_check(p, cfg);
- if (status)
- return status;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return encap_ether_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return encap_vlan_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return encap_qinq_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- return encap_mpls_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return encap_pppoe_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return encap_vxlan_apply(data, p, cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return encap_qinq_pppoe_apply(data, p);
-
- default:
- return -EINVAL;
- }
-}
-
-static __rte_always_inline uint16_t
-encap_vxlan_ipv4_checksum_update(uint16_t cksum0,
- uint16_t total_length)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Add total length (one's complement logic) */
- cksum1 += total_length;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void *
-encap(void *dst, const void *src, size_t n)
-{
- dst = ((uint8_t *) dst) - n;
- return rte_memcpy(dst, src, n);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap(struct rte_mbuf *mbuf,
- void *data,
- struct rte_table_action_encap_config *cfg,
- void *ip,
- uint16_t total_length,
- uint32_t ip_offset)
-{
- switch (cfg->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- encap(ip, data, sizeof(struct encap_ether_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_ether_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_ether_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- encap(ip, data, sizeof(struct encap_vlan_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_vlan_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_vlan_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- encap(ip, data, sizeof(struct encap_qinq_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- {
- struct encap_mpls_data *mpls = data;
- size_t size = sizeof(struct rte_ether_hdr) +
- mpls->mpls_count * 4;
-
- encap(ip, data, size);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) + size);
- mbuf->pkt_len = mbuf->data_len = total_length + size;
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- {
- struct encap_pppoe_data *pppoe =
- encap(ip, data, sizeof(struct encap_pppoe_data));
- pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- {
- struct encap_qinq_pppoe_data *qinq_pppoe =
- encap(ip, data, sizeof(struct encap_qinq_pppoe_data));
- qinq_pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- {
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv4_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv4(mbuf, data, cfg);
- else
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv6_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv6(mbuf, data, cfg);
- }
-
- default:
- break;
- }
-}
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-static int
-nat_cfg_check(struct rte_table_action_nat_config *nat)
-{
- if ((nat->proto != 0x06) &&
- (nat->proto != 0x11))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin nat_ipv4_data {
- uint32_t addr;
- uint16_t port;
-} __rte_packed_end;
-
-struct __rte_packed_begin nat_ipv6_data {
- struct rte_ipv6_addr addr;
- uint16_t port;
-} __rte_packed_end;
-
-static size_t
-nat_data_size(struct rte_table_action_nat_config *nat __rte_unused,
- struct rte_table_action_common_config *common)
-{
- int ip_version = common->ip_version;
-
- return (ip_version) ?
- sizeof(struct nat_ipv4_data) :
- sizeof(struct nat_ipv6_data);
-}
-
-static int
-nat_apply_check(struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- if ((p->ip_version && (cfg->ip_version == 0)) ||
- ((p->ip_version == 0) && cfg->ip_version))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-nat_apply(void *data,
- struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = nat_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- if (p->ip_version) {
- struct nat_ipv4_data *d = data;
-
- d->addr = rte_htonl(p->addr.ipv4);
- d->port = rte_htons(p->port);
- } else {
- struct nat_ipv6_data *d = data;
-
- d->addr = p->addr.ipv6;
- d->port = rte_htons(p->port);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_tcp_udp_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF) + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF) + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv6_tcp_udp_checksum_update(uint16_t cksum0,
- uint16_t *ip0,
- uint16_t *ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= ip0[0] + ip0[1] + ip0[2] + ip0[3] +
- ip0[4] + ip0[5] + ip0[6] + ip0[7] + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += ip1[0] + ip1[1] + ip1[2] + ip1[3] +
- ip1[4] + ip1[5] + ip1[6] + ip1[7] + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void
-pkt_ipv4_work_nat(struct rte_ipv4_hdr *ip,
- struct nat_ipv4_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->src_addr,
- data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->src_addr,
- data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->src_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->dst_addr,
- data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->dst_addr,
- data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->dst_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-static __rte_always_inline void
-pkt_ipv6_work_nat(struct rte_ipv6_hdr *ip,
- struct nat_ipv6_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- udp->src_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- udp->dst_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-static int
-ttl_cfg_check(struct rte_table_action_ttl_config *ttl)
-{
- if (ttl->drop == 0)
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin ttl_data {
- uint32_t n_packets;
-} __rte_packed_end;
-
-#define TTL_INIT(data, decrement) \
- ((data)->n_packets = (decrement) ? 1 : 0)
-
-#define TTL_DEC_GET(data) \
- ((uint8_t)((data)->n_packets & 1))
-
-#define TTL_STATS_RESET(data) \
- ((data)->n_packets = ((data)->n_packets & 1))
-
-#define TTL_STATS_READ(data) \
- ((data)->n_packets >> 1)
-
-#define TTL_STATS_ADD(data, value) \
- ((data)->n_packets = \
- (((((data)->n_packets >> 1) + (value)) << 1) | \
- ((data)->n_packets & 1)))
-
-static int
-ttl_apply(void *data,
- struct rte_table_action_ttl_params *p)
-{
- struct ttl_data *d = data;
-
- TTL_INIT(d, p->decrement);
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv4_work_ttl(struct rte_ipv4_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint16_t cksum = ip->hdr_checksum;
- uint8_t ttl = ip->time_to_live;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- cksum += ttl_diff;
- ttl -= ttl_diff;
-
- ip->hdr_checksum = cksum;
- ip->time_to_live = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv6_work_ttl(struct rte_ipv6_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint8_t ttl = ip->hop_limits;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- ttl -= ttl_diff;
-
- ip->hop_limits = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-static int
-stats_cfg_check(struct rte_table_action_stats_config *stats)
-{
- if ((stats->n_packets_enabled == 0) && (stats->n_bytes_enabled == 0))
- return -EINVAL;
-
- return 0;
-}
-
-struct __rte_packed_begin stats_data {
- uint64_t n_packets;
- uint64_t n_bytes;
-} __rte_packed_end;
-
-static int
-stats_apply(struct stats_data *data,
- struct rte_table_action_stats_params *p)
-{
- data->n_packets = p->n_packets;
- data->n_bytes = p->n_bytes;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_stats(struct stats_data *data,
- uint16_t total_length)
-{
- data->n_packets++;
- data->n_bytes += total_length;
-}
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-struct __rte_packed_begin time_data {
- uint64_t time;
-} __rte_packed_end;
-
-static int
-time_apply(struct time_data *data,
- struct rte_table_action_time_params *p)
-{
- data->time = p->time;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_time(struct time_data *data,
- uint64_t time)
-{
- data->time = time;
-}
-
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-
-#define CRYPTO_OP_MASK_CIPHER 0x1
-#define CRYPTO_OP_MASK_AUTH 0x2
-#define CRYPTO_OP_MASK_AEAD 0x4
-
-struct crypto_op_sym_iv_aad {
- struct rte_crypto_op op;
- struct rte_crypto_sym_op sym_op;
- union {
- struct {
- uint8_t cipher_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t auth_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- } cipher_auth;
-
- struct {
- uint8_t iv[RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t aad[RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX];
- } aead_iv_aad;
-
- } iv_aad;
-};
-
-struct __rte_packed_begin sym_crypto_data {
-
- union {
- struct {
-
- /** Length of cipher iv. */
- uint16_t cipher_iv_len;
-
- /** Offset from start of IP header to the cipher iv. */
- uint16_t cipher_iv_data_offset;
-
- /** Length of cipher iv to be updated in the mbuf. */
- uint16_t cipher_iv_update_len;
-
- /** Offset from start of IP header to the auth iv. */
- uint16_t auth_iv_data_offset;
-
- /** Length of auth iv in the mbuf. */
- uint16_t auth_iv_len;
-
- /** Length of auth iv to be updated in the mbuf. */
- uint16_t auth_iv_update_len;
-
- } cipher_auth;
- struct {
-
- /** Length of iv. */
- uint16_t iv_len;
-
- /** Offset from start of IP header to the aead iv. */
- uint16_t iv_data_offset;
-
- /** Length of iv to be updated in the mbuf. */
- uint16_t iv_update_len;
-
- /** Length of aad */
- uint16_t aad_len;
-
- /** Offset from start of IP header to the aad. */
- uint16_t aad_data_offset;
-
- /** Length of aad to updated in the mbuf. */
- uint16_t aad_update_len;
-
- } aead;
- };
-
- /** Offset from start of IP header to the data. */
- uint16_t data_offset;
-
- /** Digest length. */
- uint16_t digest_len;
-
- /** block size */
- uint16_t block_size;
-
- /** Mask of crypto operation */
- uint16_t op_mask;
-
- /** Session pointer. */
- struct rte_cryptodev_sym_session *session;
-
- /** Direction of crypto, encrypt or decrypt */
- uint16_t direction;
-
- /** Private data size to store cipher iv / aad. */
- uint8_t iv_aad_data[32];
-
-} __rte_packed_end;
-
-static int
-sym_crypto_cfg_check(struct rte_table_action_sym_crypto_config *cfg)
-{
- if (!rte_cryptodev_is_valid_dev(cfg->cryptodev_id))
- return -EINVAL;
- if (cfg->mp_create == NULL || cfg->mp_init == NULL)
- return -EINVAL;
-
- return 0;
-}
-
-static int
-get_block_size(const struct rte_crypto_sym_xform *xform, uint8_t cdev_id)
-{
- struct rte_cryptodev_info dev_info;
- const struct rte_cryptodev_capabilities *cap;
- uint32_t i;
-
- rte_cryptodev_info_get(cdev_id, &dev_info);
-
- for (i = 0; dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
- i++) {
- cap = &dev_info.capabilities[i];
-
- if (cap->sym.xform_type != xform->type)
- continue;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
- (cap->sym.cipher.algo == xform->cipher.algo))
- return cap->sym.cipher.block_size;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
- (cap->sym.aead.algo == xform->aead.algo))
- return cap->sym.aead.block_size;
-
- if (xform->type == RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED)
- break;
- }
-
- return -1;
-}
-
-static int
-sym_crypto_apply(struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- struct rte_table_action_sym_crypto_params *p)
-{
- const struct rte_crypto_cipher_xform *cipher_xform = NULL;
- const struct rte_crypto_auth_xform *auth_xform = NULL;
- const struct rte_crypto_aead_xform *aead_xform = NULL;
- struct rte_crypto_sym_xform *xform = p->xform;
- struct rte_cryptodev_sym_session *session;
- int ret;
-
- memset(data, 0, sizeof(*data));
-
- while (xform) {
- if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
- cipher_xform = &xform->cipher;
-
- if (cipher_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- if (cipher_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_CIPHER;
-
- data->cipher_auth.cipher_iv_len =
- cipher_xform->iv.length;
- data->cipher_auth.cipher_iv_data_offset = (uint16_t)
- p->cipher_auth.cipher_iv_update.offset;
- data->cipher_auth.cipher_iv_update_len = (uint16_t)
- p->cipher_auth.cipher_iv_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.cipher_iv.val,
- p->cipher_auth.cipher_iv.length);
-
- data->direction = cipher_xform->op;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
- auth_xform = &xform->auth;
- if (auth_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- data->op_mask |= CRYPTO_OP_MASK_AUTH;
-
- data->cipher_auth.auth_iv_len = auth_xform->iv.length;
- data->cipher_auth.auth_iv_data_offset = (uint16_t)
- p->cipher_auth.auth_iv_update.offset;
- data->cipher_auth.auth_iv_update_len = (uint16_t)
- p->cipher_auth.auth_iv_update.length;
- data->digest_len = auth_xform->digest_length;
-
- data->direction = (auth_xform->op ==
- RTE_CRYPTO_AUTH_OP_GENERATE) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
- aead_xform = &xform->aead;
-
- if ((aead_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX) || (
- aead_xform->aad_length >
- RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX))
- return -EINVAL;
- if (aead_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_AEAD;
-
- data->digest_len = aead_xform->digest_length;
- data->aead.iv_len = aead_xform->iv.length;
- data->aead.aad_len = aead_xform->aad_length;
-
- data->aead.iv_data_offset = (uint16_t)
- p->aead.iv_update.offset;
- data->aead.iv_update_len = (uint16_t)
- p->aead.iv_update.length;
- data->aead.aad_data_offset = (uint16_t)
- p->aead.aad_update.offset;
- data->aead.aad_update_len = (uint16_t)
- p->aead.aad_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->aead.iv.val,
- p->aead.iv.length);
-
- rte_memcpy(data->iv_aad_data + p->aead.iv.length,
- p->aead.aad.val,
- p->aead.aad.length);
-
- data->direction = (aead_xform->op ==
- RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
- } else
- return -EINVAL;
-
- xform = xform->next;
- }
-
- if (auth_xform && auth_xform->iv.length) {
- if (cipher_xform) {
- if (auth_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET +
- cipher_xform->iv.length)
- return -EINVAL;
-
- rte_memcpy(data->iv_aad_data + cipher_xform->iv.length,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- } else {
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- }
- }
-
- session = rte_cryptodev_sym_session_create(cfg->cryptodev_id,
- p->xform, cfg->mp_create);
- if (!session)
- return -ENOMEM;
-
- data->data_offset = (uint16_t)p->data_offset;
- data->session = session;
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_sym_crypto(struct rte_mbuf *mbuf, struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- uint16_t ip_offset)
-{
- struct crypto_op_sym_iv_aad *crypto_op = (struct crypto_op_sym_iv_aad *)
- RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->op_offset);
- struct rte_crypto_op *op = &crypto_op->op;
- struct rte_crypto_sym_op *sym = op->sym;
- uint32_t pkt_offset = sizeof(*mbuf) + mbuf->data_off;
- uint32_t payload_len = pkt_offset + mbuf->data_len - data->data_offset;
-
- op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
- op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
- op->phys_addr = rte_mbuf_iova_get(mbuf) + cfg->op_offset - sizeof(*mbuf);
- op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
- sym->m_src = mbuf;
- sym->m_dst = NULL;
- sym->session = data->session;
-
- /** pad the packet */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
- uint32_t append_len = RTE_ALIGN_CEIL(payload_len,
- data->block_size) - payload_len;
-
- if (unlikely(rte_pktmbuf_append(mbuf, append_len +
- data->digest_len) == NULL))
- return 1;
-
- payload_len += append_len;
- } else
- payload_len -= data->digest_len;
-
- if (data->op_mask & CRYPTO_OP_MASK_CIPHER) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.cipher_iv;
-
- sym->cipher.data.length = payload_len;
- sym->cipher.data.offset = data->data_offset - pkt_offset;
-
- if (data->cipher_auth.cipher_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.cipher_iv_data_offset
- + ip_offset);
-
- /** For encryption, update the pkt iv field, otherwise
- * update the iv_aad_field
- */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_update_len);
- else
- rte_memcpy(data->iv_aad_data, pkt_iv,
- data->cipher_auth.cipher_iv_update_len);
- }
-
- /** write iv */
- rte_memcpy(iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_len);
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AUTH) {
- /** authentication always start from IP header. */
- sym->auth.data.offset = ip_offset - pkt_offset;
- sym->auth.data.length = mbuf->data_len - sym->auth.data.offset -
- data->digest_len;
- sym->auth.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->auth.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
-
- if (data->cipher_auth.auth_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.auth_iv_data_offset
- + ip_offset);
- uint8_t *data_iv = data->iv_aad_data +
- data->cipher_auth.cipher_iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->cipher_auth.auth_iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->cipher_auth.auth_iv_update_len);
- }
-
- if (data->cipher_auth.auth_iv_len) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.auth_iv;
-
- rte_memcpy(iv, data->iv_aad_data +
- data->cipher_auth.cipher_iv_len,
- data->cipher_auth.auth_iv_len);
- }
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AEAD) {
- uint8_t *iv = crypto_op->iv_aad.aead_iv_aad.iv;
- uint8_t *aad = crypto_op->iv_aad.aead_iv_aad.aad;
-
- sym->aead.aad.data = aad;
- sym->aead.aad.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- aad - rte_pktmbuf_mtod(mbuf, uint8_t *));
- sym->aead.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->aead.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
- sym->aead.data.offset = data->data_offset - pkt_offset;
- sym->aead.data.length = payload_len;
-
- if (data->aead.iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.iv_data_offset + ip_offset);
- uint8_t *data_iv = data->iv_aad_data;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(iv, data->iv_aad_data, data->aead.iv_len);
-
- if (data->aead.aad_update_len) {
- uint8_t *pkt_aad = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.aad_data_offset + ip_offset);
- uint8_t *data_aad = data->iv_aad_data +
- data->aead.iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_aad, data_aad,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_aad, pkt_aad,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(aad, data->iv_aad_data + data->aead.iv_len,
- data->aead.aad_len);
- }
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-struct __rte_packed_begin tag_data {
- uint32_t tag;
-} __rte_packed_end;
-
-static int
-tag_apply(struct tag_data *data,
- struct rte_table_action_tag_params *p)
-{
- data->tag = p->tag;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tag(struct rte_mbuf *mbuf,
- struct tag_data *data)
-{
- mbuf->hash.fdir.hi = data->tag;
- mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-static __rte_always_inline void
-pkt4_work_tag(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct tag_data *data0,
- struct tag_data *data1,
- struct tag_data *data2,
- struct tag_data *data3)
-{
- mbuf0->hash.fdir.hi = data0->tag;
- mbuf1->hash.fdir.hi = data1->tag;
- mbuf2->hash.fdir.hi = data2->tag;
- mbuf3->hash.fdir.hi = data3->tag;
-
- mbuf0->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf1->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf2->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf3->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-struct __rte_packed_begin decap_data {
- uint16_t n;
-} __rte_packed_end;
-
-static int
-decap_apply(struct decap_data *data,
- struct rte_table_action_decap_params *p)
-{
- data->n = p->n;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_decap(struct rte_mbuf *mbuf,
- struct decap_data *data)
-{
- uint16_t data_off = mbuf->data_off;
- uint16_t data_len = mbuf->data_len;
- uint32_t pkt_len = mbuf->pkt_len;
- uint16_t n = data->n;
-
- mbuf->data_off = data_off + n;
- mbuf->data_len = data_len - n;
- mbuf->pkt_len = pkt_len - n;
-}
-
-static __rte_always_inline void
-pkt4_work_decap(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct decap_data *data0,
- struct decap_data *data1,
- struct decap_data *data2,
- struct decap_data *data3)
-{
- uint16_t data_off0 = mbuf0->data_off;
- uint16_t data_len0 = mbuf0->data_len;
- uint32_t pkt_len0 = mbuf0->pkt_len;
-
- uint16_t data_off1 = mbuf1->data_off;
- uint16_t data_len1 = mbuf1->data_len;
- uint32_t pkt_len1 = mbuf1->pkt_len;
-
- uint16_t data_off2 = mbuf2->data_off;
- uint16_t data_len2 = mbuf2->data_len;
- uint32_t pkt_len2 = mbuf2->pkt_len;
-
- uint16_t data_off3 = mbuf3->data_off;
- uint16_t data_len3 = mbuf3->data_len;
- uint32_t pkt_len3 = mbuf3->pkt_len;
-
- uint16_t n0 = data0->n;
- uint16_t n1 = data1->n;
- uint16_t n2 = data2->n;
- uint16_t n3 = data3->n;
-
- mbuf0->data_off = data_off0 + n0;
- mbuf0->data_len = data_len0 - n0;
- mbuf0->pkt_len = pkt_len0 - n0;
-
- mbuf1->data_off = data_off1 + n1;
- mbuf1->data_len = data_len1 - n1;
- mbuf1->pkt_len = pkt_len1 - n1;
-
- mbuf2->data_off = data_off2 + n2;
- mbuf2->data_len = data_len2 - n2;
- mbuf2->pkt_len = pkt_len2 - n2;
-
- mbuf3->data_off = data_off3 + n3;
- mbuf3->data_len = data_len3 - n3;
- mbuf3->pkt_len = pkt_len3 - n3;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- case RTE_TABLE_ACTION_LB:
- case RTE_TABLE_ACTION_MTR:
- case RTE_TABLE_ACTION_TM:
- case RTE_TABLE_ACTION_ENCAP:
- case RTE_TABLE_ACTION_NAT:
- case RTE_TABLE_ACTION_TTL:
- case RTE_TABLE_ACTION_STATS:
- case RTE_TABLE_ACTION_TIME:
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- case RTE_TABLE_ACTION_TAG:
- case RTE_TABLE_ACTION_DECAP:
- return 1;
- default:
- return 0;
- }
-}
-
-
-#define RTE_TABLE_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-static size_t
-action_cfg_size(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct rte_table_action_lb_config);
- case RTE_TABLE_ACTION_MTR:
- return sizeof(struct rte_table_action_mtr_config);
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct rte_table_action_tm_config);
- case RTE_TABLE_ACTION_ENCAP:
- return sizeof(struct rte_table_action_encap_config);
- case RTE_TABLE_ACTION_NAT:
- return sizeof(struct rte_table_action_nat_config);
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct rte_table_action_ttl_config);
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct rte_table_action_stats_config);
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sizeof(struct rte_table_action_sym_crypto_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_table_action_type type)
-{
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- return &ap_config->lb;
-
- case RTE_TABLE_ACTION_MTR:
- return &ap_config->mtr;
-
- case RTE_TABLE_ACTION_TM:
- return &ap_config->tm;
-
- case RTE_TABLE_ACTION_ENCAP:
- return &ap_config->encap;
-
- case RTE_TABLE_ACTION_NAT:
- return &ap_config->nat;
-
- case RTE_TABLE_ACTION_TTL:
- return &ap_config->ttl;
-
- case RTE_TABLE_ACTION_STATS:
- return &ap_config->stats;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return &ap_config->sym_crypto;
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_table_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_TABLE_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_table_action_type action,
- struct ap_config *ap_config)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- return sizeof(struct fwd_data);
-
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct lb_data);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_data_size(&ap_config->mtr);
-
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct tm_data);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_data_size(&ap_config->encap);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_data_size(&ap_config->nat,
- &ap_config->common);
-
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct ttl_data);
-
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct stats_data);
-
- case RTE_TABLE_ACTION_TIME:
- return sizeof(struct time_data);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return (sizeof(struct sym_crypto_data));
-
- case RTE_TABLE_ACTION_TAG:
- return sizeof(struct tag_data);
-
- case RTE_TABLE_ACTION_DECAP:
- return sizeof(struct decap_data);
-
- default:
- return 0;
- }
-}
-
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_TABLE_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_table_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_table_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_create, 18.05)
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common)
-{
- struct rte_table_action_profile *ap;
-
- /* Check input arguments */
- if (common == NULL)
- return NULL;
-
- /* Memory allocation */
- ap = calloc(1, sizeof(struct rte_table_action_profile));
- if (ap == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&ap->cfg.common, common, sizeof(*common));
-
- return ap;
-}
-
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_action_register, 18.05)
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_MTR:
- status = mtr_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TM:
- status = tm_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_ENCAP:
- status = encap_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_NAT:
- status = nat_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TTL:
- status = ttl_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_STATS:
- status = stats_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- status = sym_crypto_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_freeze, 18.05)
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- profile->cfg.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_free, 18.05)
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-#define METER_PROFILES_MAX 32
-
-struct rte_table_action {
- struct ap_config cfg;
- struct ap_data data;
- struct dscp_table_data dscp_table;
- struct meter_profile_data mp[METER_PROFILES_MAX];
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_create, 18.05)
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_table_action *action;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- action = rte_zmalloc_socket(NULL,
- sizeof(struct rte_table_action),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- return action;
-}
-
-static __rte_always_inline void *
-action_data_get(void *data,
- struct rte_table_action *action,
- enum rte_table_action_type type)
-{
- size_t offset = action->data.offset[type];
- uint8_t *data_bytes = data;
-
- return &data_bytes[offset];
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_apply, 18.05)
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (data == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(data, action, type);
-
- switch (type) {
- case RTE_TABLE_ACTION_FWD:
- return fwd_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_apply(action_data,
- action_params,
- &action->cfg.mtr,
- action->mp,
- RTE_DIM(action->mp));
-
- case RTE_TABLE_ACTION_TM:
- return tm_apply(action_data,
- action_params,
- &action->cfg.tm);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_apply(action_data,
- action_params,
- &action->cfg.encap,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_apply(action_data,
- action_params,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_TTL:
- return ttl_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_STATS:
- return stats_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_TIME:
- return time_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sym_crypto_apply(action_data,
- &action->cfg.sym_crypto,
- action_params);
-
- case RTE_TABLE_ACTION_TAG:
- return tag_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_DECAP:
- return decap_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_dscp_table_update, 18.05)
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table)
-{
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TM))) == 0) ||
- (dscp_mask == 0) ||
- (table == NULL))
- return -EINVAL;
-
- for (i = 0; i < RTE_DIM(table->entry); i++) {
- struct dscp_table_entry_data *data =
- &action->dscp_table.entry[i];
- struct rte_table_action_dscp_table_entry *entry =
- &table->entry[i];
-
- if ((dscp_mask & (1LLU << i)) == 0)
- continue;
-
- data->color = entry->color;
- data->tc = entry->tc_id;
- data->tc_queue = entry->tc_queue_id;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_add, 18.05)
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct meter_profile_data *mp_data;
- uint32_t status;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (profile == NULL))
- return -EINVAL;
-
- if (profile->alg != RTE_TABLE_ACTION_METER_TRTCM)
- return -ENOTSUP;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (mp_data)
- return -EEXIST;
-
- mp_data = meter_profile_data_find_unused(action->mp,
- RTE_DIM(action->mp));
- if (!mp_data)
- return -ENOSPC;
-
- /* Install new profile */
- status = rte_meter_trtcm_profile_config(&mp_data->profile,
- &profile->trtcm);
- if (status)
- return status;
-
- mp_data->profile_id = meter_profile_id;
- mp_data->valid = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_delete, 18.05)
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id)
-{
- struct meter_profile_data *mp_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0))
- return -EINVAL;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (!mp_data)
- return 0;
-
- /* Uninstall profile */
- mp_data->valid = 0;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_read, 18.05)
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct mtr_trtcm_data *mtr_data;
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (data == NULL) ||
- (tc_mask > RTE_LEN2MASK(action->cfg.mtr.n_tc, uint32_t)))
- return -EINVAL;
-
- mtr_data = action_data_get(data, action, RTE_TABLE_ACTION_MTR);
-
- /* Read */
- if (stats) {
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_counters_tc *dst =
- &stats->stats[i];
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- dst->n_packets[RTE_COLOR_GREEN] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_GREEN);
-
- dst->n_packets[RTE_COLOR_YELLOW] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_YELLOW);
-
- dst->n_packets[RTE_COLOR_RED] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_RED);
-
- dst->n_packets_valid = 1;
- dst->n_bytes_valid = 0;
- }
-
- stats->tc_mask = tc_mask;
- }
-
- /* Clear */
- if (clear)
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_GREEN);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_YELLOW);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_RED);
- }
-
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_ttl_read, 18.05)
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct ttl_data *ttl_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TTL)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- ttl_data = action_data_get(data, action, RTE_TABLE_ACTION_TTL);
-
- /* Read */
- if (stats)
- stats->n_packets = TTL_STATS_READ(ttl_data);
-
- /* Clear */
- if (clear)
- TTL_STATS_RESET(ttl_data);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_stats_read, 18.05)
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct stats_data *stats_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_STATS)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- stats_data = action_data_get(data, action,
- RTE_TABLE_ACTION_STATS);
-
- /* Read */
- if (stats) {
- stats->n_packets = stats_data->n_packets;
- stats->n_bytes = stats_data->n_bytes;
- stats->n_packets_valid = 1;
- stats->n_bytes_valid = 1;
- }
-
- /* Clear */
- if (clear) {
- stats_data->n_packets = 0;
- stats_data->n_bytes = 0;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_time_read, 18.05)
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp)
-{
- struct time_data *time_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TIME)) == 0) ||
- (data == NULL) ||
- (timestamp == NULL))
- return -EINVAL;
-
- time_data = action_data_get(data, action, RTE_TABLE_ACTION_TIME);
-
- /* Read */
- *timestamp = time_data->time;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_crypto_sym_session_get, 18.11)
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data)
-{
- struct sym_crypto_data *sym_crypto_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) == 0) ||
- (data == NULL))
- return NULL;
-
- sym_crypto_data = action_data_get(data, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- return sym_crypto_data->session;
-}
-
-static __rte_always_inline uint64_t
-pkt_work(struct rte_mbuf *mbuf,
- struct rte_pipeline_table_entry *table_entry,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask = 0;
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ip_offset);
-
- uint32_t dscp;
- uint16_t total_length;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr = ip;
-
- dscp = hdr->type_of_service >> 2;
- total_length = rte_ntohs(hdr->total_length);
- } else {
- struct rte_ipv6_hdr *hdr = ip;
-
- dscp = (rte_ntohl(hdr->vtc_flow) & 0x0F600000) >> 18;
- total_length = rte_ntohs(hdr->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf,
- data,
- &cfg->lb);
- }
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask |= pkt_work_mtr(mbuf,
- data,
- &action->dscp_table,
- action->mp,
- time,
- dscp,
- total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf,
- data,
- &action->dscp_table,
- dscp);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt_work_decap(mbuf, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf,
- data,
- &cfg->encap,
- ip,
- total_length,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version)
- pkt_ipv4_work_nat(ip, data, &cfg->nat);
- else
- pkt_ipv6_work_nat(ip, data, &cfg->nat);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version)
- drop_mask |= pkt_ipv4_work_ttl(ip, data);
- else
- drop_mask |= pkt_ipv6_work_ttl(ip, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data, total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data = action_data_get(table_entry, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask |= pkt_work_sym_crypto(mbuf, data, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt_work_tag(mbuf, data);
- }
-
- return drop_mask;
-}
-
-static __rte_always_inline uint64_t
-pkt4_work(struct rte_mbuf **mbufs,
- struct rte_pipeline_table_entry **table_entries,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask0 = 0;
- uint64_t drop_mask1 = 0;
- uint64_t drop_mask2 = 0;
- uint64_t drop_mask3 = 0;
-
- struct rte_mbuf *mbuf0 = mbufs[0];
- struct rte_mbuf *mbuf1 = mbufs[1];
- struct rte_mbuf *mbuf2 = mbufs[2];
- struct rte_mbuf *mbuf3 = mbufs[3];
-
- struct rte_pipeline_table_entry *table_entry0 = table_entries[0];
- struct rte_pipeline_table_entry *table_entry1 = table_entries[1];
- struct rte_pipeline_table_entry *table_entry2 = table_entries[2];
- struct rte_pipeline_table_entry *table_entry3 = table_entries[3];
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip0 = RTE_MBUF_METADATA_UINT32_PTR(mbuf0, ip_offset);
- void *ip1 = RTE_MBUF_METADATA_UINT32_PTR(mbuf1, ip_offset);
- void *ip2 = RTE_MBUF_METADATA_UINT32_PTR(mbuf2, ip_offset);
- void *ip3 = RTE_MBUF_METADATA_UINT32_PTR(mbuf3, ip_offset);
-
- uint32_t dscp0, dscp1, dscp2, dscp3;
- uint16_t total_length0, total_length1, total_length2, total_length3;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr0 = ip0;
- struct rte_ipv4_hdr *hdr1 = ip1;
- struct rte_ipv4_hdr *hdr2 = ip2;
- struct rte_ipv4_hdr *hdr3 = ip3;
-
- dscp0 = hdr0->type_of_service >> 2;
- dscp1 = hdr1->type_of_service >> 2;
- dscp2 = hdr2->type_of_service >> 2;
- dscp3 = hdr3->type_of_service >> 2;
-
- total_length0 = rte_ntohs(hdr0->total_length);
- total_length1 = rte_ntohs(hdr1->total_length);
- total_length2 = rte_ntohs(hdr2->total_length);
- total_length3 = rte_ntohs(hdr3->total_length);
- } else {
- struct rte_ipv6_hdr *hdr0 = ip0;
- struct rte_ipv6_hdr *hdr1 = ip1;
- struct rte_ipv6_hdr *hdr2 = ip2;
- struct rte_ipv6_hdr *hdr3 = ip3;
-
- dscp0 = (rte_ntohl(hdr0->vtc_flow) & 0x0F600000) >> 18;
- dscp1 = (rte_ntohl(hdr1->vtc_flow) & 0x0F600000) >> 18;
- dscp2 = (rte_ntohl(hdr2->vtc_flow) & 0x0F600000) >> 18;
- dscp3 = (rte_ntohl(hdr3->vtc_flow) & 0x0F600000) >> 18;
-
- total_length0 = rte_ntohs(hdr0->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length1 = rte_ntohs(hdr1->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length2 = rte_ntohs(hdr2->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length3 = rte_ntohs(hdr3->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_LB);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_LB);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_LB);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf0,
- data0,
- &cfg->lb);
-
- pkt_work_lb(mbuf1,
- data1,
- &cfg->lb);
-
- pkt_work_lb(mbuf2,
- data2,
- &cfg->lb);
-
- pkt_work_lb(mbuf3,
- data3,
- &cfg->lb);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_MTR);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_MTR);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_MTR);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask0 |= pkt_work_mtr(mbuf0,
- data0,
- &action->dscp_table,
- action->mp,
- time,
- dscp0,
- total_length0);
-
- drop_mask1 |= pkt_work_mtr(mbuf1,
- data1,
- &action->dscp_table,
- action->mp,
- time,
- dscp1,
- total_length1);
-
- drop_mask2 |= pkt_work_mtr(mbuf2,
- data2,
- &action->dscp_table,
- action->mp,
- time,
- dscp2,
- total_length2);
-
- drop_mask3 |= pkt_work_mtr(mbuf3,
- data3,
- &action->dscp_table,
- action->mp,
- time,
- dscp3,
- total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TM);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TM);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TM);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf0,
- data0,
- &action->dscp_table,
- dscp0);
-
- pkt_work_tm(mbuf1,
- data1,
- &action->dscp_table,
- dscp1);
-
- pkt_work_tm(mbuf2,
- data2,
- &action->dscp_table,
- dscp2);
-
- pkt_work_tm(mbuf3,
- data3,
- &action->dscp_table,
- dscp3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt4_work_decap(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_ENCAP);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_ENCAP);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_ENCAP);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf0,
- data0,
- &cfg->encap,
- ip0,
- total_length0,
- ip_offset);
-
- pkt_work_encap(mbuf1,
- data1,
- &cfg->encap,
- ip1,
- total_length1,
- ip_offset);
-
- pkt_work_encap(mbuf2,
- data2,
- &cfg->encap,
- ip2,
- total_length2,
- ip_offset);
-
- pkt_work_encap(mbuf3,
- data3,
- &cfg->encap,
- ip3,
- total_length3,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_NAT);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_NAT);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_NAT);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version) {
- pkt_ipv4_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv4_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv4_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv4_work_nat(ip3, data3, &cfg->nat);
- } else {
- pkt_ipv6_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv6_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv6_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv6_work_nat(ip3, data3, &cfg->nat);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TTL);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TTL);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TTL);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version) {
- drop_mask0 |= pkt_ipv4_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv4_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv4_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv4_work_ttl(ip3, data3);
- } else {
- drop_mask0 |= pkt_ipv6_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv6_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv6_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv6_work_ttl(ip3, data3);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_STATS);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_STATS);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_STATS);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data0, total_length0);
- pkt_work_stats(data1, total_length1);
- pkt_work_stats(data2, total_length2);
- pkt_work_stats(data3, total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TIME);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TIME);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TIME);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data0, time);
- pkt_work_time(data1, time);
- pkt_work_time(data2, time);
- pkt_work_time(data3, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data0 = action_data_get(table_entry0, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data1 = action_data_get(table_entry1, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data2 = action_data_get(table_entry2, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data3 = action_data_get(table_entry3, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask0 |= pkt_work_sym_crypto(mbuf0, data0, &cfg->sym_crypto,
- ip_offset);
- drop_mask1 |= pkt_work_sym_crypto(mbuf1, data1, &cfg->sym_crypto,
- ip_offset);
- drop_mask2 |= pkt_work_sym_crypto(mbuf2, data2, &cfg->sym_crypto,
- ip_offset);
- drop_mask3 |= pkt_work_sym_crypto(mbuf3, data3, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt4_work_tag(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- return drop_mask0 |
- (drop_mask1 << 1) |
- (drop_mask2 << 2) |
- (drop_mask3 << 3);
-}
-
-static __rte_always_inline int
-ah(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t pkts_drop_mask = 0;
- uint64_t time = 0;
-
- if (cfg->action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TIME)))
- time = rte_rdtsc();
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {
- uint64_t drop_mask;
-
- drop_mask = pkt4_work(&pkts[i],
- &entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
-
- for ( ; i < n_pkts; i++) {
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[i],
- entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
- } else
- for ( ; pkts_mask; ) {
- uint32_t pos = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pos;
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[pos],
- entries[pos],
- time,
- action,
- cfg);
-
- pkts_mask &= ~pkt_mask;
- pkts_drop_mask |= drop_mask << pos;
- }
-
- rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
-
- return 0;
-}
-
-static int
-ah_default(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg)
-{
- struct rte_table_action *action = arg;
-
- return ah(p,
- pkts,
- pkts_mask,
- entries,
- action,
- &action->cfg);
-}
-
-static rte_pipeline_table_action_handler_hit
-ah_selector(struct rte_table_action *action)
-{
- if (action->cfg.action_mask == (1LLU << RTE_TABLE_ACTION_FWD))
- return NULL;
-
- return ah_default;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_table_params_get, 18.05)
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params)
-{
- rte_pipeline_table_action_handler_hit f_action_hit;
- uint32_t total_size;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action_hit = ah_selector(action);
- total_size = rte_align32pow2(action->data.total_size);
-
- /* Fill in params */
- params->f_action_hit = f_action_hit;
- params->f_action_miss = NULL;
- params->arg_ah = (f_action_hit) ? action : NULL;
- params->action_data_size = total_size -
- sizeof(struct rte_pipeline_table_entry);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_free, 18.05)
-int
-rte_table_action_free(struct rte_table_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_table_action.h b/lib/pipeline/rte_table_action.h
deleted file mode 100644
index 47a7bdfc01..0000000000
--- a/lib/pipeline/rte_table_action.h
+++ /dev/null
@@ -1,1137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_ACTION_H__
-#define __INCLUDE_RTE_TABLE_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Table Actions
- *
- * This API provides a common set of actions for pipeline tables to speed up
- * application development.
- *
- * Each match-action rule added to a pipeline table has associated data that
- * stores the action context. This data is input to the table action handler
- * called for every input packet that hits the rule as part of the table lookup
- * during the pipeline execution. The pipeline library allows the user to define
- * his own table actions by providing customized table action handlers (table
- * lookup) and complete freedom of setting the rules and their data (table rule
- * add/delete). While the user can still follow this process, this API is
- * intended to provide a quicker development alternative for a set of predefined
- * actions.
- *
- * The typical steps to use this API are:
- * - Define a table action profile. This is a configuration template that can
- * potentially be shared by multiple tables from the same or different
- * pipelines, with different tables from the same pipeline likely to use
- * different action profiles. For every table using a given action profile,
- * the profile defines the set of actions and the action configuration to be
- * implemented for all the table rules. API functions:
- * rte_table_action_profile_create(),
- * rte_table_action_profile_action_register(),
- * rte_table_action_profile_freeze().
- *
- * - Instantiate the table action profile to create table action objects. Each
- * pipeline table has its own table action object. API functions:
- * rte_table_action_create().
- *
- * - Use the table action object to generate the pipeline table action handlers
- * (invoked by the pipeline table lookup operation). API functions:
- * rte_table_action_table_params_get().
- *
- * - Use the table action object to generate the rule data (for the pipeline
- * table rule add operation) based on given action parameters. API functions:
- * rte_table_action_apply().
- *
- * - Use the table action object to read action data (e.g. stats counters) for
- * any given rule. API functions: rte_table_action_XYZ_read().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_ether.h>
-#include <rte_ip6.h>
-#include <rte_meter.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Table actions. */
-enum rte_table_action_type {
- /** Forward to next pipeline table, output port or drop. */
- RTE_TABLE_ACTION_FWD = 0,
-
- /** Load balance. */
- RTE_TABLE_ACTION_LB,
-
- /** Traffic Metering and Policing. */
- RTE_TABLE_ACTION_MTR,
-
- /** Traffic Management. */
- RTE_TABLE_ACTION_TM,
-
- /** Packet encapsulations. */
- RTE_TABLE_ACTION_ENCAP,
-
- /** Network Address Translation (NAT). */
- RTE_TABLE_ACTION_NAT,
-
- /** Time to Live (TTL) update. */
- RTE_TABLE_ACTION_TTL,
-
- /** Statistics. */
- RTE_TABLE_ACTION_STATS,
-
- /** Timestamp. */
- RTE_TABLE_ACTION_TIME,
-
- /** Crypto. */
- RTE_TABLE_ACTION_SYM_CRYPTO,
-
- /** Tag. */
- RTE_TABLE_ACTION_TAG,
-
- /** Packet decapsulations. */
- RTE_TABLE_ACTION_DECAP,
-};
-
-/** Common action configuration (per table action profile). */
-struct rte_table_action_common_config {
- /** Input packet Internet Protocol (IP) version. Non-zero for IPv4, zero
- * for IPv6.
- */
- int ip_version;
-
- /** IP header offset within the input packet buffer. Offset 0 points to
- * the first byte of the MBUF structure.
- */
- uint32_t ip_offset;
-};
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-/** Forward action parameters (per table rule). */
-struct rte_table_action_fwd_params {
- /** Forward action. */
- enum rte_pipeline_action action;
-
- /** Pipeline table ID or output port ID. */
- uint32_t id;
-};
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_TABLE_ACTION_LB_TABLE_SIZE 8
-
-/** Load balance action configuration (per table action profile). */
-struct rte_table_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask (*key_size* bytes are valid). */
- uint8_t key_mask[RTE_TABLE_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Output value offset within the input packet buffer. Offset 0 points
- * to the first byte of the MBUF structure.
- */
- uint32_t out_offset;
-};
-
-/** Load balance action parameters (per table rule). */
-struct rte_table_action_lb_params {
- /** Table defining the output values and their weights. The weights are
- * set in 1/RTE_TABLE_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_TABLE_ACTION_LB_TABLE_SIZE to a given output value
- * (0 <= N <= RTE_TABLE_ACTION_LB_TABLE_SIZE), the same output value
- * needs to show up exactly N times in this table.
- */
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-/** Max number of traffic classes (TCs). */
-#define RTE_TABLE_ACTION_TC_MAX 16
-
-/** Max number of queues per traffic class. */
-#define RTE_TABLE_ACTION_TC_QUEUE_MAX 16
-
-/** Differentiated Services Code Point (DSCP) translation table entry. */
-struct rte_table_action_dscp_table_entry {
- /** Traffic class. Used by the meter or the traffic management actions.
- * Has to be strictly smaller than *RTE_TABLE_ACTION_TC_MAX*. Traffic
- * class 0 is the highest priority.
- */
- uint32_t tc_id;
-
- /** Traffic class queue. Used by the traffic management action. Has to
- * be strictly smaller than *RTE_TABLE_ACTION_TC_QUEUE_MAX*.
- */
- uint32_t tc_queue_id;
-
- /** Packet color. Used by the meter action as the packet input color
- * for the color aware mode of the traffic metering algorithm.
- */
- enum rte_color color;
-};
-
-/** DSCP translation table. */
-struct rte_table_action_dscp_table {
- /** Array of DSCP table entries */
- struct rte_table_action_dscp_table_entry entry[64];
-};
-
-/** Supported traffic metering algorithms. */
-enum rte_table_action_meter_algorithm {
- /** Single Rate Three Color Marker (srTCM) - IETF RFC 2697. */
- RTE_TABLE_ACTION_METER_SRTCM,
-
- /** Two Rate Three Color Marker (trTCM) - IETF RFC 2698. */
- RTE_TABLE_ACTION_METER_TRTCM,
-};
-
-/** Traffic metering profile (configuration template). */
-struct rte_table_action_meter_profile {
- /** Traffic metering algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- union {
- /** Only valid when *alg* is set to srTCM - IETF RFC 2697. */
- struct rte_meter_srtcm_params srtcm;
-
- /** Only valid when *alg* is set to trTCM - IETF RFC 2698. */
- struct rte_meter_trtcm_params trtcm;
- };
-};
-
-/** Policer actions. */
-enum rte_table_action_policer {
- /** Recolor the packet as green. */
- RTE_TABLE_ACTION_POLICER_COLOR_GREEN = 0,
-
- /** Recolor the packet as yellow. */
- RTE_TABLE_ACTION_POLICER_COLOR_YELLOW,
-
- /** Recolor the packet as red. */
- RTE_TABLE_ACTION_POLICER_COLOR_RED,
-
- /** Drop the packet. */
- RTE_TABLE_ACTION_POLICER_DROP,
-
- /** Number of policer actions. */
- RTE_TABLE_ACTION_POLICER_MAX
-};
-
-/** Meter action configuration per traffic class. */
-struct rte_table_action_mtr_tc_params {
- /** Meter profile ID. */
- uint32_t meter_profile_id;
-
- /** Policer actions. */
- enum rte_table_action_policer policer[RTE_COLORS];
-};
-
-/** Meter action statistics counters per traffic class. */
-struct rte_table_action_mtr_counters_tc {
- /** Number of packets per color at the output of the traffic metering
- * and before the policer actions are executed. Only valid when
- * *n_packets_valid* is non-zero.
- */
- uint64_t n_packets[RTE_COLORS];
-
- /** Number of packet bytes per color at the output of the traffic
- * metering and before the policer actions are executed. Only valid when
- * *n_bytes_valid* is non-zero.
- */
- uint64_t n_bytes[RTE_COLORS];
-
- /** When non-zero, the *n_packets* field is valid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid. */
- int n_bytes_valid;
-};
-
-/** Meter action configuration (per table action profile). */
-struct rte_table_action_mtr_config {
- /** Meter algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- /** Number of traffic classes. Each traffic class has its own traffic
- * meter and policer instances. Needs to be equal to either 1 or to
- * *RTE_TABLE_ACTION_TC_MAX*.
- */
- uint32_t n_tc;
-
- /** When non-zero, the *n_packets* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_bytes_enabled;
-};
-
-/** Meter action parameters (per table rule). */
-struct rte_table_action_mtr_params {
- /** Traffic meter and policer parameters for each of the *tc_mask*
- * traffic classes.
- */
- struct rte_table_action_mtr_tc_params mtr[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/** Meter action statistics counters (per table rule). */
-struct rte_table_action_mtr_counters {
- /** Stats counters for each of the *tc_mask* traffic classes. */
- struct rte_table_action_mtr_counters_tc stats[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-/** Traffic management action configuration (per table action profile). */
-struct rte_table_action_tm_config {
- /** Number of subports per port. */
- uint32_t n_subports_per_port;
-
- /** Number of pipes per subport. */
- uint32_t n_pipes_per_subport;
-};
-
-/** Traffic management action parameters (per table rule). */
-struct rte_table_action_tm_params {
- /** Subport ID. */
- uint32_t subport_id;
-
- /** Pipe ID. */
- uint32_t pipe_id;
-};
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-/** Supported packet encapsulation types. */
-enum rte_table_action_encap_type {
- /** IP -> { Ether | IP } */
- RTE_TABLE_ACTION_ENCAP_ETHER = 0,
-
- /** IP -> { Ether | VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_VLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ,
-
- /** IP -> { Ether | MPLS | IP } */
- RTE_TABLE_ACTION_ENCAP_MPLS,
-
- /** IP -> { Ether | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_PPPOE,
-
- /** Ether -> { Ether | IP | UDP | VXLAN | Ether }
- * Ether -> { Ether | VLAN | IP | UDP | VXLAN | Ether }
- */
- RTE_TABLE_ACTION_ENCAP_VXLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE,
-};
-
-/** Pre-computed Ethernet header fields for encapsulation action. */
-struct rte_table_action_ether_hdr {
- struct rte_ether_addr da; /**< Destination address. */
- struct rte_ether_addr sa; /**< Source address. */
-};
-
-/** Pre-computed VLAN header fields for encapsulation action. */
-struct rte_table_action_vlan_hdr {
- uint8_t pcp; /**< Priority Code Point (PCP). */
- uint8_t dei; /**< Drop Eligibility Indicator (DEI). */
- uint16_t vid; /**< VLAN Identifier (VID). */
-};
-
-/** Pre-computed MPLS header fields for encapsulation action. */
-struct rte_table_action_mpls_hdr {
- uint32_t label; /**< Label. */
- uint8_t tc; /**< Traffic Class (TC). */
- uint8_t ttl; /**< Time to Live (TTL). */
-};
-
-/** Pre-computed PPPoE header fields for encapsulation action. */
-struct rte_table_action_pppoe_hdr {
- uint16_t session_id; /**< Session ID. */
-};
-
-/** Pre-computed IPv4 header fields for encapsulation action. */
-struct rte_table_action_ipv4_header {
- uint32_t sa; /**< Source address. */
- uint32_t da; /**< Destination address. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t ttl; /**< Time To Live (TTL). */
-};
-
-/** Pre-computed IPv6 header fields for encapsulation action. */
-struct rte_table_action_ipv6_header {
- struct rte_ipv6_addr sa; /**< Source address. */
- struct rte_ipv6_addr da; /**< Destination address. */
- uint32_t flow_label; /**< Flow label. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t hop_limit; /**< Hop Limit (HL). */
-};
-
-/** Pre-computed UDP header fields for encapsulation action. */
-struct rte_table_action_udp_header {
- uint16_t sp; /**< Source port. */
- uint16_t dp; /**< Destination port. */
-};
-
-/** Pre-computed VXLAN header fields for encapsulation action. */
-struct rte_table_action_vxlan_hdr {
- uint32_t vni; /**< VXLAN Network Identifier (VNI). */
-};
-
-/** Ether encap parameters. */
-struct rte_table_action_encap_ether_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
-};
-
-/** VLAN encap parameters. */
-struct rte_table_action_encap_vlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-};
-
-/** QinQ encap parameters. */
-struct rte_table_action_encap_qinq_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
-};
-
-/** Max number of MPLS labels per output packet for MPLS encapsulation. */
-#ifndef RTE_TABLE_ACTION_MPLS_LABELS_MAX
-#define RTE_TABLE_ACTION_MPLS_LABELS_MAX 4
-#endif
-
-/** MPLS encap parameters. */
-struct rte_table_action_encap_mpls_params {
- /** Ethernet header. */
- struct rte_table_action_ether_hdr ether;
-
- /** MPLS header. */
- struct rte_table_action_mpls_hdr mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
-
- /** Number of MPLS labels in MPLS header. */
- uint32_t mpls_count;
-
- /** Non-zero for MPLS unicast, zero for MPLS multicast. */
- int unicast;
-};
-
-/** PPPoE encap parameters. */
-struct rte_table_action_encap_pppoe_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** VXLAN encap parameters. */
-struct rte_table_action_encap_vxlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-
- union {
- struct rte_table_action_ipv4_header ipv4; /**< IPv4 header. */
- struct rte_table_action_ipv6_header ipv6; /**< IPv6 header. */
- };
-
- struct rte_table_action_udp_header udp; /**< UDP header. */
- struct rte_table_action_vxlan_hdr vxlan; /**< VXLAN header. */
-};
-
-/** Encap action configuration (per table action profile). */
-struct rte_table_action_encap_config {
- /** Bit mask defining the set of packet encapsulations enabled for the
- * current table action profile. If bit (1 << N) is set in *encap_mask*,
- * then packet encapsulation N is enabled, otherwise it is disabled.
- *
- * @see enum rte_table_action_encap_type
- */
- uint64_t encap_mask;
-
- /** Encapsulation type specific configuration. */
- union {
- struct {
- /** Input packet to be encapsulated: offset within the
- * input packet buffer to the start of the Ethernet
- * frame to be encapsulated. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- /** Encapsulation header: non-zero when encapsulation
- * header includes a VLAN tag, zero otherwise.
- */
- int vlan;
-
- /** Encapsulation header: IP version of the IP header
- * within the encapsulation header. Non-zero for IPv4,
- * zero for IPv6.
- */
- int ip_version;
- } vxlan; /**< VXLAN specific configuration. */
- };
-};
-
-/** QinQ_PPPoE encap parameters. */
-struct rte_table_encap_ether_qinq_pppoe {
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_ether_hdr ether;
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** Encap action parameters (per table rule). */
-struct rte_table_action_encap_params {
- /** Encapsulation type. */
- enum rte_table_action_encap_type type;
-
- union {
- /** Only valid when *type* is set to Ether. */
- struct rte_table_action_encap_ether_params ether;
-
- /** Only valid when *type* is set to VLAN. */
- struct rte_table_action_encap_vlan_params vlan;
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_encap_qinq_params qinq;
-
- /** Only valid when *type* is set to MPLS. */
- struct rte_table_action_encap_mpls_params mpls;
-
- /** Only valid when *type* is set to PPPoE. */
- struct rte_table_action_encap_pppoe_params pppoe;
-
- /** Only valid when *type* is set to VXLAN. */
- struct rte_table_action_encap_vxlan_params vxlan;
-
- /** Only valid when *type* is set to QinQ_PPPoE. */
- struct rte_table_encap_ether_qinq_pppoe qinq_pppoe;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-/** NAT action configuration (per table action profile). */
-struct rte_table_action_nat_config {
- /** When non-zero, the IP source address and L4 protocol source port are
- * translated. When zero, the IP destination address and L4 protocol
- * destination port are translated.
- */
- int source_nat;
-
- /** Layer 4 protocol, for example TCP (0x06) or UDP (0x11). The checksum
- * field is computed differently and placed at different header offset
- * by each layer 4 protocol.
- */
- uint8_t proto;
-};
-
-/** NAT action parameters (per table rule). */
-struct rte_table_action_nat_params {
- /** IP version for *addr*: non-zero for IPv4, zero for IPv6. */
- int ip_version;
-
- /** IP address. */
- union {
- /** IPv4 address; only valid when *ip_version* is non-zero. */
- uint32_t ipv4;
-
- /** IPv6 address; only valid when *ip_version* is set to 0. */
- struct rte_ipv6_addr ipv6;
- } addr;
-
- /** Port. */
- uint16_t port;
-};
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-/** TTL action configuration (per table action profile). */
-struct rte_table_action_ttl_config {
- /** When non-zero, the input packets whose updated IPv4 Time to Live
- * (TTL) field or IPv6 Hop Limit (HL) field is zero are dropped.
- * When zero, the input packets whose updated IPv4 TTL field or IPv6 HL
- * field is zero are forwarded as usual (typically for debugging
- * purpose).
- */
- int drop;
-
- /** When non-zero, the *n_packets* stats counter for TTL action is
- * enabled, otherwise disabled.
- *
- * @see struct rte_table_action_ttl_counters
- */
- int n_packets_enabled;
-};
-
-/** TTL action parameters (per table rule). */
-struct rte_table_action_ttl_params {
- /** When non-zero, decrement the IPv4 TTL field and update the checksum
- * field, or decrement the IPv6 HL field. When zero, the IPv4 TTL field
- * or the IPv6 HL field is not changed.
- */
- int decrement;
-};
-
-/** TTL action statistics packets (per table rule). */
-struct rte_table_action_ttl_counters {
- /** Number of IPv4 packets whose updated TTL field is zero or IPv6
- * packets whose updated HL field is zero.
- */
- uint64_t n_packets;
-};
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-/** Stats action configuration (per table action profile). */
-struct rte_table_action_stats_config {
- /** When non-zero, the *n_packets* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_bytes_enabled;
-};
-
-/** Stats action parameters (per table rule). */
-struct rte_table_action_stats_params {
- /** Initial value for the *n_packets* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_packets;
-
- /** Initial value for the *n_bytes* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_bytes;
-};
-
-/** Stats action counters (per table rule). */
-struct rte_table_action_stats_counters {
- /** Number of packets. Valid only when *n_packets_valid* is non-zero. */
- uint64_t n_packets;
-
- /** Number of bytes. Valid only when *n_bytes_valid* is non-zero. */
- uint64_t n_bytes;
-
- /** When non-zero, the *n_packets* field is valid, otherwise invalid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid, otherwise invalid. */
- int n_bytes_valid;
-};
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-/** Timestamp action parameters (per table rule). */
-struct rte_table_action_time_params {
- /** Initial timestamp value. Typically set to current time. */
- uint64_t time;
-};
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET \
- (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
-#endif
-
-/** Common action structure to store the data's value, length, and offset */
-struct rte_table_action_vlo {
- uint8_t *val;
- uint32_t length;
- uint32_t offset;
-};
-
-/** Symmetric crypto action configuration (per table action profile). */
-struct rte_table_action_sym_crypto_config {
- /** Target Cryptodev ID. */
- uint8_t cryptodev_id;
-
- /**
- * Offset to rte_crypto_op structure within the input packet buffer.
- * Offset 0 points to the first byte of the MBUF structure.
- */
- uint32_t op_offset;
-
- /** The mempool for creating cryptodev sessions. */
- struct rte_mempool *mp_create;
-
- /** The mempool for initializing cryptodev sessions. */
- struct rte_mempool *mp_init;
-};
-
-/** Symmetric Crypto action parameters (per table rule). */
-struct rte_table_action_sym_crypto_params {
-
- /** Xform pointer contains all relevant information */
- struct rte_crypto_sym_xform *xform;
-
- /**
- * Offset within the input packet buffer to the first byte of data
- * to be processed by the crypto unit. Offset 0 points to the first
- * byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- union {
- struct {
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv;
-
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv_update;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv_update;
-
- } cipher_auth;
-
- struct {
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv;
-
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad_update;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv_update;
-
- } aead;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-/** Tag action parameters (per table rule). */
-struct rte_table_action_tag_params {
- /** Tag to be attached to the input packet. */
- uint32_t tag;
-};
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-/** Decap action parameters (per table rule). */
-struct rte_table_action_decap_params {
- /** Number of bytes to be removed from the start of the packet. */
- uint16_t n;
-};
-
-/**
- * Table action profile.
- */
-struct rte_table_action_profile;
-
-/**
- * Table action profile create.
- *
- * @param[in] common
- * Common action configuration.
- * @return
- * Table action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common);
-
-/**
- * Table action profile free.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile);
-
-/**
- * Table action profile action register.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @param[in] type
- * Specific table action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_table_action_*type*_config is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config);
-
-/**
- * Table action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * table action objects.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile);
-
-/**
- * Table action.
- */
-struct rte_table_action;
-
-/**
- * Table action create.
- *
- * Instantiates the given table action profile to create a table action object.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new table
- * action object should be allocated.
- * @return
- * Handle to table action object on success, NULL on error.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Table action free.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_free(struct rte_table_action *action);
-
-/**
- * Table action table params get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[inout] params
- * Pipeline table parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params);
-
-/**
- * Table action apply.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) to apply action *type* on.
- * @param[in] type
- * Specific table action previously registered for the table action profile of
- * the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_table_action_*type*_params is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params);
-
-/**
- * Table action DSCP table update.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] dscp_mask
- * 64-bit mask defining the DSCP table entries to be updated. If bit N is set
- * in this bit mask, then DSCP table entry N is to be updated, otherwise not.
- * @param[in] table
- * DSCP table.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table);
-
-/**
- * Table action meter profile add.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID to be used for the *profile* once it is successfully added
- * to the *action* object (needs to be unused by the set of meter profiles
- * currently registered for the *action* object).
- * @param[in] profile
- * Meter profile to be added.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-/**
- * Table action meter profile delete.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID of the meter profile to be deleted from the *action*
- * object (needs to be valid for the *action* object).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id);
-
-/**
- * Table action meter read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with meter action previously
- * applied on it.
- * @param[in] tc_mask
- * Bit mask defining which traffic classes should have the meter stats
- * counters read from *data* and stored into *stats*. If bit N is set in this
- * bit mask, then traffic class N is part of this operation, otherwise it is
- * not. If bit N is set in this bit mask, then traffic class N must be one of
- * the traffic classes that are enabled for the meter action in the table
- * action profile used by the *action* object.
- * @param[inout] stats
- * When non-NULL, it points to the area where the meter stats counters read
- * from *data* are saved. Only the meter stats counters for the *tc_mask*
- * traffic classes are read and stored to *stats*.
- * @param[in] clear
- * When non-zero, the meter stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-/**
- * Table action TTL read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with TTL action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the TTL stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the TTL stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-/**
- * Table action stats read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with stats action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the stats counters are cleared (i.e. set to zero), otherwise
- * the counters are not modified. When the read operation is enabled (*stats*
- * is non-NULL), the clear operation is performed after the read operation is
- * completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-/**
- * Table action timestamp read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with timestamp action
- * previously applied on it.
- * @param[inout] timestamp
- * Pre-allocated memory where the timestamp read from *data* is saved (has to
- * be non-NULL).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp);
-
-/**
- * Table action cryptodev symmetric session get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with sym crypto action.
- * @return
- * The pointer to the session on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_TABLE_ACTION_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v3 6/6] port: remove legacy API
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
` (3 preceding siblings ...)
2026-07-28 14:20 ` [PATCH v3 4/6] pipeline: remove legacy API Stephen Hemminger
@ 2026-07-28 14:20 ` Stephen Hemminger
2026-07-28 14:48 ` [PATCH v3 0/6] remove legacy packet framework David Marchand
5 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 14:20 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy port library API (rte_port_*) as announced for
removal in the 24.11 release. The SWX port API remains.
The sched, ip_frag, cryptodev and eventdev dependencies were only
used by the legacy port types, so drop them. The pcap dependency
is kept for the SWX source/sink port.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 7 -
doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
doc/guides/prog_guide/packet_framework.rst | 132 +---
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 3 +
lib/port/meson.build | 22 +-
lib/port/port_log.c | 7 -
lib/port/port_log.h | 11 -
lib/port/rte_port.h | 223 ------
lib/port/rte_port_ethdev.c | 530 --------------
lib/port/rte_port_ethdev.h | 75 --
lib/port/rte_port_eventdev.c | 590 ---------------
lib/port/rte_port_eventdev.h | 94 ---
lib/port/rte_port_fd.c | 524 --------------
lib/port/rte_port_fd.h | 74 --
lib/port/rte_port_frag.c | 280 --------
lib/port/rte_port_frag.h | 70 --
lib/port/rte_port_ras.c | 336 ---------
lib/port/rte_port_ras.h | 58 --
lib/port/rte_port_ring.c | 796 ---------------------
lib/port/rte_port_ring.h | 91 ---
lib/port/rte_port_sched.c | 298 --------
lib/port/rte_port_sched.h | 52 --
lib/port/rte_port_source_sink.c | 616 ----------------
lib/port/rte_port_source_sink.h | 57 --
lib/port/rte_port_sym_crypto.c | 558 ---------------
lib/port/rte_port_sym_crypto.h | 92 ---
27 files changed, 10 insertions(+), 5591 deletions(-)
delete mode 100644 doc/guides/prog_guide/img/figure32.png
delete mode 100644 lib/port/port_log.c
delete mode 100644 lib/port/port_log.h
delete mode 100644 lib/port/rte_port.h
delete mode 100644 lib/port/rte_port_ethdev.c
delete mode 100644 lib/port/rte_port_ethdev.h
delete mode 100644 lib/port/rte_port_eventdev.c
delete mode 100644 lib/port/rte_port_eventdev.h
delete mode 100644 lib/port/rte_port_fd.c
delete mode 100644 lib/port/rte_port_fd.h
delete mode 100644 lib/port/rte_port_frag.c
delete mode 100644 lib/port/rte_port_frag.h
delete mode 100644 lib/port/rte_port_ras.c
delete mode 100644 lib/port/rte_port_ras.h
delete mode 100644 lib/port/rte_port_ring.c
delete mode 100644 lib/port/rte_port_ring.h
delete mode 100644 lib/port/rte_port_sched.c
delete mode 100644 lib/port/rte_port_sched.h
delete mode 100644 lib/port/rte_port_source_sink.c
delete mode 100644 lib/port/rte_port_source_sink.h
delete mode 100644 lib/port/rte_port_sym_crypto.c
delete mode 100644 lib/port/rte_port_sym_crypto.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 760b770d6f..16827a602b 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -182,13 +182,6 @@ The public API headers are grouped by topics:
[bitmap](@ref rte_bitmap.h)
- **packet framework**:
- * [port](@ref rte_port.h):
- [ethdev](@ref rte_port_ethdev.h),
- [ring](@ref rte_port_ring.h),
- [frag](@ref rte_port_frag.h),
- [reass](@ref rte_port_ras.h),
- [sched](@ref rte_port_sched.h),
- [src/sink](@ref rte_port_source_sink.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/img/figure32.png b/doc/guides/prog_guide/img/figure32.png
deleted file mode 100644
index 5215113fd9d533ff56526e21e1832bc7a6cabd04..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 11603
zcmb`NcQjn>+wX^H;XwrP=pv62BJya7P9hP}dz2v}+Ni<kgODykB8WD68G-~e!w5nO
z(aVh9qs=Iz_j2yZ^S<Z&-nQ0R>zqHVF*BRJ_r0(Cy1w7fb-ge$&}L@jVT3>+%sRKV
zOdt?yBm_c5!$1c<dE_W330|oDOth~<$~yUo;0=w7roJWw@+pq#(18}bKkakd$`1lz
z`9}GnN|a>bg+MMX=xAx01=%f+AzqmgrcTzrmcMSKUXPE8MBf)Td?dm2=at5Fjs^{p
zmUZoz(+mM?*;G`#MM7u|@ptDg6`lEVUE{oi8$0qob>5pNw>g*%t&O?<x+J2KSD?a>
zBO-q|=XcGeMp?O5Synl8XMAW!vZiJyy~b~+Q>Hy^d(^Mf(_gj`Tp0wubW$S^UX2PF
zz&$}2XdBtVOSVuDH3TBWL1PHsJdT<?4S_@&ol$x8UeSLc-VI;$Mlt-bx&-C%{Uv9B
zAOw>0c=Gh)mS;bTlelG_t5w|twn*k!^Q+q{W9~|UE4JZYOk9`!;~<cD{wT3CIpcMq
zyknJ((!Q&cjqB^v-(x(X2vZFKIoEiriU%)L%X@oGWJ9+-n#3Sk7T}^JtZIDoFG@(r
zT+oiKazck)zWedZQ*d1sH&<zdU4Q*}J)2yE9{=R{EOZ9brFPK%N<bACCJ5yzk0tM<
zbRN48l*!Z5(w6zRb!XpLwl2+vKpsR-p4NI5m2rKl9&xbb<ON*`KU`~;WESPQ>Xq*K
z2(M;ZXn;=s(UqxA7AU=)+!7NL(^2C$zjWMiaztJ}COl~gCD#pjQbFQ*X$*z#<5~SX
zQsoPvwE>tV=|D+2y2N+y1`$rZc{%}gPHpFES#SZ%smw)fNm7#PbAz88^&K3t6@4Zn
zr3!t!RClVSAP`^51;t;EInZ6Uo&iS$EX%w1w|kD|2&KHFqtnS$L$t;fIxY5>&b1~=
zZhtcCM5-=gAdnVju$+H0W+aFiDx@iRRwRE%&s_J}{A_O*LKN9?b#m!Ue`v!gLT?9w
z^imdUE+cUKQ)%+COo;j0`86{p=Z(1zC=qiRiW`KBO1(ci*tx15%l9zfCV)KdsRSoI
zu(?kKX`yRmfBrs}UpduKZSNZkhsjBMv1lSI3(NY!D<1jQvglL=PgsFrrWaR3L#*n<
z>2DJBT*M%rp%uXa>mx0B@zan<4>pxY&r@VwV)ur+!kve)-rmygSdXDzOr$8*nbf<-
zZm8mL;0}wA-}jYxP>|zj@cv5n=gj#?s#8n;I_BtNm`30FY+GAgIl7hS9SuYS!!u^4
zEe%34B&S3<TqqAmZ@#7Nk9Qlcy?3=J6{knwj1Yi*S*=XbqLl(con<HPL%Q`R4wqY-
z>(+z89V~p(b3G}>vCc-tLi-di${D69bkwty!oQ0Xm^CW0FPr?_P!!u}=wiEYYtYYV
z^+R#31tR-9*cXot&b#fdP6dR{cV^6%rZe7c*!?cOv|UTCcOM|G%0}UDelT7zvlM|p
zEH2|T)s(G{Te)7ChQM!r_7^w0Q@od|`a}<2x87h#YyM=4nO8xppoD{Rg+l%#7*E-Q
z9dh{@rJKo5;a{0l=e(EGiqVGf`X{C%PEJk%Ht@#&pEJudzZU+E;OiQ2E4_&oKUZpA
zo|()dxc%0<f2vE>oT-4cS*=d*S+de5-B1-ns`{(%7}uB4RCt1boqL;;BU~A>1+$5z
zjuHbKJ;QoM&PT>P!eBya!8<)0afJ6llJJZ~EY^F%3wtCIIx%2!AU-4U7-iQSJo84|
z!-#!LilEkbWqz^B!abkW%X;z8dUaUArYyl1r90W^cbcvnJmb`c!&&J9%W}H_!8(lk
z$zGSjb9du05Vm9E*gd~H^^56rZ%M&#vUQh1W^pi~v8oTNku*<Y$PZv!PUf?EyJ)g}
zp}6lYgEJ<bArG?@5g>ebxT4?A7g~%k(HYlPH-(Fch+sYp^fg38gtFwoSK%))Tj^Ty
z0rJ?t$jR-Qx#}280y)3Fdm7}db!*|U#EHY}QXf(W?p|FiVmkKyOvmXKZzy~z_0cK%
zVcj`gPxIm4Mw?AA8Y$!SvXs@Xen4MEt`w?Zf)>&~P059i4Fa#%`p&+TG%w(F+tnr3
z^k?6o$0mk?e-%}@Z%Z<%NmmZ+EKBfKUTQmj=r)E!kF?qrhvyn!U!?(wwC}Zy+(&Uv
z^l`?uhfSLcJzohk7Vt+{jNFww4t^kQSYfUEpOQyNM6|?=_V48T*dSXk+Ro&4cmE_0
zw@T1QsMth}ek`BjG{%cKUROI(d?|QhYjI#?gk9H{DR0+!$!`5ifyXYD>CX$Jh?)Xo
z5)5{<)iqHUiiL)Tl;ZrL531`asXaSY4T0m|&7r!&!<Vah?dHv!m`+x@w|?`TLrTl#
zM^$ljL>k9ef-Sj@#A_k3MFug*-1+@Xq97N)Zj8Xd#?dG9?WksketHpgu@u3DU-sqF
z^z>)V<)6ELeaakQUx%4_q;0nvq*Q+b6=l6vY^Wy`*HRm{S5fCr^&sbF%(?B(^N<{U
zDdhL>-{)q2CSX(^w470%HCitfKxY=P;eyt3JR28>(IpunEj!s9TP0>p_9YgjOF{zt
zHxh7S)F}wtQ!nwodz*cR$*c-zp~IGvC7qh;5r?~Lb3es0<zmiBNlZxZZn$(IGb)~#
z%=3pCNGNGbDaCd=wZH$HGZyVLb$z5s*{%04OTU<c`ym@0SKI8rg5ooFfs;0_+@iM-
z86shV?f5H5czv!j!+m>s#D(sUKPO?4sl+zzm|F?duGL|ydMv(0f;5I&$S4;d<~+yl
zEKTRmbVVA&tVb7uZZSp2Kp-09y(*~$W|iyJlzJ-UjbatIRLcSR{hta-1%aGlr0hS)
zbxlfqXo&xJWp}iO;Z1W!O#JK2<ITeD<7R#(e;@gtd_}qxmopkSG-AXeKX2BN5nY})
zM~Hoe9iM|YY)?bhd8LrgRjgIsysjQCL6FDm6oQi8y{qPd)MTC53{e)?jZmB@=~SST
zAUd~L-Vl)A4#KEQ&TDiqah<i1{f+jjmI4D(<15-@NTzl);^e4I6j5l9A#>Gh^a>Q`
z|4^QIus!0vya95RyEVpx2<r=+YND0(7`#&HPc*Sih+qKcj}of@H^x&o9OkVD(rT4!
zk8sI+Qet8XD7C2_X;)pghAP94LJm^0;Pp9i|79U=>m(n?38<3pptUK>^C_E31w2`q
zWNG^V`6As^rkbp*FC6F2&HWX5R)q?p;o(}G&8oKhCHC$BM2OmT%w!d>f$|)|%>LW=
zAO7H1!qXXaFla(bLr>BD;bT+KPxX%SFz)9AVc^vUmNTBz|8<DYXl_kwMs=fI*7;z2
zc`jCY#YbMFqs+d+YdmC8YGcqbt|rx02^4K^wXka9P-S5Wl@a^V$?@t}RwzoiqY+gj
z2dB@f?)X*n;OE(mR>^WRhJNELWkm!K7G>{-i;Q#Iaqz_@a+wl{o^f*cj<VnOl9g=u
zVUXo1yhrQ1i*x7!yO=|o^_*1{6+5JNgIJiE3LaEVuP37_MUI?g;<@C!8co@oxwyE}
zK%&K^x(-&l#HFZ5)PvO2jp7Z++n|>Nk8%EF!)4=q<WtGZftRV{6`^wk5xXw>&YA8%
zn<u%yD{~RIbEQA8MoEq(=}c}e{GzPI_nnJo8fL3KM?IVz=C@W7lag?yHXPUD_!RGB
zyv9-=UOi6<+2@>F2Vy=?Z;YM8H(f%XP8Xo0$8S%gjC6EPKa%~cHek8p6dJ~RP4)M|
z%*;H(K2Kc+KRPJ>+o6z)7Z>Kw{-ZDNDT!zyGkb;8P*UAKe`lQS_8}fjZxZ{gI!-=^
z?fLe7u&Vrk3<cq(TuS-90w-4&y5r?{e7M)5U-(WJEFw7j5KyVi$ptpOVd+EFKx5U(
zngAJOtM9z>dBXr~@QG@ZIl17^`{r|!QDVYzlP^5Zs89)o{Jv+3oc+JsjQ>dk|H~gW
z)(x`-<FpUx1;g$=W#K1*Tv2LU)BC}$E;STA{|E$F3ed8BwSnH2rbBxh^Bsf|OMM_6
zpv;lt!XVGQeEG7y3|gxPR?e2$sFEUH50A(ZS1Dx^%1nx8eQoYGQIB|if@S4bda%Dq
zbYu}wx$CrR`|19Z6qVqLpWiKc&Yvq%rX(b5m1uV%{%AU88Na#q?C+IGe)aIt_H@O*
z#8*Q&cnNW$p@CAHq*%FSzUigP{q(XFX`dv<ncltYit!klhEdHhBEW*cZ<Rh}^a+3C
z)RvT(?9Q0sVBEH}(39)AKw}gLGF9a5ZV@lE7Yxct`z>|*v`LJ+(m^IDfBs8@J!OR9
z(^+1WRo%Md;5+^8h4Yt4D(A*1TFk`!D{k4*Tr4MuT)VoEL~<oa#yhv2>S_JHJ!f-U
zE>9Zz9>dj_%va<H7F(mvL^5}Ox)^SfJR$$5+t0Tmn0%RqFON>mtxkOn5Zu~HR}Brw
zM|>8`4C}?*ql-fw1uhLvZ9|L%DHj-$-~Z#2V{?){Y~Z=CV(9h<XefzyxXR76cA1|0
z;w#a<hjPz}jr4+5%^S`5tO8k=&gwb{o*sm3mfc?4G>)&VZQ44oApWkoy&gL2<=n%q
z=DwUan;>&x<ESXPA6#GRRd3|pOoE|DNuJ;`GFH0bu-7yH9G@zg3;lt*Nd5OQO2O-S
z#GYL3Jtu#3WI;|Eb<nWO$??(Lcqkbzk2QyL+jXHxgODal6~IgC3zw^<@a$FwlI>)}
zc71kk-vqv<lKpc@SHZS%X2+Wg+Bj`VYao>}68gyHj_z8Y8~(`DdxYPiH`gsbXHORo
zVgRDyikGgms&p>%j}d({@zEjLsv*2?sQO_pB}XhL4Aq4O9#n4+Z1`WS|L~z*tzZ&(
z8iRxCqFGbyz?Oge+qY-^W?I;4PbhL$!E@Mb*7FMI?P!E1dRHcLbSf$3xr$fH3lE<*
zJ;-wb>;L!7BPGig+*hD4JA(DTx-%A-SwaQd?$H)Z0ZW~Ba?o(%C%;w&Dv{sbx|1b!
zudG88O&?HRmein_zGyLBHGBT&m3xukk1zqt*0tXhgD6ENDvDYbPBNq9RIqWjH+)w{
zYs%=Jvw-d26%n+4{-xd@JaR4VDYDIf@LlUBe2a@J?6h|mf`&N@xBh=h3q@C-vGB_P
z!z-7o9fyg*{C1JAlV7llB{i@}@m}?k8z_VN#XX(hUHi3d8vsHV_K!RuJ&7^~PH$;@
zX{d79m)I-P2TJCv8-2hodk&T`F*Ye-sG;!wGN}7b-{O0qR;}tn(4ZUz88pqm<dpOf
zFMrYGm3$exRFkgg_k(bY{vY)!l@X_YTs>5es0}9OC+h)Suv`(ecE1v2*@L^HQkl)M
z{IWJ!FL?eau<Gfm+aO0l^$DO@IomgbP1iATynVGY;v~G%b3|dsb$dK`p5JeEQq%H|
zezxCe^~3EQE^`ojkTbaH>HB>sQ!!cJncJ3rBjE0qtsQjn`zYOJ&EgHIbQp8k7Qu2E
zLy9U*2p=Jr|0;sx`y7i|pW50NqPH^?JX1>tthb1m9~k$6&a!gbn)?GeUsN4`ym~h;
z3?tyzIE9b8dczs(t<4HW63^dwI_RT95p(RS|D634J<Fg)hZ)6;?(dMj)%F)I*z}7y
zLX}udGQ6kE&TKTVCod@nu6VQ!7Zw$@&|M>Nad5oXjHVlch%>^5wM$cx<$cyrDkNgt
z%BCD0`*+alJsSf{;E<QC=d*sn7rL{XYQ(RF!U*X=M%U?;BUWnW1vW+|j{A?*s*1dN
za&CH&Uvl_w)yBwB>K{YKWlhOQ^L+SXKSl1AnW@rVj<^)@Q|&fFVBmw5<065l2!i#U
zy|d%G#WCZ*XM5<h>Hjr@oPbKYZG5fY$tNRPohwny5a}VfV~~E$Az)?H>e!kiXX~JQ
zy6quw^AN}ze6hJC)?688^#_lv^Q#)5@FZuG8u-e6s)52XH8Hs#{mI*5d7wNK8d|?3
znB3IV)Pl8jj-kk(>xDjWu-Pq(^^$Q3ryTiq+t$1rjxfM`Y2K=S{m&8gu_SB?toXe8
z<Q&+S=tckC@OQ+b%c}*wAFO1t=CTorYJ0xb1<&8kyjcVPzx+;_b;Kg?@2Fcr6(TDZ
zgE!{P88Tra_()#nk84w<p*t%9rOk&*HTHSrXDKj7(PiGSGHUYU)9fBrN9wbn09LwZ
z#0Y+0+1t2A$=ohCl1B)w2gB~=i4At8_ThU@He~HDmN!cqGQ-wiNPg$~C&D#Ls;clT
zLMAae`#06rTP`RtP!Lh)Jdx;&zE!aJ_wv>I-xw+#zS8Y1NQLP2$uj?W<%@vWpo`3|
zZ7C=0NX~$yi*j^3)>R!Zv6NOGGnV1M5glD+=)(~rD#rtz>H+7Lzqe3|9rq12(?@8^
zFWfFKEpEKYBVYat#-{&w{<6O)l2tc1?X(x~^E^;EQ@HGc8WSToiN4ldNLA>?aJ)>e
zMeO20c`c8SYQsLETtZ)+!wHtZ*~d+kftzneTu&}Q$5}IR+9vE+PMT$HOnorUy%jK1
zJx514#^q%c!+SELqfkvnvA?i&lU;@)1V59tW*zwD5WV?K65o+~8BzW(reie{So@+I
z+HnHt<TrR7wb;!^9okw)7bPVtrBtm?5mS`|y`I2t%tyPt6EpX|U5#hKpMPR7CZSKo
z0f~GXJ9!$<_C!A-!j9GmqOt2QCKSPBfLD(aGt!Q7NU$)36bX{zQpyuPHM4=UoNDYh
zhyx#L+yFA2q){BNQvwQT_Jts7#iU|%UoL?i(j5<|4<FOhw#>sBu>xQK1K6xpsUXbU
zjqEMiAU(dvc#aIeXp=vgwLjUnRDQIVubaG7;WdU^4?S}V(%lVcBcI8FZH=!}Ywc_i
z!E}etpq~B;Ah7>JDC4#9v)YIbcuC9t-G$~@5=DHpTp+E3s?ImkrLyES`Q_0ZKu0Tj
zk*z!;<KkDx6e9WhG=$MA?|?H(4KiM&6=d5g1l2J7jXQImJE#_%{SG{UL^9WfO!SMP
zan2)|$HQp%x&5uh0{t|FGEv#U@!-O}xioLvi+<oVa=`rh<sY)wOe%(Kx>f?W(^uo?
zV#&@w-<5eaK~&#Y#L*fJbGjAF=azg0*tiy!dz5`j9Q>3UyiY8=uy;V+$d118+j(K_
z4uG4h1cDM=vVNs=M@2{(PEjvIiO`-ZFF7mJm%21wH{$#nxVG9<mApxA5vBZSdRClC
z(AmaGX8;u?^9wfC=L?;HgTbgE_WiNi%N(4XLyi{O^Qg=kumM6@_J<^rfx1^cBeK79
zCk#?+a=1|UWZ#d3N2O6}up|{xheo{?PmdTU`jyuc<^tmxVy)CIPh3W-+!D6P_r`GW
ztL%>k64%)gDjAN=u_>iCSe(gL$j*u<7usJmDu;q_DR4McE|fxEDF`wjj|`sUuDsVs
zEgP_OH<TrYOIjgA30|>r6EJ2itC{G+%XN}?&(Z20FT?a}pRTv`VMqiqM+#dG{qc&M
zb9)HDU4&gcsj7S-xV(P9c+4Ur$v=8Vb!XIZ0FWlMdrv+{m$A8-X(|rYBy?BP6Q;I^
zr2d?ZZj69#!4V~W{+8!nJ)`lA4ZwTXY%XIbaHXTq!&c2CXP&cN@CZs%4aK+(Rpb+U
z^JAD(bG{TJp0WyhwGC?rK0m#ZYoUb}r9*XMeIyoCk9U6s*mMoNb<5P*qGzKWRzvK+
zXW>^G{Kdh+F{mcZh((64P>5!iAFy@XHN%$v0>j}XRH27r%QKsk%FlBhX|;g)uBSzv
zxiJ5=(tY4E5aI7D-74-sL_r-q02A8oT?ZxHV+^Spx-=ZRJ>;_dMR2(iXd#=zgZqWK
z05mIzzifDgWTCZzZm&!<L<AcVYKk2z)VWH{k-!%qMi+Z>pVjG=u?+6-9lMZJs!DOi
zSK=8U-A3}j?JF#}LfELPR@@#R0SM-C!}>C{>!qkd)+fCbnQXAaG*oJH6$^J4Jn}8G
zt(k`T>PqEVhqdK;>l0@Ei2u8sfErv~+P;@$3xV(m%dflsh(91VWJ0W)IX0VLaXVrO
zS(YP^*2$bpptb<hBWr{4I9*3u0dh4U=iRHjsFxhqPG`Z%^#?0{Hdwr9<Sj1&!w%jc
zN>@O)OX5Ix!0w|#>2s1PcUUaVj`7JID2b&WKcmEK2Qa-Y+V9+cra3_^HM9hAupQ9(
zW0KFAlv&(H%~*_kj3mkHm~SD~>u>ea&$DcuD#Y_s^)#s<i<mnmP+jO``|u$GM83~9
zK4ju>iZ#MVeyS%h!}>yH%2yfo%<z4;R&wh(DeJ*tIRdMh6nv=Nsrbb_Jlz9Xa#9IS
zCZBfIyAyWVv}3}`*49JpP25?yclvJ|t^mV}k8sLlMC^P%jU>5H^mS;;*t6S$n_;V_
zy4luZ@=CVRao-xkBKS_y&0vhkY3;&>t$v$rTYoFtQ<>ISFHalo{NhN|JnVYV*3pNT
z>h<bL5mG-LxOy~JwLD#^J@k{ezno&N=E-t~<pnK$YHsKC{yYV1%KiHsj1T3GtL%Oz
z7`||a^P-%@Au7#gG^)_KD0nu}QV(cOsJ`67Q+dIN!%rYjtk!sqDIL_7Bt^NrTX-k;
zH?GiEIIpHxs!?gVq$2Zn-N%pJWeH;U2WFOz*S^u$WJE%p$Rt7u#!grGo5eNyu9FWW
zSK&bZ3qhBy7k81QxAqCUe!a&^6K02N=-pq^p#G}9Eb95I=>@Bx<x9c32BV1g8UjN_
z9W%s-*<BV0HQHpY$xr16z4^N6ef}$t!km=KXC|=rXCH0M0kboTl#j6$G(-pN_un>F
z+{2gy0U3c*sxL;HAf)A&jn+Lc!MUxakRi6EkMGPW#TNGK5WI)0ezKfnw8QN9+cnPT
zP1~3qb*&$19A$~?Y^7=?G#v~~YR`#nG)EjPW83T(b*1ZO1ZW{bCy3*{d9OtaCKqAx
zRIP=|(s%Nh>hq2$uaOeIM27T$mo0iY3$4pR605W~tbMJ_l1aYRB$H+G#i~6G6yh)-
zo>a_p$&6Bw)g=kR#r4I0ABgfn$Gh^&^bn1DV|5E^mmt6r=P?zm=>oaKznRr!{J!zo
zYhSbb4PILoc}{NL7gRZ#CHvb5gKxv!s&Kau?BLtUl$bBX?`lELzI&iu2qE?@9NN+t
z#Qg^6|K6s1K1#E$q2@pxjDNasL6os9M(ITs@4o1&Oo6D{yWY7jg-diUkaH#ec+JaM
z5TKV#r$*cZcuZc(2IG$=*7{6EaVvPdx5D|ON`3<0n#IDVVhnm(pg|TKqZUz_ue?<S
zBeW*U^yTTWZ)^?N*P6`vH;XW5wOam%gI|c}{s)w|E)iq^;GZ2&yT4oi2dmb7oUN~-
z*g1eZ`DV;l0pO{y!g^&aCnWt`&lNms*>2R`x(koFg;YIU{d!Tb#H;5yR?@Ppx)StP
zUH=3^<^QnLmv?EphTFe`rfQ_?^P8(-fb!^TYCammc&3#AGNUp2O*kl4P<@<FH3Sbh
z;aLsv;eCm7ji!Mss|;CS8P_<{8gJsJ!p{KJ0}-;57%M>l>F&I<GFHaH|BO{o!5*=d
z2!Pt@AyDxgkwMd^DbCX}4GEM<N}{Btg{zf*GXN3GVd><$9b}14+)C|X_YKw*0o9Od
zo|%%9!+G_9mHvq1jm$DpJO9e)yf}u(MIh;Qa*l#U1kQ8`JPeG3GojcVIMdiWjT;+X
z>Q}ig+xp}$1OZ9V!DSydb%&FZs8x1G{kA^?JINC>IRyG0l@EX2vWyPPPuin+<eiC#
z3Bos~#>#MFWsdhm{kAGip6)4MkWalv;%T(>^C!8@!E>$(6lGk0wDFzGzAAZ|^BSkX
zuQMw2%sdas_Z}Y>puT`=<U)SMsZG<hpWnrZxa{`tGDzdyx16{_YL_ei5<aB*B}OmZ
z<jbY_6H0fuhdpMJNYBc44J_`o<he#aAUJ3Yz$1Adb92=e>&5>F93?b&pH0Q4%5@4f
zDj{bqKmF$1&l?8y3g5Bl=i<wt%F4+uq7(!M?%!K1yX$emLtOX~F8F9`0IDA%H?aV?
z-+KcT6+ne}y1t9&dG!h(i?@|bqH5(hxVUOf_KyK88)4fB9D^s9=yXM#9N2G+1x}<0
z9!}B&at*5FY}r|62#{Brzvb2QiqDKl4g8sZkMRE-wErE5r+CYM>3{zV`}-g0y@nRr
zwWkTF*6(sK{PQOw%TD8;g9~mvV_AXHXfXl5A`Bil$a-^N-9OpX@6GY@hIeMFXRfam
zNdpTj2bx<K1!KO-fSB94Or7%tII)%*^Ad}ciVB&HLiMAc1PHhzNW9}j_<?8eq#2|R
z?BOvw2(X+&g;5T&e_p4Gr2I{anI=WFQxI*uEb6*wDG~zEJVZ#WnCX302=$rYzlT)=
z)KHiad%J37pj;3fa_RTSpuBn*WGFd-p40vLFC3*45hn=c%=u_mHP=((kxwc9vE{`)
zGPJB!d9KQHq~8Em=EImZCH&ux4E)z6;~CTQ8F};Z{&z-MAes9>AON`x>XWQ@{a%42
zci-n=KiLN@@ga(q8EwEL=wZFaDAWQfmE#OvoWXj|`tkhG&%O0p@0*(NnF|lYPyP++
z6ov_h;rS7n{3=1+e98gsNwtAwfsu&=u;Dtu*0uflURw}>_g@(uN^E*~xchJ;F5>X3
z*Ww(raT~)M_qB8&ofH8Bk$j?kV#HWSxF{uso}Wi-_GlM?s_zUyNm)U_=2KNL0wHOx
zKR*oIqO8~GHNVL(RF+H-jn4}QAYz^8W|Kj$;)e=oB`AC#e$va^P(?~TapbqTdc7#N
zKDn*6bqPc53OG$WfTA8X7<|03>3DY+&)@eSkM#!w1m1kfwz@m%!VM{;agOPo!`WYV
zrYKF)qai|1un75AW->!tnP{j|Y^-GlKz6nE4h|012f5+I3CXqOTFLK*>j(TTTImz&
z`w=B44MocP<M>btJ1(2UfDZ7%;BUUu(Yq(mm2`4kelhbe@Gr55g8<6}RRq}`Ww0LF
ze_|lBr`nHh*;(6+aM*2lfR`w0P*G8xJ83d@&&F(VY5E8f7K1gz?R)Im$e%Z2DSABh
zxOff!N~+Pq`pDxSEgp6$BJ9Yvp%lHKQUxX0%kQ^cS-YhGRNzA}Z}P2+(hdn(oBkfa
zFBfqfRyz)Q8PI{b&{6LL^6(7V$v#uU#<ld&7$~eov_)NbfYPDU3NT!QX#6|2&G)fn
zzqp8H3I>2uc+kvcMz!39m!4)?YC)u4OzI?}Zw<(m4oafNh_AW{%1cu;Nx#T(Nb$$G
z%i1M-%D3T-ZF4_4Rx7fvzC_jnU}9sTfu9XJDqP+46Vp$9V4s{i%^vZhTHC93v8;B~
z;${eYUm-i>Odw1P45RqwzmyBe0gV|2R~^s#W^|YR@j936y)O`(?TI$E)jdA8KV0fB
z4;FElC39=WUF=$rsRP)$zbsnr$6x%%HOF_~Oj@g5xKYUAQD9-E-&UV;ZB6teyk2qW
zsv~_G=}4{KP1$@S)EBCxzj^FJD>BZ<NjiICyd)AOl#xbKT`u?a?ZcAb0>oDTh{r$@
zxVB6m9#5Hsj+GFVF9o?N5(51x9dj)>nCU2A%_t$?%j7)_480Qi*FgTTSmF#~Q@{i&
zj34$@;?^uz+~t$rJ-BVD(1mjU^xi<{LNn;1z_3RQzUuoOynrl?;LwKC`WD%4%E@7}
z*jp2TYSe~(t2lnE_;C91-d1^pXB)Cpe=B4(O$iR$a|f;tu08R!kvw{uUGzN|PQjUY
z?X|7p&Xx?Zoqbdt_R$Q-eV*-{yDE=e@;unxFrc+(U^(Z#=hr+yi(;f$Iph~friN_#
zhV(YrNIwqH0HdNuEpZUTo7p<dhVb)ax&-vvWHjrr?iR^f%)yxkinAPeygY(^rj}u<
zzpfCpAATOL=`Ab;CWbz&asg<gR<X=Z4fI&g7cSadv#`a?xy=tu1lsXo6Q%;0CNOa$
z*}lPVajTo$iLH_-)Y2cPF;t({lcUz_=nt10sM{HL9|-@J+TVEeoy^NeNV<4r-h(nN
zywhw4Mw3d*iRCQvrSxJ*ASdnjblZRC61G%7XlldQwk$c^4^+z#(OuAr2Rgy-#dJHj
zKYssvZ!p}*+tXUaJ&n!39$>9}AjrE>kF<CmEZbP;ih4&C-om1~^7qYMo6L@Sk9eJc
zCE6A=zc98{Eo#5xZPeAU24IA<m<{tby5$>i01gw~$F@~=wE?BUK;4cBm@fjpuq<0V
z@22zJP;g4H+-+Y3OljSo=z*=_MI25tP-J_Ac3WqL^0Kw>nrhknLXFbX>&t-Ide&Ks
zaQYMO6g9&yqZa1f6;g-8=KDo2h=-9U8Yb#7#iIE;xdY1n3-{v4$&*EU`{!yVQ3Vbs
zb8Lz5Hk1%Sq+u#a%EtM?_9fi`%{*=2?CRHNtZ6Qpi2kG<&`}THNShe^6%_IdC4CFX
zw!O8u2-_(>6#{K$!pmc&zK4gr13Rafk3|wl@-I4v>;rCxBTx(1;Di%eNF=U6w{bsq
zb7F!NTI1Fyy0KDAwpeJj7$HAImyxP-x(keWRgP2T-CG+X2#`FoBfoOctI4j2h3scb
zN>=NBZ}St_%&t1Ma#-T@8%h8-8J_655T`N?lkDwcJvPV@_uYYYy|ac8notpc%we_g
z3*~w%gxIGqL(vx)H`UDkj3MREKNa<+=K>{7$oe16e!HWU6#@~~<UVh{qkxYaq&M6m
z8f^rBEC<RpQv3p5?mpktl!-DB5&vzw|M`&$QWNyH6#%q@=Wjwk2lcQR;C{s_+v@LA
zs&M_$wvFYT%oT|&+P&AoDn0Rk$BB_*>XYHxUp)YO|2h{13M4MIUCyodTNuzyW$$VL
zGe`ydsoLcDXUXK=s9)DmE%$?cXT^Y}_j|zVx~>3uXqkWnJ%PbPa>R*bL!BjVQ}Fuv
zJwRXm<XeEQmwP~Ch))K<E`_2yfTy1z<dI{f>#s~8cAyr0a-@SJJjztz8EDS*5(>xw
zwm5@E-}dN+xgD+HnDZUMv&a25L{figTAfZrf#4O~#3CrZ?O<eX9@cAWVd1Qf-<;D5
zzYvsj9{kj|XDDNvl-O|twbp!<!DaOmKuo$Tc#o$OLS2sbx3)uXEQZ|_{8t?YBz|#u
z^u88lLQ#b$FR|mxaxwTUDJf}~rHSON3895#P4z+qm<5DcAK#E&1zhGmVBhI9-M~D6
zJe|DFT%gHAV+6RxWqrq8&<u>Hzn;Uk4^W;gm~Cj&fxN!Cx&%1K2u|Lzkh<trj<gNt
zQi-A*#hx+qE4`ybopH;n2Xuo6c!{40rS4@V6y#e!MR6E%d_Z}^ZLqv~3|Vk70<(7o
zb5`Qq8eTnB)FCdFvKs)xYE6_dHT40eqXXm~$G_uTfU@a0#i}w1i!a}#D%t@PD9TX%
z&!fTf8JuO;ASvBhkAXV+kvM%blMI_|nOAQ4HUuzW$3JeLIH4!yzrSQs@Y4*@`JX2c
zhy{uSZh6={;JBc#Ph2Eu4Uc-Ov^v0E?`SyQlC~_qZNDU4znjBc2=+uQxN*=arZf#p
zG}Zd(pO5E0+}xYb9Fevc;tiS5US^VmhD<CT#kuZ-L7a{}odjE=!V@IOg~KITBqkp0
zB<jU4%D5zGu>sxy<YjYvruqc9+XXx`mw#;+&&8l0n$!AOk+u#xVMSxMIDcZtH+y_Q
zrq;E(l-nZ#%Iq&#f208wT=uTs;p@|}u-&O=(2JBY6x`77?jHn_GKhn_KT*kg70;k{
zRT_$WAUJ?Y^7t#ty}ygF6H1wbY~{%LBli-!e5-Zizc2+m;tLQ*N3+~ZmDvqB><u)b
zZ8}FzISnvi8^2~5FXtrbpsOyj7CkX>nn4zz|1beaz$f*aAcTnarK7~$sgg6m@kIJk
zJ(A@kVJ7|VdQum1#Z00a4JhU(OK9`>fXsgFMg<^x%0?xaM}5Ez;l(dfgKm(~IU%2?
z+6m3`!agCu3H>%ptFubc-~SQK#}XaCxWVXLB?z5u3+ohdFzwo<eiHVhqa{_@EMc(z
zcz>}>RFx-R-M#<PhzlnKGLy6)fmA~bcTyoyvu(*~&K;>vTegS>cL8HWvx}b_0J39q
zV6rVhtt%|ive7i5tjrqSn%G;2O05S&tZATr;8Hg!Ib`%<Gk@8;6c9;+haesMgF+E6
ziF=a!<LQH6fP7<&QU7pn+%Fr?mBIX<zX;_r_Os@{hnM_&nkjzpf0!1gNPlX_WAzQC
XpF?WbPu~YeLUe8#Xq8>R7xljYKq0l$
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index 98cf3be109..3b5ede7dc2 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -4,132 +4,12 @@
Packet Framework Library
========================
-Design Objectives
------------------
-
-The main design objectives for the DPDK Packet Framework are:
-
-* Provide standard methodology to build complex packet processing pipelines.
- Provide reusable and extensible templates for the commonly used pipeline functional blocks;
-
-* Provide capability to switch between pure software and hardware-accelerated implementations for the same pipeline functional block;
-
-* Provide the best trade-off between flexibility and performance.
- Hardcoded pipelines usually provide the best performance, but are not flexible,
- while developing flexible frameworks is never a problem, but performance is usually low;
-
-* Provide a framework that is logically similar to Open Flow.
-
-Overview
---------
-
-Packet processing applications are frequently structured as pipelines of multiple stages,
-with the logic of each stage glued around a lookup table.
-For each incoming packet, the table defines the set of actions to be applied to the packet,
-as well as the next stage to send the packet to.
-
-The DPDK Packet Framework minimizes the development effort required to build packet processing pipelines
-by defining a standard methodology for pipeline development,
-as well as providing libraries of reusable templates for the commonly used pipeline blocks.
-
-The pipeline is constructed by connecting the set of input ports with the set of output ports
-through the set of tables in a tree-like topology.
-As a result of lookup operation for the current packet in the current table,
-one of the table entries (on lookup hit) or the default table entry (on lookup miss)
-provides the set of actions to be applied on the current packet,
-as well as the next hop for the packet, which can be either another table, an output port or packet drop.
-
-An example of packet processing pipeline is presented in :numref:`packet_framework_figure_32`:
-
-.. _packet_framework_figure_32:
-
-.. figure:: img/figure32.*
-
- Example of Packet Processing Pipeline where Input Ports 0 and 1
- are Connected with Output Ports 0, 1 and 2 through Tables 0 and 1
-
-
-Port Library Design
--------------------
-
-Port Types
-~~~~~~~~~~
-
-:numref:`packet_framework_table_qos_19` is a non-exhaustive list of ports
-that can be implemented with the Packet Framework.
-
-.. _packet_framework_table_qos_19:
-
-.. table:: Port Types
-
- +---+------------------+---------------------------------------------------------------------------------------+
- | # | Port type | Description |
- | | | |
- +===+==================+=======================================================================================+
- | 1 | SW ring | SW circular buffer used for message passing between the application threads. Uses |
- | | | the DPDK rte_ring primitive. Expected to be the most commonly used type of |
- | | | port. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 2 | HW ring | Queue of buffer descriptors used to interact with NIC, switch or accelerator ports. |
- | | | For NIC ports, it uses the DPDK rte_eth_rx_queue or rte_eth_tx_queue |
- | | | primitives. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 3 | IP reassembly | Input packets are either IP fragments or complete IP datagrams. Output packets are |
- | | | complete IP datagrams. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 4 | IP fragmentation | Input packets are jumbo (IP datagrams with length bigger than MTU) or non-jumbo |
- | | | packets. Output packets are non-jumbo packets. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 5 | Traffic manager | Traffic manager attached to a specific NIC output port, performing congestion |
- | | | management and hierarchical scheduling according to pre-defined SLAs. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 6 | Source | Input port used as packet generator. Similar to Linux kernel /dev/zero character |
- | | | device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 7 | Sink | Output port used to drop all input packets. Similar to Linux kernel /dev/null |
- | | | character device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 8 | Sym_crypto | Output port used to extract DPDK Cryptodev operations from a fixed offset of the |
- | | | packet and then enqueue to the Cryptodev PMD. Input port used to dequeue the |
- | | | Cryptodev operations from the Cryptodev PMD and then retrieve the packets from them. |
- +---+------------------+---------------------------------------------------------------------------------------+
-
-Port Interface
-~~~~~~~~~~~~~~
-
-Each port is unidirectional, i.e. either input port or output port.
-Each input/output port is required to implement an abstract interface that
-defines the initialization and run-time operation of the port.
-The port abstract interface is described below.
-
-.. table:: 20 Port Abstract Interface
-
- +---+----------------+-----------------------------------------------------------------------------------------+
- | # | Port Operation | Description |
- | | | |
- +===+================+=========================================================================================+
- | 1 | Create | Create the low-level port object (e.g. queue). Can internally allocate memory. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 2 | Free | Free the resources (e.g. memory) used by the low-level port object. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 3 | RX | Read a burst of input packets. Non-blocking operation. Only defined for input ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 4 | TX | Write a burst of input packets. Non-blocking operation. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 5 | Flush | Flush the output buffer. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
+The Packet Framework is a set of libraries (port, table and pipeline)
+for building flexible packet processing pipelines:
+the pipeline is constructed by connecting a set of input ports
+with a set of output ports through a set of match-action tables.
+The current framework API is the Software Switch (SWX) pipeline
+described below.
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9dcf86098f..75b56b0e10 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* port: The port library legacy API (functions rte_port_*)
- will be deprecated and subsequently removed in DPDK 24.11 release.
- Before this, the new port library API (functions rte_swx_port_*)
- will gradually transition from experimental to stable status.
-
* bus/vmbus: Starting DPDK 25.11, all the vmbus API defined in
``drivers/bus/vmbus/rte_bus_vmbus.h`` will become internal to DPDK.
Those API functions are used internally by DPDK core and netvsc PMD.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 50b0d3ac06..31b075b3cc 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -91,6 +91,9 @@ Removed Items
* Removed the legacy table library API (``rte_table_*`` functions).
The SWX table API (``rte_swx_table_*``) remains.
+* Removed the legacy port library API (``rte_port_*`` functions).
+ The SWX port API (``rte_swx_port_*``) remains.
+
API Changes
-----------
diff --git a/lib/port/meson.build b/lib/port/meson.build
index b597772872..ef88b917a3 100644
--- a/lib/port/meson.build
+++ b/lib/port/meson.build
@@ -8,39 +8,19 @@ if is_windows
endif
sources = files(
- 'port_log.c',
- 'rte_port_ethdev.c',
- 'rte_port_fd.c',
- 'rte_port_frag.c',
- 'rte_port_ras.c',
- 'rte_port_ring.c',
- 'rte_port_sched.c',
- 'rte_port_source_sink.c',
- 'rte_port_sym_crypto.c',
- 'rte_port_eventdev.c',
'rte_swx_port_ethdev.c',
'rte_swx_port_fd.c',
'rte_swx_port_ring.c',
'rte_swx_port_source_sink.c',
)
headers = files(
- 'rte_port_ethdev.h',
- 'rte_port_fd.h',
- 'rte_port_frag.h',
- 'rte_port_ras.h',
- 'rte_port.h',
- 'rte_port_ring.h',
- 'rte_port_sched.h',
- 'rte_port_source_sink.h',
- 'rte_port_sym_crypto.h',
- 'rte_port_eventdev.h',
'rte_swx_port.h',
'rte_swx_port_ethdev.h',
'rte_swx_port_fd.h',
'rte_swx_port_ring.h',
'rte_swx_port_source_sink.h',
)
-deps += ['ethdev', 'sched', 'ip_frag', 'cryptodev', 'eventdev']
+deps += ['ethdev']
if dpdk_conf.has('RTE_HAS_LIBPCAP')
dpdk_conf.set('RTE_PORT_PCAP', 1)
diff --git a/lib/port/port_log.c b/lib/port/port_log.c
deleted file mode 100644
index e7a10d80ef..0000000000
--- a/lib/port/port_log.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2024 Stephen Hemminger <stephen@networkplumber.org>
- */
-
-#include <rte_log.h>
-
-RTE_LOG_REGISTER_DEFAULT(port_logtype, INFO);
diff --git a/lib/port/port_log.h b/lib/port/port_log.h
deleted file mode 100644
index 28d75ee48b..0000000000
--- a/lib/port/port_log.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2023 Red Hat, Inc.
- */
-
-#include <rte_log.h>
-
-extern int port_logtype;
-#define RTE_LOGTYPE_PORT port_logtype
-
-#define PORT_LOG(level, ...) \
- RTE_LOG_LINE(level, PORT, "" __VA_ARGS__)
diff --git a/lib/port/rte_port.h b/lib/port/rte_port.h
deleted file mode 100644
index 81f57c41a5..0000000000
--- a/lib/port/rte_port.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_H__
-#define __INCLUDE_RTE_PORT_H__
-
-/**
- * @file
- * RTE Port
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard interface to implement different types of packet ports.
- */
-
-#include <stdint.h>
-#include <rte_mbuf.h>
-
-/**@{
- * Macros to allow accessing metadata stored in the mbuf headroom
- * just beyond the end of the mbuf data structure returned by a port
- */
-#define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset) \
- (&((uint8_t *)(mbuf))[offset])
-#define RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset) \
- ((uint16_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset) \
- ((uint32_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset) \
- ((uint64_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-
-#define RTE_MBUF_METADATA_UINT8(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT16(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset))
-/**@}*/
-
-/*
- * Port IN
- */
-/** Maximum number of packets read from any input port in a single burst.
-Cannot be changed. */
-#define RTE_PORT_IN_BURST_SIZE_MAX 64
-
-/** Input port statistics */
-struct rte_port_in_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Input port create
- *
- * @param params
- * Parameters for input port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to input port instance
- */
-typedef void* (*rte_port_in_op_create)(void *params, int socket_id);
-
-/**
- * Input port free
- *
- * @param port
- * Handle to input port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_free)(void *port);
-
-/**
- * Input port packet burst RX
- *
- * @param port
- * Handle to input port instance
- * @param pkts
- * Burst of input packets
- * @param n_pkts
- * Number of packets in the input burst
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_rx)(
- void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts);
-
-/**
- * Input port stats get
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_in stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_in_op_stats_read)(
- void *port,
- struct rte_port_in_stats *stats,
- int clear);
-
-/** Input port interface defining the input port operation */
-struct rte_port_in_ops {
- rte_port_in_op_create f_create; /**< Create */
- rte_port_in_op_free f_free; /**< Free */
- rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
- rte_port_in_op_stats_read f_stats; /**< Stats */
-};
-
-/*
- * Port OUT
- */
-/** Output port statistics */
-struct rte_port_out_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Output port create
- *
- * @param params
- * Parameters for output port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to output port instance
- */
-typedef void* (*rte_port_out_op_create)(void *params, int socket_id);
-
-/**
- * Output port free
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_free)(void *port);
-
-/**
- * Output port single packet TX
- *
- * @param port
- * Handle to output port instance
- * @param pkt
- * Input packet
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx)(
- void *port,
- struct rte_mbuf *pkt);
-
-/**
- * Output port packet burst TX
- *
- * @param port
- * Handle to output port instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx_bulk)(
- void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask);
-
-/**
- * Output port flush
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_flush)(void *port);
-
-/**
- * Output port stats read
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_out stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_out_op_stats_read)(
- void *port,
- struct rte_port_out_stats *stats,
- int clear);
-
-/** Output port interface defining the output port operation */
-struct rte_port_out_ops {
- rte_port_out_op_create f_create; /**< Create */
- rte_port_out_op_free f_free; /**< Free */
- rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
- rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
- rte_port_out_op_flush f_flush; /**< Flush */
- rte_port_out_op_stats_read f_stats; /**< Stats */
-};
-
-#endif
diff --git a/lib/port/rte_port_ethdev.c b/lib/port/rte_port_ethdev.c
deleted file mode 100644
index bdab2fbf6c..0000000000
--- a/lib/port/rte_port_ethdev.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ethdev.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ethdev.h"
-
-#include "port_log.h"
-
-/*
- * Port ETHDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_reader {
- struct rte_port_in_stats stats;
-
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_reader_params *conf =
- params;
- struct rte_port_ethdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
-
- return port;
-}
-
-static int
-rte_port_ethdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ethdev_reader *p =
- port;
- uint16_t rx_pkt_cnt;
-
- rx_pkt_cnt = rte_eth_rx_burst(p->port_id, p->queue_id, pkts, n_pkts);
- RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(p, rx_pkt_cnt);
- return rx_pkt_cnt;
-}
-
-static int
-rte_port_ethdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ethdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_params *conf =
- params;
- struct rte_port_ethdev_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_ethdev_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst(p);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_flush(void *port)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_nodrop_params *conf =
- params;
- struct rte_port_ethdev_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ethdev_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id, p->tx_buf,
- p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf + nb_tx, p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to send all packets in single burst,
- * move remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ethdev_reader_ops)
-struct rte_port_in_ops rte_port_ethdev_reader_ops = {
- .f_create = rte_port_ethdev_reader_create,
- .f_free = rte_port_ethdev_reader_free,
- .f_rx = rte_port_ethdev_reader_rx,
- .f_stats = rte_port_ethdev_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_ops = {
- .f_create = rte_port_ethdev_writer_create,
- .f_free = rte_port_ethdev_writer_free,
- .f_tx = rte_port_ethdev_writer_tx,
- .f_tx_bulk = rte_port_ethdev_writer_tx_bulk,
- .f_flush = rte_port_ethdev_writer_flush,
- .f_stats = rte_port_ethdev_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops = {
- .f_create = rte_port_ethdev_writer_nodrop_create,
- .f_free = rte_port_ethdev_writer_nodrop_free,
- .f_tx = rte_port_ethdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ethdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ethdev_writer_nodrop_flush,
- .f_stats = rte_port_ethdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ethdev.h b/lib/port/rte_port_ethdev.h
deleted file mode 100644
index 7729ff0da3..0000000000
--- a/lib/port/rte_port_ethdev.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_ETHDEV_H__
-#define __INCLUDE_RTE_PORT_ETHDEV_H__
-
-/**
- * @file
- * RTE Port Ethernet Device
- *
- * ethdev_reader: input port built on top of pre-initialized NIC RX queue
- * ethdev_writer: output port built on top of pre-initialized NIC TX queue
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ethdev_reader port parameters */
-struct rte_port_ethdev_reader_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-};
-
-/** ethdev_reader port operations */
-extern struct rte_port_in_ops rte_port_ethdev_reader_ops;
-
-/** ethdev_writer port parameters */
-struct rte_port_ethdev_writer_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ethdev_writer port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_ops;
-
-/** ethdev_writer_nodrop port parameters */
-struct rte_port_ethdev_writer_nodrop_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ethdev_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_eventdev.c b/lib/port/rte_port_eventdev.c
deleted file mode 100644
index c3a287b834..0000000000
--- a/lib/port/rte_port_eventdev.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_eventdev.h"
-
-#include "port_log.h"
-
-/*
- * Port EVENTDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_reader {
- struct rte_port_in_stats stats;
-
- uint8_t eventdev_id;
- uint16_t port_id;
-
- struct rte_event ev[RTE_PORT_IN_BURST_SIZE_MAX];
-};
-
-static void *
-rte_port_eventdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_reader_params *conf =
- params;
- struct rte_port_eventdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
-
- return port;
-}
-
-static int
-rte_port_eventdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_eventdev_reader *p = port;
- uint16_t rx_evts_cnt, i;
-
- rx_evts_cnt = rte_event_dequeue_burst(p->eventdev_id, p->port_id,
- p->ev, n_pkts, 0);
-
- for (i = 0; i < rx_evts_cnt; i++)
- pkts[i] = p->ev[i].mbuf;
-
- RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(p, rx_evts_cnt);
-
- return rx_evts_cnt;
-}
-
-static int
-rte_port_eventdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_eventdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
-
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-static void *
-rte_port_eventdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_params *conf =
- params;
- struct rte_port_eventdev_writer *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_eventdev_writer *p)
-{
- uint32_t nb_enq;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->enq_buf_count -
- nb_enq);
-
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst(p);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[2 * RTE_PORT_IN_BURST_SIZE_MAX] = {};
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p,
- n_pkts - n_enq_ok);
- for (; n_enq_ok < n_pkts; n_enq_ok++)
- rte_pktmbuf_free(pkts[n_enq_ok]);
-
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_flush(void *port)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-
-static void *
-rte_port_eventdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_nodrop_params *conf =
- params;
- struct rte_port_eventdev_writer_nodrop *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
- /*
- * When n_retries is 0 it means that we should wait for every event to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_eventdev_writer_nodrop *p)
-{
- uint32_t nb_enq, i;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_enq += rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev + nb_enq,
- p->enq_buf_count - nb_enq);
-
- /* We sent all the events in more than one try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
- }
- /* We didn't send the events in maximum allowed attempts */
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->enq_buf_count - nb_enq);
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer_nodrop *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[RTE_PORT_IN_BURST_SIZE_MAX] = {};
-
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- if (n_enq_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to enqueue all events in single burst,
- * move remaining events to the buffer and call send burst.
- */
- for (; n_enq_ok < n_pkts; n_enq_ok++) {
- struct rte_mbuf *pkt = pkts[n_enq_ok];
- p->ev[p->enq_buf_count++].mbuf = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_reader_ops, 19.11)
-struct rte_port_in_ops rte_port_eventdev_reader_ops = {
- .f_create = rte_port_eventdev_reader_create,
- .f_free = rte_port_eventdev_reader_free,
- .f_rx = rte_port_eventdev_reader_rx,
- .f_stats = rte_port_eventdev_reader_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_ops = {
- .f_create = rte_port_eventdev_writer_create,
- .f_free = rte_port_eventdev_writer_free,
- .f_tx = rte_port_eventdev_writer_tx,
- .f_tx_bulk = rte_port_eventdev_writer_tx_bulk,
- .f_flush = rte_port_eventdev_writer_flush,
- .f_stats = rte_port_eventdev_writer_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_nodrop_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops = {
- .f_create = rte_port_eventdev_writer_nodrop_create,
- .f_free = rte_port_eventdev_writer_nodrop_free,
- .f_tx = rte_port_eventdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_eventdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_eventdev_writer_nodrop_flush,
- .f_stats = rte_port_eventdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_eventdev.h b/lib/port/rte_port_eventdev.h
deleted file mode 100644
index d9eccf07d4..0000000000
--- a/lib/port/rte_port_eventdev.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_EVENTDEV_H__
-#define __INCLUDE_RTE_PORT_EVENTDEV_H__
-
-/**
- * @file
- * RTE Port Eventdev Interface
- *
- * eventdev_reader: input port built on top of pre-initialized eventdev
- * interface
- * eventdev_writer: output port built on top of pre-initialized eventdev
- * interface
- */
-
-#include <stdint.h>
-#include <rte_eventdev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Eventdev_reader port parameters */
-struct rte_port_eventdev_reader_params {
- /** Eventdev Device ID */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID */
- uint8_t port_id;
-};
-
-/** Eventdev_reader port operations. */
-extern struct rte_port_in_ops rte_port_eventdev_reader_ops;
-
-/** Eventdev_writer port parameters. */
-struct rte_port_eventdev_writer_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint8_t port_id;
-
- /** Eventdev Queue ID. */
- uint8_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-};
-
-/** Eventdev_writer port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_ops;
-
-/** Event_writer_nodrop port parameters. */
-struct rte_port_eventdev_writer_nodrop_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint16_t port_id;
-
- /** Eventdev Queue ID. */
- uint16_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Eventdev_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_fd.c b/lib/port/rte_port_fd.c
deleted file mode 100644
index dbc9efef1b..0000000000
--- a/lib/port/rte_port_fd.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_fd.h"
-
-#include "port_log.h"
-
-/*
- * Port FD Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_reader {
- struct rte_port_in_stats stats;
- int fd;
- uint32_t mtu;
- struct rte_mempool *mempool;
-};
-
-static void *
-rte_port_fd_reader_create(void *params, int socket_id)
-{
- struct rte_port_fd_reader_params *conf =
- params;
- struct rte_port_fd_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
- if (conf->fd < 0) {
- PORT_LOG(ERR, "%s: Invalid file descriptor", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Invalid MTU", __func__);
- return NULL;
- }
- if (conf->mempool == NULL) {
- PORT_LOG(ERR, "%s: Invalid mempool", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->mtu = conf->mtu;
- port->mempool = conf->mempool;
-
- return port;
-}
-
-static int
-rte_port_fd_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_fd_reader *p = port;
- uint32_t i, j;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void *);
- ssize_t n_bytes;
-
- n_bytes = read(p->fd, pkt_data, (size_t) p->mtu);
- if (n_bytes <= 0)
- break;
-
- pkt->data_len = n_bytes;
- pkt->pkt_len = n_bytes;
- }
-
- for (j = i; j < n_pkts; j++)
- rte_pktmbuf_free(pkts[j]);
-
- RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(p, i);
-
- return i;
-}
-
-static int
-rte_port_fd_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_fd_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_params *conf =
- params;
- struct rte_port_fd_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_fd_writer *p)
-{
- uint32_t i;
-
- for (i = 0; i < p->tx_buf_count; i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret < 0)
- break;
- }
-
- RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_flush(void *port)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t n_retries;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_nodrop_params *conf =
- params;
- struct rte_port_fd_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->fd < 0) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_fd_writer_nodrop *p)
-{
- uint64_t n_retries;
- uint32_t i;
-
- n_retries = 0;
- for (i = 0; (i < p->tx_buf_count) && (n_retries < p->n_retries); i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
-
- for ( ; n_retries < p->n_retries; n_retries++) {
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret)
- break;
- }
- }
-
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_flush(void *port)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_nodrop_flush(port);
- rte_free(port);
-
-return 0;
-}
-
-static int rte_port_fd_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_fd_reader_ops)
-struct rte_port_in_ops rte_port_fd_reader_ops = {
- .f_create = rte_port_fd_reader_create,
- .f_free = rte_port_fd_reader_free,
- .f_rx = rte_port_fd_reader_rx,
- .f_stats = rte_port_fd_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_ops)
-struct rte_port_out_ops rte_port_fd_writer_ops = {
- .f_create = rte_port_fd_writer_create,
- .f_free = rte_port_fd_writer_free,
- .f_tx = rte_port_fd_writer_tx,
- .f_tx_bulk = rte_port_fd_writer_tx_bulk,
- .f_flush = rte_port_fd_writer_flush,
- .f_stats = rte_port_fd_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_fd_writer_nodrop_ops = {
- .f_create = rte_port_fd_writer_nodrop_create,
- .f_free = rte_port_fd_writer_nodrop_free,
- .f_tx = rte_port_fd_writer_nodrop_tx,
- .f_tx_bulk = rte_port_fd_writer_nodrop_tx_bulk,
- .f_flush = rte_port_fd_writer_nodrop_flush,
- .f_stats = rte_port_fd_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_fd.h b/lib/port/rte_port_fd.h
deleted file mode 100644
index 40a5e4a426..0000000000
--- a/lib/port/rte_port_fd.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_FD_H__
-#define __INCLUDE_RTE_PORT_FD_H__
-
-/**
- * @file
- * RTE Port FD Device
- *
- * fd_reader: input port built on top of valid non-blocking file descriptor
- * fd_writer: output port built on top of valid non-blocking file descriptor
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** fd_reader port parameters */
-struct rte_port_fd_reader_params {
- /** File descriptor */
- int fd;
-
- /** Maximum Transfer Unit (MTU) */
- uint32_t mtu;
-
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-};
-
-/** fd_reader port operations */
-extern struct rte_port_in_ops rte_port_fd_reader_ops;
-
-/** fd_writer port parameters */
-struct rte_port_fd_writer_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-};
-
-/** fd_writer port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_ops;
-
-/** fd_writer_nodrop port parameters */
-struct rte_port_fd_writer_nodrop_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** fd_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_frag.c b/lib/port/rte_port_frag.c
deleted file mode 100644
index 9444f5939c..0000000000
--- a/lib/port/rte_port_frag.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-
-#include "rte_port_frag.h"
-
-#include "port_log.h"
-
-/* Max number of fragments per packet allowed */
-#define RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET 0x80
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-typedef int32_t
- (*frag_op)(struct rte_mbuf *pkt_in,
- struct rte_mbuf **pkts_out,
- uint16_t nb_pkts_out,
- uint16_t mtu_size,
- struct rte_mempool *pool_direct,
- struct rte_mempool *pool_indirect);
-
-struct __rte_cache_aligned rte_port_ring_reader_frag {
- struct rte_port_in_stats stats;
-
- /* Input parameters */
- struct rte_ring *ring;
- uint32_t mtu;
- uint32_t metadata_size;
- struct rte_mempool *pool_direct;
- struct rte_mempool *pool_indirect;
-
- /* Internal buffers */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *frags[RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET];
- uint32_t n_pkts;
- uint32_t pos_pkts;
- uint32_t n_frags;
- uint32_t pos_frags;
-
- frag_op f_frag;
-};
-
-static void *
-rte_port_ring_reader_frag_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_reader_frag_params *conf =
- params;
- struct rte_port_ring_reader_frag *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Parameter mtu is invalid", __func__);
- return NULL;
- }
- if (conf->pool_direct == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_direct is NULL",
- __func__);
- return NULL;
- }
- if (conf->pool_indirect == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_indirect is NULL",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port), RTE_CACHE_LINE_SIZE,
- socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->mtu = conf->mtu;
- port->metadata_size = conf->metadata_size;
- port->pool_direct = conf->pool_direct;
- port->pool_indirect = conf->pool_indirect;
-
- port->n_pkts = 0;
- port->pos_pkts = 0;
- port->n_frags = 0;
- port->pos_frags = 0;
-
- port->f_frag = (is_ipv4) ?
- rte_ipv4_fragment_packet : rte_ipv6_fragment_packet;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_ipv4_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_reader_ipv6_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 0);
-}
-
-static int
-rte_port_ring_reader_frag_rx(void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader_frag *p =
- port;
- uint32_t n_pkts_out;
-
- n_pkts_out = 0;
-
- /* Get packets from the "frag" buffer */
- if (p->n_frags >= n_pkts) {
- memcpy(pkts, &p->frags[p->pos_frags], n_pkts * sizeof(void *));
- p->pos_frags += n_pkts;
- p->n_frags -= n_pkts;
-
- return n_pkts;
- }
-
- memcpy(pkts, &p->frags[p->pos_frags], p->n_frags * sizeof(void *));
- n_pkts_out = p->n_frags;
- p->n_frags = 0;
-
- /* Look to "pkts" buffer to get more packets */
- for ( ; ; ) {
- struct rte_mbuf *pkt;
- uint32_t n_pkts_to_provide, i;
- int status;
-
- /* If "pkts" buffer is empty, read packet burst from ring */
- if (p->n_pkts == 0) {
- p->n_pkts = rte_ring_sc_dequeue_burst(p->ring,
- (void **) p->pkts, RTE_PORT_IN_BURST_SIZE_MAX,
- NULL);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(p, p->n_pkts);
- if (p->n_pkts == 0)
- return n_pkts_out;
- p->pos_pkts = 0;
- }
-
- /* Read next packet from "pkts" buffer */
- pkt = p->pkts[p->pos_pkts++];
- p->n_pkts--;
-
- /* If not jumbo, pass current packet to output */
- if (pkt->pkt_len <= p->mtu) {
- pkts[n_pkts_out++] = pkt;
-
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (n_pkts_to_provide == 0)
- return n_pkts;
-
- continue;
- }
-
- /* Fragment current packet into the "frags" buffer */
- status = p->f_frag(
- pkt,
- p->frags,
- RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET,
- p->mtu,
- p->pool_direct,
- p->pool_indirect
- );
-
- if (status < 0) {
- rte_pktmbuf_free(pkt);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(p, 1);
- continue;
- }
-
- p->n_frags = (uint32_t) status;
- p->pos_frags = 0;
-
- /* Copy meta-data from input jumbo packet to its fragments */
- for (i = 0; i < p->n_frags; i++) {
- uint8_t *src =
- RTE_MBUF_METADATA_UINT8_PTR(pkt, sizeof(struct rte_mbuf));
- uint8_t *dst =
- RTE_MBUF_METADATA_UINT8_PTR(p->frags[i], sizeof(struct rte_mbuf));
-
- memcpy(dst, src, p->metadata_size);
- }
-
- /* Free input jumbo packet */
- rte_pktmbuf_free(pkt);
-
- /* Get packets from "frag" buffer */
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (p->n_frags >= n_pkts_to_provide) {
- memcpy(&pkts[n_pkts_out], p->frags,
- n_pkts_to_provide * sizeof(void *));
- p->n_frags -= n_pkts_to_provide;
- p->pos_frags += n_pkts_to_provide;
-
- return n_pkts;
- }
-
- memcpy(&pkts[n_pkts_out], p->frags,
- p->n_frags * sizeof(void *));
- n_pkts_out += p->n_frags;
- p->n_frags = 0;
- }
-}
-
-static int
-rte_port_ring_reader_frag_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_frag_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader_frag *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv4_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops = {
- .f_create = rte_port_ring_reader_ipv4_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv6_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops = {
- .f_create = rte_port_ring_reader_ipv6_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
diff --git a/lib/port/rte_port_frag.h b/lib/port/rte_port_frag.h
deleted file mode 100644
index 9a10f10523..0000000000
--- a/lib/port/rte_port_frag.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IP_FRAG_H__
-#define __INCLUDE_RTE_PORT_IP_FRAG_H__
-
-/**
- * @file
- * RTE Port for IPv4 Fragmentation
- *
- * This port is built on top of pre-initialized single consumer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP fragmentation functionality is executed on ring read operation,
- * hence this port is implemented as an input port. A regular ring_writer port
- * can be created to write to the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or jumbo
- * frames (i.e. IP packets with length bigger than provided MTU value). The
- * packets read from the ring are all non-jumbo frames. The complete IP
- * datagrams written to the ring are not changed. The jumbo frames are
- * fragmented into several IP packets with length less or equal to MTU.
- */
-
-#include <stdint.h>
-
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader_ipv4_frag port parameters */
-struct rte_port_ring_reader_frag_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Maximum Transfer Unit (MTU). Maximum IP packet size (in bytes). */
- uint32_t mtu;
-
- /** Size of application dependent meta-data stored per each input packet
- that has to be copied to each of the fragments originating from the
- same input IP datagram. */
- uint32_t metadata_size;
-
- /** Pre-initialized buffer pool used for allocating direct buffers for
- the output fragments. */
- struct rte_mempool *pool_direct;
-
- /** Pre-initialized buffer pool used for allocating indirect buffers for
- the output fragments. */
- struct rte_mempool *pool_indirect;
-};
-
-#define rte_port_ring_reader_ipv4_frag_params rte_port_ring_reader_frag_params
-
-#define rte_port_ring_reader_ipv6_frag_params rte_port_ring_reader_frag_params
-
-/** ring_reader_ipv4_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops;
-
-/** ring_reader_ipv6_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ras.c b/lib/port/rte_port_ras.c
deleted file mode 100644
index 58ab7a1c5b..0000000000
--- a/lib/port/rte_port_ras.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-#include <rte_cycles.h>
-#include <rte_log.h>
-
-#include "rte_port_ras.h"
-
-#include "port_log.h"
-
-#ifndef RTE_PORT_RAS_N_BUCKETS
-#define RTE_PORT_RAS_N_BUCKETS 4094
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES_PER_BUCKET
-#define RTE_PORT_RAS_N_ENTRIES_PER_BUCKET 8
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES
-#define RTE_PORT_RAS_N_ENTRIES (RTE_PORT_RAS_N_BUCKETS * RTE_PORT_RAS_N_ENTRIES_PER_BUCKET)
-#endif
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_ras;
-
-typedef void (*ras_op)(
- struct rte_port_ring_writer_ras *p,
- struct rte_mbuf *pkt);
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-
-struct rte_port_ring_writer_ras {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- struct rte_ip_frag_tbl *frag_tbl;
- struct rte_ip_frag_death_row death_row;
-
- ras_op f_ras;
-};
-
-static void *
-rte_port_ring_writer_ras_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_writer_ras_params *conf =
- params;
- struct rte_port_ring_writer_ras *port;
- uint64_t frag_cycles;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if ((conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Parameter tx_burst_sz is invalid",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate socket", __func__);
- return NULL;
- }
-
- /* Create fragmentation table */
- frag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * MS_PER_S;
- frag_cycles *= 100;
-
- port->frag_tbl = rte_ip_frag_table_create(
- RTE_PORT_RAS_N_BUCKETS,
- RTE_PORT_RAS_N_ENTRIES_PER_BUCKET,
- RTE_PORT_RAS_N_ENTRIES,
- frag_cycles,
- socket_id);
-
- if (port->frag_tbl == NULL) {
- PORT_LOG(ERR, "%s: rte_ip_frag_table_create failed",
- __func__);
- rte_free(port);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- port->f_ras = (is_ipv4 == 1) ? process_ipv4 : process_ipv6;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_ipv4_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_writer_ipv6_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 0);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer_ras *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv4_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv4_hdr *);
-
- /* Get "More fragments" flag and fragment offset */
- uint16_t frag_field = rte_be_to_cpu_16(pkt_hdr->fragment_offset);
- uint16_t frag_offset = (uint16_t)(frag_field & RTE_IPV4_HDR_OFFSET_MASK);
- uint16_t frag_flag = (uint16_t)(frag_field & RTE_IPV4_HDR_MF_FLAG);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_flag == 0) && (frag_offset == 0))
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr);
-
- /* Process this fragment */
- mo = rte_ipv4_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(),
- pkt_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv6_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv6_hdr *);
-
- struct rte_ipv6_fragment_ext *frag_hdr;
- uint16_t frag_data = 0;
- frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt_hdr);
- if (frag_hdr != NULL)
- frag_data = rte_be_to_cpu_16(frag_hdr->frag_data);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_data & RTE_IPV6_FRAG_USED_MASK) == 0)
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr) + sizeof(*frag_hdr);
-
- /* Process this fragment */
- mo = rte_ipv6_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(), pkt_hdr,
- frag_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static int
-rte_port_ring_writer_ras_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_flush(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_free(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_port_ring_writer_ras_flush(port);
- rte_ip_frag_table_destroy(p->frag_tbl);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ras_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv4_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops = {
- .f_create = rte_port_ring_writer_ipv4_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv6_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops = {
- .f_create = rte_port_ring_writer_ipv6_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
diff --git a/lib/port/rte_port_ras.h b/lib/port/rte_port_ras.h
deleted file mode 100644
index 86e36f5362..0000000000
--- a/lib/port/rte_port_ras.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RAS_H__
-#define __INCLUDE_RTE_PORT_RAS_H__
-
-/**
- * @file
- * RTE Port for IPv4 Reassembly
- *
- * This port is built on top of pre-initialized single producer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP reassembly functionality is executed on ring write operation,
- * hence this port is implemented as an output port. A regular ring_reader port
- * can be created to read from the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or IP
- * fragments. The packets read from the ring are all complete IP datagrams,
- * either jumbo frames (i.e. IP packets with length bigger than MTU) or not.
- * The complete IP datagrams written to the ring are not changed. The IP
- * fragments written to the ring are first reassembled and into complete IP
- * datagrams or dropped on error or IP reassembly time-out.
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_writer_ipv4_ras port parameters */
-struct rte_port_ring_writer_ras_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be bigger
- or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-#define rte_port_ring_writer_ipv4_ras_params rte_port_ring_writer_ras_params
-
-#define rte_port_ring_writer_ipv6_ras_params rte_port_ring_writer_ras_params
-
-/** ring_writer_ipv4_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops;
-
-/** ring_writer_ipv6_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ring.c b/lib/port/rte_port_ring.c
deleted file mode 100644
index 307a576d65..0000000000
--- a/lib/port/rte_port_ring.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ring.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ring.h"
-
-#include "port_log.h"
-
-/*
- * Port RING Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_reader {
- struct rte_port_in_stats stats;
-
- struct rte_ring *ring;
-};
-
-static void *
-rte_port_ring_reader_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_reader_params *conf =
- params;
- struct rte_port_ring_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_cons_single(conf->ring) && is_multi) ||
- (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 1);
-}
-
-static int
-rte_port_ring_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_sc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_multi_reader_rx(void *port, struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_mc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_params *conf =
- params;
- struct rte_port_ring_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
-
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok = rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok = rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_free(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_flush(port);
- else
- rte_port_ring_writer_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop_params *conf =
- params;
- struct rte_port_ring_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_sp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_mp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_nodrop_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
-
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok =
- rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok =
- rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we didn't manage to send all packets in single burst, move
- * remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_free(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_nodrop_flush(port);
- else
- rte_port_ring_writer_nodrop_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ops)
-struct rte_port_in_ops rte_port_ring_reader_ops = {
- .f_create = rte_port_ring_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ops)
-struct rte_port_out_ops rte_port_ring_writer_ops = {
- .f_create = rte_port_ring_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_writer_tx,
- .f_tx_bulk = rte_port_ring_writer_tx_bulk,
- .f_flush = rte_port_ring_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_writer_nodrop_ops = {
- .f_create = rte_port_ring_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_reader_ops)
-struct rte_port_in_ops rte_port_ring_multi_reader_ops = {
- .f_create = rte_port_ring_multi_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_multi_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_ops = {
- .f_create = rte_port_ring_multi_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_multi_writer_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops = {
- .f_create = rte_port_ring_multi_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_multi_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ring.h b/lib/port/rte_port_ring.h
deleted file mode 100644
index 2089d0889b..0000000000
--- a/lib/port/rte_port_ring.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RING_H__
-#define __INCLUDE_RTE_PORT_RING_H__
-
-/**
- * @file
- * RTE Port Ring
- *
- * ring_reader:
- * input port built on top of pre-initialized single consumer ring
- * ring_writer:
- * output port built on top of pre-initialized single producer ring
- * ring_multi_reader:
- * input port built on top of pre-initialized multi consumers ring
- * ring_multi_writer:
- * output port built on top of pre-initialized multi producers ring
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader port parameters */
-struct rte_port_ring_reader_params {
- /** Underlying consumer ring that has to be pre-initialized */
- struct rte_ring *ring;
-};
-
-/** ring_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ops;
-
-/** ring_writer port parameters */
-struct rte_port_ring_writer_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ring_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ops;
-
-/** ring_writer_nodrop port parameters */
-struct rte_port_ring_writer_nodrop_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ring_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_nodrop_ops;
-
-/** ring_multi_reader port parameters */
-#define rte_port_ring_multi_reader_params rte_port_ring_reader_params
-
-/** ring_multi_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_multi_reader_ops;
-
-/** ring_multi_writer port parameters */
-#define rte_port_ring_multi_writer_params rte_port_ring_writer_params
-
-/** ring_multi_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_ops;
-
-/** ring_multi_writer_nodrop port parameters */
-#define rte_port_ring_multi_writer_nodrop_params \
- rte_port_ring_writer_nodrop_params
-
-/** ring_multi_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sched.c b/lib/port/rte_port_sched.c
deleted file mode 100644
index 3091078aa1..0000000000
--- a/lib/port/rte_port_sched.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sched.h"
-
-#include "port_log.h"
-
-/*
- * Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_reader {
- struct rte_port_in_stats stats;
-
- struct rte_sched_port *sched;
-};
-
-static void *
-rte_port_sched_reader_create(void *params, int socket_id)
-{
- struct rte_port_sched_reader_params *conf =
- params;
- struct rte_port_sched_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
-
- return port;
-}
-
-static int
-rte_port_sched_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sched_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_sched_port_dequeue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_READER_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_sched_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sched_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_sched_port *sched;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-};
-
-static void *
-rte_port_sched_writer_create(void *params, int socket_id)
-{
- struct rte_port_sched_writer_params *conf =
- params;
- struct rte_port_sched_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static int
-rte_port_sched_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- __rte_unused uint32_t nb_tx;
- uint64_t n_pkts = rte_popcount64(pkts_mask);
-
- if (tx_buf_count) {
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- nb_tx = rte_sched_port_enqueue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - nb_tx);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
- p->tx_buf_count = tx_buf_count;
-
- if (tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_flush(void *port)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- if (p->tx_buf_count) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sched_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sched_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sched_reader_ops)
-struct rte_port_in_ops rte_port_sched_reader_ops = {
- .f_create = rte_port_sched_reader_create,
- .f_free = rte_port_sched_reader_free,
- .f_rx = rte_port_sched_reader_rx,
- .f_stats = rte_port_sched_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sched_writer_ops)
-struct rte_port_out_ops rte_port_sched_writer_ops = {
- .f_create = rte_port_sched_writer_create,
- .f_free = rte_port_sched_writer_free,
- .f_tx = rte_port_sched_writer_tx,
- .f_tx_bulk = rte_port_sched_writer_tx_bulk,
- .f_flush = rte_port_sched_writer_flush,
- .f_stats = rte_port_sched_writer_stats_read,
-};
diff --git a/lib/port/rte_port_sched.h b/lib/port/rte_port_sched.h
deleted file mode 100644
index 1bf08ae6a9..0000000000
--- a/lib/port/rte_port_sched.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SCHED_H__
-#define __INCLUDE_RTE_PORT_SCHED_H__
-
-/**
- * @file
- * RTE Port Hierarchical Scheduler
- *
- * sched_reader: input port built on top of pre-initialized rte_sched_port
- * sched_writer: output port built on top of pre-initialized rte_sched_port
- */
-
-#include <stdint.h>
-
-#include <rte_sched.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** sched_reader port parameters */
-struct rte_port_sched_reader_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-};
-
-/** sched_reader port operations */
-extern struct rte_port_in_ops rte_port_sched_reader_ops;
-
-/** sched_writer port parameters */
-struct rte_port_sched_writer_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-
- /** Recommended burst size. The actual burst size can be bigger or
- smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** sched_writer port operations */
-extern struct rte_port_out_ops rte_port_sched_writer_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_source_sink.c b/lib/port/rte_port_source_sink.c
deleted file mode 100644
index 0557e12506..0000000000
--- a/lib/port/rte_port_source_sink.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-#include <stdint.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-
-#ifdef RTE_PORT_PCAP
-#include <rte_ether.h>
-#include <pcap.h>
-#endif
-
-#include "rte_port_source_sink.h"
-
-#include "port_log.h"
-
-/*
- * Port SOURCE
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_source {
- struct rte_port_in_stats stats;
-
- struct rte_mempool *mempool;
-
- /* PCAP buffers and indices */
- uint8_t **pkts;
- uint8_t *pkt_buff;
- uint32_t *pkt_len;
- uint32_t n_pkts;
- uint32_t pkt_index;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_source_load(struct rte_port_source *port,
- const char *file_name,
- uint32_t n_bytes_per_pkt,
- int socket_id)
-{
- uint32_t n_pkts = 0;
- uint32_t i;
- uint32_t *pkt_len_aligns = NULL;
- size_t total_buff_len = 0;
- pcap_t *pcap_handle;
- char pcap_errbuf[PCAP_ERRBUF_SIZE];
- uint32_t max_len;
- struct pcap_pkthdr pcap_hdr;
- const uint8_t *pkt;
- uint8_t *buff = NULL;
- uint32_t pktmbuf_maxlen = (uint32_t)
- (rte_pktmbuf_data_room_size(port->mempool) -
- RTE_PKTMBUF_HEADROOM);
-
- if (n_bytes_per_pkt == 0)
- max_len = pktmbuf_maxlen;
- else
- max_len = RTE_MIN(n_bytes_per_pkt, pktmbuf_maxlen);
-
- /* first time open, get packet number */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- while ((pkt = pcap_next(pcap_handle, &pcap_hdr)) != NULL)
- n_pkts++;
-
- pcap_close(pcap_handle);
-
- port->pkt_len = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkt_len) * n_pkts), 0, socket_id);
- if (port->pkt_len == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- pkt_len_aligns = rte_malloc("PCAP",
- (sizeof(*pkt_len_aligns) * n_pkts), 0);
- if (pkt_len_aligns == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkts = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkts) * n_pkts), 0, socket_id);
- if (port->pkts == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- /* open 2nd time, get pkt_len */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pcap_next(pcap_handle, &pcap_hdr);
- port->pkt_len[i] = RTE_MIN(max_len, pcap_hdr.len);
- pkt_len_aligns[i] = RTE_CACHE_LINE_ROUNDUP(
- port->pkt_len[i]);
- total_buff_len += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- /* allocate a big trunk of data for pcap file load */
- buff = rte_zmalloc_socket("PCAP",
- total_buff_len, 0, socket_id);
- if (buff == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkt_buff = buff;
-
- /* open file one last time to copy the pkt content */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pkt = pcap_next(pcap_handle, &pcap_hdr);
- rte_memcpy(buff, pkt, port->pkt_len[i]);
- port->pkts[i] = buff;
- buff += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- port->n_pkts = n_pkts;
-
- rte_free(pkt_len_aligns);
-
- PORT_LOG(INFO, "Successfully load pcap file "
- "'%s' with %u pkts",
- file_name, port->n_pkts);
-
- return 0;
-
-error_exit:
- rte_free(pkt_len_aligns);
- rte_free(port->pkt_len);
- rte_free(port->pkts);
- rte_free(port->pkt_buff);
-
- return -1;
-}
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
- pcap_source_load(port, file_name, n_bytes, socket_id)
-
-#else /* RTE_PORT_PCAP */
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Source port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#endif /* RTE_PORT_PCAP */
-
-static void *
-rte_port_source_create(void *params, int socket_id)
-{
- struct rte_port_source_params *p =
- params;
- struct rte_port_source *port;
-
- /* Check input arguments*/
- if ((p == NULL) || (p->mempool == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->mempool = (struct rte_mempool *) p->mempool;
-
- if (p->file_name) {
- int status = PCAP_SOURCE_LOAD(port, p->file_name,
- p->n_bytes_per_pkt, socket_id);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_source_free(void *port)
-{
- struct rte_port_source *p =
- port;
-
- /* Check input parameters */
- if (p == NULL)
- return 0;
-
- rte_free(p->pkt_len);
- rte_free(p->pkts);
- rte_free(p->pkt_buff);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_source_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_source *p = port;
- uint32_t i;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- if (p->pkt_buff != NULL) {
- for (i = 0; i < n_pkts; i++) {
- uint8_t *pkt_data = rte_pktmbuf_mtod(pkts[i],
- uint8_t *);
-
- rte_memcpy(pkt_data, p->pkts[p->pkt_index],
- p->pkt_len[p->pkt_index]);
- pkts[i]->data_len = p->pkt_len[p->pkt_index];
- pkts[i]->pkt_len = pkts[i]->data_len;
-
- p->pkt_index++;
- if (p->pkt_index >= p->n_pkts)
- p->pkt_index = 0;
- }
- }
-
- RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(p, n_pkts);
-
- return n_pkts;
-}
-
-static int
-rte_port_source_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_source *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port SINK
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val) \
- (port->stats.n_pkts_in += val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val) \
- (port->stats.n_pkts_drop += val)
-
-#else
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sink {
- struct rte_port_out_stats stats;
-
- /* PCAP dumper handle and pkts number */
- void *dumper;
- uint32_t max_pkts;
- uint32_t pkt_index;
- uint32_t dump_finish;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_sink_open(struct rte_port_sink *port,
- const char *file_name,
- uint32_t max_n_pkts)
-{
- pcap_t *tx_pcap;
- pcap_dumper_t *pcap_dumper;
-
- /** Open a dead pcap handler for opening dumper file */
- tx_pcap = pcap_open_dead(DLT_EN10MB, 65535);
- if (tx_pcap == NULL) {
- PORT_LOG(ERR, "Cannot open pcap dead handler");
- return -1;
- }
-
- /* The dumper is created using the previous pcap_t reference */
- pcap_dumper = pcap_dump_open(tx_pcap, file_name);
- if (pcap_dumper == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "\"%s\" for writing", file_name);
- return -1;
- }
-
- port->dumper = pcap_dumper;
- port->max_pkts = max_n_pkts;
- port->pkt_index = 0;
- port->dump_finish = 0;
-
- PORT_LOG(INFO, "Ready to dump packets to file \"%s\"",
- file_name);
-
- return 0;
-}
-
-static void
-pcap_sink_write_pkt(struct rte_port_sink *port, struct rte_mbuf *mbuf)
-{
- uint8_t *pcap_dumper = (port->dumper);
- struct pcap_pkthdr pcap_hdr;
- uint8_t jumbo_pkt_buf[RTE_ETHER_MAX_JUMBO_FRAME_LEN];
- uint8_t *pkt;
-
- /* Maximum num packets already reached */
- if (port->dump_finish)
- return;
-
- pkt = rte_pktmbuf_mtod(mbuf, uint8_t *);
-
- pcap_hdr.len = mbuf->pkt_len;
- pcap_hdr.caplen = pcap_hdr.len;
- gettimeofday(&(pcap_hdr.ts), NULL);
-
- if (mbuf->nb_segs > 1) {
- struct rte_mbuf *jumbo_mbuf;
- uint32_t pkt_index = 0;
-
- /* if packet size longer than RTE_ETHER_MAX_JUMBO_FRAME_LEN,
- * ignore it.
- */
- if (mbuf->pkt_len > RTE_ETHER_MAX_JUMBO_FRAME_LEN)
- return;
-
- for (jumbo_mbuf = mbuf; jumbo_mbuf != NULL;
- jumbo_mbuf = jumbo_mbuf->next) {
- rte_memcpy(&jumbo_pkt_buf[pkt_index],
- rte_pktmbuf_mtod(jumbo_mbuf, uint8_t *),
- jumbo_mbuf->data_len);
- pkt_index += jumbo_mbuf->data_len;
- }
-
- jumbo_pkt_buf[pkt_index] = '\0';
-
- pkt = jumbo_pkt_buf;
- }
-
- pcap_dump(pcap_dumper, &pcap_hdr, pkt);
-
- port->pkt_index++;
-
- if ((port->max_pkts != 0) && (port->pkt_index >= port->max_pkts)) {
- port->dump_finish = 1;
- PORT_LOG(INFO, "Dumped %u packets to file",
- port->pkt_index);
- }
-
-}
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
- pcap_sink_open(port, file_name, max_n_pkts)
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) \
- pcap_sink_write_pkt(port, mbuf)
-
-#define PCAP_SINK_FLUSH_PKT(dumper) \
-do { \
- if (dumper) \
- pcap_dump_flush((pcap_dumper_t *)dumper); \
-} while (0)
-
-#define PCAP_SINK_CLOSE(dumper) \
-do { \
- if (dumper) \
- pcap_dump_close((pcap_dumper_t *)dumper); \
-} while (0)
-
-#else
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Sink port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) {}
-
-#define PCAP_SINK_FLUSH_PKT(dumper)
-
-#define PCAP_SINK_CLOSE(dumper)
-
-#endif
-
-static void *
-rte_port_sink_create(void *params, int socket_id)
-{
- struct rte_port_sink *port;
- struct rte_port_sink_params *p = params;
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- if (!p)
- return port;
-
- if (p->file_name) {
- int status = PCAP_SINK_OPEN(port, p->file_name,
- p->max_n_pkts);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_sink_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sink *p = port;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- if (p->dumper != NULL)
- PCAP_SINK_WRITE_PKT(p, pkt);
- rte_pktmbuf_free(pkt);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
-
- return 0;
-}
-
-static int
-rte_port_sink_tx_bulk(void *port, struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sink *p = port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, n_pkts);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, n_pkts);
-
- if (p->dumper) {
- for (i = 0; i < n_pkts; i++)
- PCAP_SINK_WRITE_PKT(p, pkts[i]);
- }
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- rte_pktmbuf_free(pkt);
- }
-
- } else {
- if (p->dumper) {
- uint64_t dump_pkts_mask = pkts_mask;
- uint32_t pkt_index;
-
- for ( ; dump_pkts_mask; ) {
- pkt_index = rte_ctz64(
- dump_pkts_mask);
- PCAP_SINK_WRITE_PKT(p, pkts[pkt_index]);
- dump_pkts_mask &= ~(1LLU << pkt_index);
- }
- }
-
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
- rte_pktmbuf_free(pkt);
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sink_flush(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_FLUSH_PKT(p->dumper);
-
- return 0;
-}
-
-static int
-rte_port_sink_free(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_CLOSE(p->dumper);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_sink_stats_read(void *port, struct rte_port_out_stats *stats,
- int clear)
-{
- struct rte_port_sink *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_source_ops)
-struct rte_port_in_ops rte_port_source_ops = {
- .f_create = rte_port_source_create,
- .f_free = rte_port_source_free,
- .f_rx = rte_port_source_rx,
- .f_stats = rte_port_source_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sink_ops)
-struct rte_port_out_ops rte_port_sink_ops = {
- .f_create = rte_port_sink_create,
- .f_free = rte_port_sink_free,
- .f_tx = rte_port_sink_tx,
- .f_tx_bulk = rte_port_sink_tx_bulk,
- .f_flush = rte_port_sink_flush,
- .f_stats = rte_port_sink_stats_read,
-};
diff --git a/lib/port/rte_port_source_sink.h b/lib/port/rte_port_source_sink.h
deleted file mode 100644
index 3122dd5038..0000000000
--- a/lib/port/rte_port_source_sink.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-#define __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-
-/**
- * @file
- * RTE Port Source/Sink
- *
- * source: input port that can be used to generate packets
- * sink: output port that drops all packets written to it
- */
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** source port parameters */
-struct rte_port_source_params {
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-
- /** The full path of the pcap file to read packets from */
- const char *file_name;
- /** The number of bytes to be read from each packet in the
- * pcap file. If this value is 0, the whole packet is read;
- * if it is bigger than packet size, the generated packets
- * will contain the whole packet */
- uint32_t n_bytes_per_pkt;
-};
-
-/** source port operations */
-extern struct rte_port_in_ops rte_port_source_ops;
-
-/** sink port parameters */
-struct rte_port_sink_params {
- /** The full path of the pcap file to write the packets to */
- const char *file_name;
- /** The maximum number of packets write to the pcap file.
- * If this value is 0, the "infinite" write will be carried
- * out.
- */
- uint32_t max_n_pkts;
-};
-
-/** sink port operations */
-extern struct rte_port_out_ops rte_port_sink_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sym_crypto.c b/lib/port/rte_port_sym_crypto.c
deleted file mode 100644
index 30c9d1283e..0000000000
--- a/lib/port/rte_port_sym_crypto.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sym_crypto.h"
-
-#include "port_log.h"
-
-/*
- * Port Crypto Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_reader {
- struct rte_port_in_stats stats;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- struct rte_crypto_op *ops[RTE_PORT_IN_BURST_SIZE_MAX];
- rte_port_sym_crypto_reader_callback_fn f_callback;
- void *arg_callback;
-};
-
-static void *
-rte_port_sym_crypto_reader_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_reader_params *conf =
- params;
- struct rte_port_sym_crypto_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->f_callback = conf->f_callback;
- port->arg_callback = conf->arg_callback;
-
- return port;
-}
-
-static int
-rte_port_sym_crypto_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
- uint16_t rx_ops_cnt, i, n = 0;
-
- rx_ops_cnt = rte_cryptodev_dequeue_burst(p->cryptodev_id, p->queue_id,
- p->ops, n_pkts);
-
- for (i = 0; i < rx_ops_cnt; i++) {
- struct rte_crypto_op *op = p->ops[i];
-
- /** Drop failed pkts */
- if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)) {
- rte_pktmbuf_free(op->sym->m_src);
- continue;
- }
-
- pkts[n++] = op->sym->m_src;
- }
-
- if (p->f_callback)
- (*p->f_callback)(pkts, n, p->arg_callback);
-
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(p, n);
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(p, rx_ops_cnt - n);
-
- return n;
-}
-
-static int
-rte_port_sym_crypto_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_params *conf =
- params;
- struct rte_port_sym_crypto_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_sym_crypto_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count -
- nb_tx);
- for (; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_flush(void *port)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_nodrop_params *conf =
- params;
- struct rte_port_sym_crypto_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_sym_crypto_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_cryptodev_enqueue_burst(p->cryptodev_id,
- p->queue_id, p->tx_buf + nb_tx,
- p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p,
- 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_flush(void *port)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_reader_ops)
-struct rte_port_in_ops rte_port_sym_crypto_reader_ops = {
- .f_create = rte_port_sym_crypto_reader_create,
- .f_free = rte_port_sym_crypto_reader_free,
- .f_rx = rte_port_sym_crypto_reader_rx,
- .f_stats = rte_port_sym_crypto_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_ops = {
- .f_create = rte_port_sym_crypto_writer_create,
- .f_free = rte_port_sym_crypto_writer_free,
- .f_tx = rte_port_sym_crypto_writer_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_flush,
- .f_stats = rte_port_sym_crypto_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops = {
- .f_create = rte_port_sym_crypto_writer_nodrop_create,
- .f_free = rte_port_sym_crypto_writer_nodrop_free,
- .f_tx = rte_port_sym_crypto_writer_nodrop_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_nodrop_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_nodrop_flush,
- .f_stats = rte_port_sym_crypto_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_sym_crypto.h b/lib/port/rte_port_sym_crypto.h
deleted file mode 100644
index d03cdc1e8b..0000000000
--- a/lib/port/rte_port_sym_crypto.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-#define __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-
-/**
- * @file
- * RTE Port sym crypto Interface
- *
- * crypto_reader: input port built on top of pre-initialized crypto interface
- * crypto_writer: output port built on top of pre-initialized crypto interface
- */
-
-#include <stdint.h>
-
-#include <rte_cryptodev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Function prototype for reader post action. */
-typedef void (*rte_port_sym_crypto_reader_callback_fn)(struct rte_mbuf **pkts,
- uint16_t n_pkts, void *arg);
-
-/** Crypto_reader port parameters */
-struct rte_port_sym_crypto_reader_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** Crypto reader post callback function. */
- rte_port_sym_crypto_reader_callback_fn f_callback;
-
- /** Crypto reader post callback function arguments. */
- void *arg_callback;
-};
-
-/** Crypto_reader port operations. */
-extern struct rte_port_in_ops rte_port_sym_crypto_reader_ops;
-
-
-/** Crypto_writer port parameters. */
-struct rte_port_sym_crypto_writer_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-};
-
-/** Crypto_writer port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_ops;
-
-/** Crypto_writer_nodrop port parameters. */
-struct rte_port_sym_crypto_writer_nodrop_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev queue pair id. */
- uint16_t queue_id;
-
- /** Offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Crypto_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* Re: [PATCH v3 0/6] remove legacy packet framework
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
` (4 preceding siblings ...)
2026-07-28 14:20 ` [PATCH v3 6/6] port: " Stephen Hemminger
@ 2026-07-28 14:48 ` David Marchand
5 siblings, 0 replies; 29+ messages in thread
From: David Marchand @ 2026-07-28 14:48 UTC (permalink / raw)
To: Stephen Hemminger, Ali Alnubani; +Cc: dev, Thomas Monjalon
On Tue, 28 Jul 2026 at 16:22, Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> Remove the legacy packet framework examples and libraries.
> This was announced in 24.11 but never completed.
>
> v3 - also cleanup cocci scripts
>
> Stephen Hemminger (6):
> app/test: remove packet framework tests
> app/test-pipeline: remove application
> examples/ip_pipeline: remove example
> pipeline: remove legacy API
> table: remove legacy API
> port: remove legacy API
Not sure why, but downloading the mbox from patchwork gives broken patches.
Maybe the binary part gets mangled...
At least, downloading from inbox.dpdk.org works.
--
David Marchand
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH v4 0/7] remove deprecated packet framework
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (7 preceding siblings ...)
2026-07-28 14:20 ` [PATCH v3 0/6] remove legacy packet framework Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 1/7] app/test: remove packet framework tests Stephen Hemminger
` (6 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
The packet framework was marked as deprecated in 24.11.
This patch series completes the removal of the libraries, documentation,
and tests.
Stephen Hemminger (7):
app/test: remove packet framework tests
app/test-pipeline: remove application
examples/ip_pipeline: remove example
pipeline: remove legacy API
table: remove legacy API
port: remove legacy API
doc: remove packet framework images
MAINTAINERS | 5 -
app/meson.build | 1 -
app/test-pipeline/config.c | 230 -
app/test-pipeline/init.c | 273 -
app/test-pipeline/main.c | 188 -
app/test-pipeline/main.h | 132 -
app/test-pipeline/meson.build | 21 -
app/test-pipeline/pipeline_acl.c | 251 -
app/test-pipeline/pipeline_hash.c | 471 --
app/test-pipeline/pipeline_lpm.c | 175 -
app/test-pipeline/pipeline_lpm_ipv6.c | 168 -
app/test-pipeline/pipeline_stub.c | 137 -
app/test-pipeline/runtime.c | 160 -
app/test/meson.build | 6 -
app/test/test_table.c | 209 -
app/test/test_table.h | 184 -
app/test/test_table_acl.c | 728 --
app/test/test_table_acl.h | 6 -
app/test/test_table_combined.c | 846 --
app/test/test_table_combined.h | 27 -
app/test/test_table_pipeline.c | 575 --
app/test/test_table_pipeline.h | 6 -
app/test/test_table_ports.c | 195 -
app/test/test_table_ports.h | 13 -
app/test/test_table_tables.c | 1058 ---
app/test/test_table_tables.h | 22 -
doc/api/doxy-api-index.md | 17 -
doc/guides/nics/softnic.rst | 3 +-
doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
doc/guides/prog_guide/img/figure33.png | Bin 65216 -> 0 bytes
doc/guides/prog_guide/img/figure34.png | Bin 11581 -> 0 bytes
doc/guides/prog_guide/img/figure35.png | Bin 75012 -> 0 bytes
doc/guides/prog_guide/img/figure37.png | Bin 6934 -> 0 bytes
doc/guides/prog_guide/img/figure38.png | Bin 7372 -> 0 bytes
doc/guides/prog_guide/img/figure39.png | Bin 55986 -> 0 bytes
doc/guides/prog_guide/packet_framework.rst | 1146 +--
doc/guides/rel_notes/deprecation.rst | 15 -
doc/guides/rel_notes/release_26_11.rst | 17 +
.../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
doc/guides/sample_app_ug/index.rst | 2 -
doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
doc/guides/sample_app_ug/test_pipeline.rst | 237 -
examples/ip_pipeline/Makefile | 60 -
examples/ip_pipeline/action.c | 391 -
examples/ip_pipeline/action.h | 78 -
examples/ip_pipeline/cli.c | 6791 -----------------
examples/ip_pipeline/cli.h | 18 -
examples/ip_pipeline/common.h | 12 -
examples/ip_pipeline/conn.c | 330 -
examples/ip_pipeline/conn.h | 47 -
examples/ip_pipeline/cryptodev.c | 160 -
examples/ip_pipeline/cryptodev.h | 46 -
examples/ip_pipeline/examples/firewall.cli | 59 -
examples/ip_pipeline/examples/flow.cli | 60 -
examples/ip_pipeline/examples/flow_crypto.cli | 57 -
examples/ip_pipeline/examples/l2fwd.cli | 51 -
examples/ip_pipeline/examples/route.cli | 60 -
examples/ip_pipeline/examples/route_ecmp.cli | 57 -
examples/ip_pipeline/examples/rss.cli | 112 -
examples/ip_pipeline/examples/tap.cli | 66 -
examples/ip_pipeline/link.c | 270 -
examples/ip_pipeline/link.h | 66 -
examples/ip_pipeline/main.c | 260 -
examples/ip_pipeline/mempool.c | 82 -
examples/ip_pipeline/mempool.h | 40 -
examples/ip_pipeline/meson.build | 30 -
examples/ip_pipeline/parser.c | 506 --
examples/ip_pipeline/parser.h | 56 -
examples/ip_pipeline/pipeline.c | 1078 ---
examples/ip_pipeline/pipeline.h | 425 --
examples/ip_pipeline/swq.c | 76 -
examples/ip_pipeline/swq.h | 37 -
examples/ip_pipeline/tap.c | 102 -
examples/ip_pipeline/tap.h | 29 -
examples/ip_pipeline/thread.c | 3137 --------
examples/ip_pipeline/thread.h | 24 -
examples/ip_pipeline/tmgr.c | 248 -
examples/ip_pipeline/tmgr.h | 74 -
examples/meson.build | 1 -
lib/pipeline/meson.build | 8 +-
lib/pipeline/rte_pipeline.c | 1640 ----
lib/pipeline/rte_pipeline.h | 840 --
lib/pipeline/rte_port_in_action.c | 539 --
lib/pipeline/rte_port_in_action.h | 311 -
lib/pipeline/rte_table_action.c | 3483 ---------
lib/pipeline/rte_table_action.h | 1137 ---
lib/port/meson.build | 22 +-
lib/port/port_log.c | 7 -
lib/port/port_log.h | 11 -
lib/port/rte_port.h | 223 -
lib/port/rte_port_ethdev.c | 530 --
lib/port/rte_port_ethdev.h | 75 -
lib/port/rte_port_eventdev.c | 590 --
lib/port/rte_port_eventdev.h | 94 -
lib/port/rte_port_fd.c | 524 --
lib/port/rte_port_fd.h | 74 -
lib/port/rte_port_frag.c | 280 -
lib/port/rte_port_frag.h | 70 -
lib/port/rte_port_ras.c | 336 -
lib/port/rte_port_ras.h | 58 -
lib/port/rte_port_ring.c | 796 --
lib/port/rte_port_ring.h | 91 -
lib/port/rte_port_sched.c | 298 -
lib/port/rte_port_sched.h | 52 -
lib/port/rte_port_source_sink.c | 616 --
lib/port/rte_port_source_sink.h | 57 -
lib/port/rte_port_sym_crypto.c | 558 --
lib/port/rte_port_sym_crypto.h | 92 -
lib/table/meson.build | 30 +-
lib/table/rte_lru.h | 85 -
lib/table/rte_lru_arm64.h | 61 -
lib/table/rte_lru_x86.h | 96 -
lib/table/rte_table.h | 263 -
lib/table/rte_table_acl.c | 795 --
lib/table/rte_table_acl.h | 65 -
lib/table/rte_table_array.c | 210 -
lib/table/rte_table_array.h | 46 -
lib/table/rte_table_hash.h | 106 -
lib/table/rte_table_hash_cuckoo.c | 327 -
lib/table/rte_table_hash_cuckoo.h | 57 -
lib/table/rte_table_hash_ext.c | 1011 ---
lib/table/rte_table_hash_func.h | 263 -
lib/table/rte_table_hash_func_arm64.h | 21 -
lib/table/rte_table_hash_key16.c | 1190 ---
lib/table/rte_table_hash_key32.c | 1223 ---
lib/table/rte_table_hash_key8.c | 1157 ---
lib/table/rte_table_hash_lru.c | 959 ---
lib/table/rte_table_lpm.c | 369 -
lib/table/rte_table_lpm.h | 94 -
lib/table/rte_table_lpm_ipv6.c | 370 -
lib/table/rte_table_stub.c | 95 -
lib/table/rte_table_stub.h | 30 -
lib/table/table_log.c | 7 -
lib/table/table_log.h | 11 -
134 files changed, 27 insertions(+), 45377 deletions(-)
delete mode 100644 app/test-pipeline/config.c
delete mode 100644 app/test-pipeline/init.c
delete mode 100644 app/test-pipeline/main.c
delete mode 100644 app/test-pipeline/main.h
delete mode 100644 app/test-pipeline/meson.build
delete mode 100644 app/test-pipeline/pipeline_acl.c
delete mode 100644 app/test-pipeline/pipeline_hash.c
delete mode 100644 app/test-pipeline/pipeline_lpm.c
delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
delete mode 100644 app/test-pipeline/pipeline_stub.c
delete mode 100644 app/test-pipeline/runtime.c
delete mode 100644 app/test/test_table.c
delete mode 100644 app/test/test_table.h
delete mode 100644 app/test/test_table_acl.c
delete mode 100644 app/test/test_table_acl.h
delete mode 100644 app/test/test_table_combined.c
delete mode 100644 app/test/test_table_combined.h
delete mode 100644 app/test/test_table_pipeline.c
delete mode 100644 app/test/test_table_pipeline.h
delete mode 100644 app/test/test_table_ports.c
delete mode 100644 app/test/test_table_ports.h
delete mode 100644 app/test/test_table_tables.c
delete mode 100644 app/test/test_table_tables.h
delete mode 100644 doc/guides/prog_guide/img/figure32.png
delete mode 100644 doc/guides/prog_guide/img/figure33.png
delete mode 100644 doc/guides/prog_guide/img/figure34.png
delete mode 100644 doc/guides/prog_guide/img/figure35.png
delete mode 100644 doc/guides/prog_guide/img/figure37.png
delete mode 100644 doc/guides/prog_guide/img/figure38.png
delete mode 100644 doc/guides/prog_guide/img/figure39.png
delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
delete mode 100644 examples/ip_pipeline/Makefile
delete mode 100644 examples/ip_pipeline/action.c
delete mode 100644 examples/ip_pipeline/action.h
delete mode 100644 examples/ip_pipeline/cli.c
delete mode 100644 examples/ip_pipeline/cli.h
delete mode 100644 examples/ip_pipeline/common.h
delete mode 100644 examples/ip_pipeline/conn.c
delete mode 100644 examples/ip_pipeline/conn.h
delete mode 100644 examples/ip_pipeline/cryptodev.c
delete mode 100644 examples/ip_pipeline/cryptodev.h
delete mode 100644 examples/ip_pipeline/examples/firewall.cli
delete mode 100644 examples/ip_pipeline/examples/flow.cli
delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
delete mode 100644 examples/ip_pipeline/examples/route.cli
delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
delete mode 100644 examples/ip_pipeline/examples/rss.cli
delete mode 100644 examples/ip_pipeline/examples/tap.cli
delete mode 100644 examples/ip_pipeline/link.c
delete mode 100644 examples/ip_pipeline/link.h
delete mode 100644 examples/ip_pipeline/main.c
delete mode 100644 examples/ip_pipeline/mempool.c
delete mode 100644 examples/ip_pipeline/mempool.h
delete mode 100644 examples/ip_pipeline/meson.build
delete mode 100644 examples/ip_pipeline/parser.c
delete mode 100644 examples/ip_pipeline/parser.h
delete mode 100644 examples/ip_pipeline/pipeline.c
delete mode 100644 examples/ip_pipeline/pipeline.h
delete mode 100644 examples/ip_pipeline/swq.c
delete mode 100644 examples/ip_pipeline/swq.h
delete mode 100644 examples/ip_pipeline/tap.c
delete mode 100644 examples/ip_pipeline/tap.h
delete mode 100644 examples/ip_pipeline/thread.c
delete mode 100644 examples/ip_pipeline/thread.h
delete mode 100644 examples/ip_pipeline/tmgr.c
delete mode 100644 examples/ip_pipeline/tmgr.h
delete mode 100644 lib/pipeline/rte_pipeline.c
delete mode 100644 lib/pipeline/rte_pipeline.h
delete mode 100644 lib/pipeline/rte_port_in_action.c
delete mode 100644 lib/pipeline/rte_port_in_action.h
delete mode 100644 lib/pipeline/rte_table_action.c
delete mode 100644 lib/pipeline/rte_table_action.h
delete mode 100644 lib/port/port_log.c
delete mode 100644 lib/port/port_log.h
delete mode 100644 lib/port/rte_port.h
delete mode 100644 lib/port/rte_port_ethdev.c
delete mode 100644 lib/port/rte_port_ethdev.h
delete mode 100644 lib/port/rte_port_eventdev.c
delete mode 100644 lib/port/rte_port_eventdev.h
delete mode 100644 lib/port/rte_port_fd.c
delete mode 100644 lib/port/rte_port_fd.h
delete mode 100644 lib/port/rte_port_frag.c
delete mode 100644 lib/port/rte_port_frag.h
delete mode 100644 lib/port/rte_port_ras.c
delete mode 100644 lib/port/rte_port_ras.h
delete mode 100644 lib/port/rte_port_ring.c
delete mode 100644 lib/port/rte_port_ring.h
delete mode 100644 lib/port/rte_port_sched.c
delete mode 100644 lib/port/rte_port_sched.h
delete mode 100644 lib/port/rte_port_source_sink.c
delete mode 100644 lib/port/rte_port_source_sink.h
delete mode 100644 lib/port/rte_port_sym_crypto.c
delete mode 100644 lib/port/rte_port_sym_crypto.h
delete mode 100644 lib/table/rte_lru.h
delete mode 100644 lib/table/rte_lru_arm64.h
delete mode 100644 lib/table/rte_lru_x86.h
delete mode 100644 lib/table/rte_table.h
delete mode 100644 lib/table/rte_table_acl.c
delete mode 100644 lib/table/rte_table_acl.h
delete mode 100644 lib/table/rte_table_array.c
delete mode 100644 lib/table/rte_table_array.h
delete mode 100644 lib/table/rte_table_hash.h
delete mode 100644 lib/table/rte_table_hash_cuckoo.c
delete mode 100644 lib/table/rte_table_hash_cuckoo.h
delete mode 100644 lib/table/rte_table_hash_ext.c
delete mode 100644 lib/table/rte_table_hash_func.h
delete mode 100644 lib/table/rte_table_hash_func_arm64.h
delete mode 100644 lib/table/rte_table_hash_key16.c
delete mode 100644 lib/table/rte_table_hash_key32.c
delete mode 100644 lib/table/rte_table_hash_key8.c
delete mode 100644 lib/table/rte_table_hash_lru.c
delete mode 100644 lib/table/rte_table_lpm.c
delete mode 100644 lib/table/rte_table_lpm.h
delete mode 100644 lib/table/rte_table_lpm_ipv6.c
delete mode 100644 lib/table/rte_table_stub.c
delete mode 100644 lib/table/rte_table_stub.h
delete mode 100644 lib/table/table_log.c
delete mode 100644 lib/table/table_log.h
--
2.53.0
^ permalink raw reply [flat|nested] 29+ messages in thread* [PATCH v4 1/7] app/test: remove packet framework tests
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (8 preceding siblings ...)
2026-07-28 16:35 ` [PATCH v4 0/7] remove deprecated " Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 2/7] app/test-pipeline: remove application Stephen Hemminger
` (5 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The legacy packet framework libraries (port, table, pipeline) are
being removed, so remove the unit tests exercising them.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 1 -
app/test/meson.build | 6 -
app/test/test_table.c | 209 -------
app/test/test_table.h | 184 ------
app/test/test_table_acl.c | 728 ----------------------
app/test/test_table_acl.h | 6 -
app/test/test_table_combined.c | 846 -------------------------
app/test/test_table_combined.h | 27 -
app/test/test_table_pipeline.c | 575 -----------------
app/test/test_table_pipeline.h | 6 -
app/test/test_table_ports.c | 195 ------
app/test/test_table_ports.h | 13 -
app/test/test_table_tables.c | 1058 --------------------------------
app/test/test_table_tables.h | 22 -
14 files changed, 3876 deletions(-)
delete mode 100644 app/test/test_table.c
delete mode 100644 app/test/test_table.h
delete mode 100644 app/test/test_table_acl.c
delete mode 100644 app/test/test_table_acl.h
delete mode 100644 app/test/test_table_combined.c
delete mode 100644 app/test/test_table_combined.h
delete mode 100644 app/test/test_table_pipeline.c
delete mode 100644 app/test/test_table_pipeline.h
delete mode 100644 app/test/test_table_ports.c
delete mode 100644 app/test/test_table_ports.h
delete mode 100644 app/test/test_table_tables.c
delete mode 100644 app/test/test_table_tables.h
diff --git a/MAINTAINERS b/MAINTAINERS
index e99a65d1974d38b62aa88f0662796226e57cd033..77a41b3fcf4110042ef69b7ee53351dd3cadb208 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,7 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test/test_table*
F: app/test-pipeline/
F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
diff --git a/app/test/meson.build b/app/test/meson.build
index 51abeeb7324483f07df4ff71dbc9e8a283740bc8..4fcd75594091abbf4fd09328023a3118e59b524d 100644
--- a/app/test/meson.build
+++ b/app/test/meson.build
@@ -195,12 +195,6 @@ source_file_deps = {
'test_stack.c': ['stack'],
'test_stack_perf.c': ['stack'],
'test_string_fns.c': [],
- 'test_table.c': ['table', 'pipeline', 'port'],
- 'test_table_acl.c': ['net', 'table', 'pipeline', 'port'],
- 'test_table_combined.c': ['table', 'pipeline', 'port'],
- 'test_table_pipeline.c': ['pipeline', 'table', 'port'],
- 'test_table_ports.c': ['table', 'pipeline', 'port'],
- 'test_table_tables.c': ['table', 'pipeline', 'port'],
'test_tailq.c': [],
'test_telemetry_data.c': ['telemetry'],
'test_telemetry_json.c': ['telemetry'],
diff --git a/app/test/test_table.c b/app/test/test_table.c
deleted file mode 100644
index 20623b873520f910f06fd539ee3fbe4b3aa2c52d..0000000000000000000000000000000000000000
--- a/app/test/test_table.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_byteorder.h>
-#include <rte_hexdump.h>
-#include <rte_string_fns.h>
-#include <string.h>
-#include "test.h"
-
-#ifdef RTE_EXEC_ENV_WINDOWS
-static int
-test_table(void)
-{
- printf("table not supported on Windows, skipping test\n");
- return TEST_SKIPPED;
-}
-#else
-
-#include "test_table.h"
-#include "test_table_pipeline.h"
-#include "test_table_ports.h"
-#include "test_table_tables.h"
-#include "test_table_combined.h"
-#include "test_table_acl.h"
-
-/* Global variables */
-struct rte_pipeline *p;
-struct rte_ring *rings_rx[N_PORTS];
-struct rte_ring *rings_tx[N_PORTS];
-struct rte_mempool *pool = NULL;
-
-uint32_t port_in_id[N_PORTS];
-uint32_t port_out_id[N_PORTS];
-uint32_t port_out_id_type[3];
-uint32_t table_id[N_PORTS*2];
-uint64_t override_hit_mask = 0xFFFFFFFF;
-uint64_t override_miss_mask = 0xFFFFFFFF;
-uint64_t non_reserved_actions_hit = 0;
-uint64_t non_reserved_actions_miss = 0;
-uint8_t connect_miss_action_to_port_out = 0;
-uint8_t connect_miss_action_to_table = 0;
-uint32_t table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
-uint32_t table_entry_hit_action = RTE_PIPELINE_ACTION_PORT;
-uint32_t table_entry_miss_action = RTE_PIPELINE_ACTION_DROP;
-rte_pipeline_port_in_action_handler port_in_action = NULL;
-rte_pipeline_port_out_action_handler port_out_action = NULL;
-rte_pipeline_table_action_handler_hit action_handler_hit = NULL;
-rte_pipeline_table_action_handler_miss action_handler_miss = NULL;
-
-/* Function prototypes */
-static void app_init_rings(void);
-static void app_init_mbuf_pools(void);
-
-uint64_t pipeline_test_hash(void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = ip_dst;
-
- return signature;
-}
-
-uint32_t pipeline_test_hash_cuckoo(const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = ip_dst;
-
- return signature;
-}
-
-static void
-app_free_resources(void) {
- int i;
- for (i = 0; i < N_PORTS; i++)
- rte_ring_free(rings_rx[i]);
- rte_mempool_free(pool);
-}
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- printf("Getting/Creating the mempool ...\n");
- pool = rte_mempool_lookup("mempool");
- if (!pool) {
- pool = rte_pktmbuf_pool_create(
- "mempool",
- POOL_SIZE,
- POOL_CACHE_SIZE, 0, POOL_BUFFER_SIZE,
- 0);
- if (pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
- }
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
- rings_rx[i] = rte_ring_lookup(name);
- if (rings_rx[i] == NULL) {
- rings_rx[i] = rte_ring_create(
- name,
- RING_RX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < N_PORTS; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
- rings_tx[i] = rte_ring_lookup(name);
- if (rings_tx[i] == NULL) {
- rings_tx[i] = rte_ring_create(
- name,
- RING_TX_SIZE,
- 0,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- }
- if (rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static int
-test_table(void)
-{
- int status, ret;
- unsigned i;
-
- ret = TEST_SUCCESS;
-
- app_init_rings();
- app_init_mbuf_pools();
-
- printf("\n\n\n\n************Pipeline tests************\n");
-
- if (test_table_pipeline() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-
- printf("\n\n\n\n************Port tests************\n");
- for (i = 0; i < n_port_tests; i++) {
- status = port_tests[i]();
- if (status < 0) {
- printf("\nPort test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests; i++) {
- status = table_tests[i]();
- if (status < 0) {
- printf("\nTable test number %d failed (%d).\n", i,
- status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
- printf("\n\n\n\n************Table tests************\n");
- for (i = 0; i < n_table_tests_combined; i++) {
- status = table_tests_combined[i]();
- if (status < 0) {
- printf("\nCombined table test number %d failed with "
- "reason number %d.\n", i, status);
- ret = TEST_FAILED;
- goto end;
- }
- }
-
-#ifdef RTE_LIB_ACL
- printf("\n\n\n\n************ACL tests************\n");
- if (test_table_acl() < 0) {
- ret = TEST_FAILED;
- goto end;
- }
-#endif
-
-end:
- app_free_resources();
-
- return ret;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
-
-REGISTER_FAST_TEST(table_autotest, NOHUGE_OK, ASAN_OK, test_table);
diff --git a/app/test/test_table.h b/app/test/test_table.h
deleted file mode 100644
index 209bdbff2c9d48a08aefba15b5c616b7d7fd41cb..0000000000000000000000000000000000000000
--- a/app/test/test_table.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <rte_table_stub.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_table_array.h>
-#include <rte_pipeline.h>
-
-#ifdef RTE_LIB_ACL
-#include <rte_table_acl.h>
-#endif
-
-#include <rte_port_ring.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_source_sink.h>
-
-#ifndef TEST_TABLE_H_
-#define TEST_TABLE_H_
-
-#define RING_SIZE 4096
-#define MAX_BULK 32
-#define N 65536
-#define TIME_S 5
-#define TEST_RING_FULL_EMTPY_ITER 8
-#define N_PORTS 2
-#define N_PKTS 2
-#define N_PKTS_EXT 6
-#define RING_RX rings_rx[0]
-#define RING_RX_2 rings_rx[1]
-#define RING_TX rings_tx[0]
-#define RING_TX_2 rings_tx[1]
-#define PORT_RX_RING_SIZE 128
-#define PORT_TX_RING_SIZE 512
-#define RING_RX_SIZE 128
-#define RING_TX_SIZE 128
-#define POOL_BUFFER_SIZE RTE_MBUF_DEFAULT_BUF_SIZE
-#define POOL_SIZE (32 * 1024)
-#define POOL_CACHE_SIZE 256
-#define BURST_SIZE 8
-#define WORKER_TYPE 1
-#define MAX_DUMMY_PORTS 2
-#define MP_NAME "dummy_port_mempool"
-#define MBUF_COUNT (8000 * MAX_DUMMY_PORTS)
-#define MP_CACHE_SZ 256
-#define MP_SOCKET 0
-#define MP_FLAGS 0
-
-/* Macros */
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#define RING_ENQUEUE(ring, value) do { \
- struct rte_mbuf *m; \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- \
- m = rte_pktmbuf_alloc(pool); \
- if (m == NULL) \
- return -1; \
- signature = RTE_MBUF_METADATA_UINT32_PTR(m, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(m, \
- APP_METADATA_OFFSET(32)); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
- rte_ring_enqueue((ring), m); \
-} while (0)
-
-#define RUN_PIPELINE(pipeline) do { \
- rte_pipeline_run((pipeline)); \
- rte_pipeline_flush((pipeline)); \
-} while (0)
-
-#define VERIFY(var, value) do { \
- if ((var) != -(value)) \
- return var; \
-} while (0)
-
-#define VERIFY_TRAFFIC(ring, sent, expected) do { \
- unsigned i, n = 0; \
- void *mbuf = NULL; \
- \
- for (i = 0; i < (sent); i++) { \
- if (!rte_ring_dequeue((ring), &mbuf)) { \
- if (mbuf == NULL) \
- continue; \
- n++; \
- rte_pktmbuf_free((struct rte_mbuf *)mbuf); \
- } \
- else \
- break; \
- } \
- printf("Expected %d, got %d\n", expected, n); \
- if (n != (expected)) { \
- return -21; \
- } \
-} while (0)
-
-/* Function definitions */
-uint64_t pipeline_test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed);
-
-uint32_t pipeline_test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed);
-
-/* Extern variables */
-extern struct rte_pipeline *p;
-extern struct rte_ring *rings_rx[N_PORTS];
-extern struct rte_ring *rings_tx[N_PORTS];
-extern struct rte_mempool *pool;
-extern uint32_t port_in_id[N_PORTS];
-extern uint32_t port_out_id[N_PORTS];
-extern uint32_t port_out_id_type[3];
-extern uint32_t table_id[N_PORTS*2];
-extern uint64_t override_hit_mask;
-extern uint64_t override_miss_mask;
-extern uint64_t non_reserved_actions_hit;
-extern uint64_t non_reserved_actions_miss;
-extern uint8_t connect_miss_action_to_port_out;
-extern uint8_t connect_miss_action_to_table;
-extern uint32_t table_entry_default_action;
-extern uint32_t table_entry_hit_action;
-extern uint32_t table_entry_miss_action;
-extern rte_pipeline_port_in_action_handler port_in_action;
-extern rte_pipeline_port_out_action_handler port_out_action;
-extern rte_pipeline_table_action_handler_hit action_handler_hit;
-extern rte_pipeline_table_action_handler_miss action_handler_miss;
-
-/* Global data types */
-struct manage_ops {
- uint32_t op_id;
- void *op_data;
- int expected_result;
-};
-
-/* Internal pipeline structures */
-struct rte_port_in {
- struct rte_port_in_ops ops;
- uint32_t burst_size;
- uint32_t table_id;
- void *h_port;
-};
-
-struct rte_port_out {
- struct rte_port_out_ops ops;
- void *h_port;
-};
-
-struct rte_table {
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action;
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
- uint8_t actions_lookup_miss[RTE_CACHE_LINE_SIZE];
- uint32_t action_data_size;
- void *h_table;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct rte_pipeline {
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- uint32_t socket_id;
- struct rte_port_in ports_in[16];
- struct rte_port_out ports_out[16];
- struct rte_table tables[64];
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_table_entry *actions[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t mask_action[64];
- uint32_t mask_actions;
-};
-#endif
diff --git a/app/test/test_table_acl.c b/app/test/test_table_acl.c
deleted file mode 100644
index 4fdf731596788e1bdee955d8c2d414452d1ebdea..0000000000000000000000000000000000000000
--- a/app/test/test_table_acl.c
+++ /dev/null
@@ -1,728 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <rte_ip.h>
-#include <rte_string_fns.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_acl.h"
-
-/*
- * Rule and trace formats definitions.
- **/
-
-struct ipv4_5tuple {
- uint8_t proto;
- uint32_t ip_src;
- uint32_t ip_dst;
- uint16_t port_src;
- uint16_t port_dst;
-};
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-struct rte_acl_field_def ipv4_defs[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, proto),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, ip_dst),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_src),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = offsetof(struct ipv4_5tuple, port_dst),
- },
-};
-
-struct rte_table_acl_rule_add_params table_acl_IPv4_rule;
-
-typedef int (*parse_5tuple)(char *text,
- struct rte_table_acl_rule_add_params *rule);
-
-/*
-* The order of the fields in the rule string after the initial '@'
-*/
-enum {
- CB_FLD_SRC_ADDR,
- CB_FLD_DST_ADDR,
- CB_FLD_SRC_PORT_RANGE,
- CB_FLD_DST_PORT_RANGE,
- CB_FLD_PROTO,
- CB_FLD_NUM,
-};
-
-
-#define GET_CB_FIELD(in, fd, base, lim, dlm) \
-do { \
- unsigned long val; \
- char *end; \
- \
- errno = 0; \
- val = strtoul((in), &end, (base)); \
- if (errno != 0 || end[0] != (dlm) || val > (lim)) \
- return -EINVAL; \
- (fd) = (typeof(fd)) val; \
- (in) = end + 1; \
-} while (0)
-
-
-
-
-static int
-parse_ipv4_net(const char *in, uint32_t *addr, uint32_t *mask_len)
-{
- uint8_t a, b, c, d, m;
-
- GET_CB_FIELD(in, a, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, b, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, c, 0, UINT8_MAX, '.');
- GET_CB_FIELD(in, d, 0, UINT8_MAX, '/');
- GET_CB_FIELD(in, m, 0, sizeof(uint32_t) * CHAR_BIT, 0);
-
- addr[0] = RTE_IPV4(a, b, c, d);
- mask_len[0] = m;
-
- return 0;
-}
-
-static int
-parse_port_range(const char *in, uint16_t *port_low, uint16_t *port_high)
-{
- uint16_t a, b;
-
- GET_CB_FIELD(in, a, 0, UINT16_MAX, ':');
- GET_CB_FIELD(in, b, 0, UINT16_MAX, 0);
-
- port_low[0] = a;
- port_high[0] = b;
-
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule(char *str, struct rte_table_acl_rule_add_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-parse_cb_ipv4_rule_del(char *str, struct rte_table_acl_rule_delete_params *v)
-{
- int i, rc;
- char *s, *sp, *in[CB_FLD_NUM];
- static const char *dlm = " \t\n";
-
- /*
- ** Skip leading '@'
- */
- if (strchr(str, '@') != str)
- return -EINVAL;
-
- s = str + 1;
-
- /*
- * Populate the 'in' array with the location of each
- * field in the string we're parsing
- */
- for (i = 0; i != DIM(in); i++) {
- in[i] = strtok_r(s, dlm, &sp);
- if (in[i] == NULL)
- return -EINVAL;
- s = NULL;
- }
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_SRC_ADDR],
- &v->field_value[SRC_FIELD_IPV4].value.u32,
- &v->field_value[SRC_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read src address/mask: %s\n",
- in[CB_FLD_SRC_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRC_FIELD_IPV4].value.u32,
- v->field_value[SRC_FIELD_IPV4].mask_range.u32);
-
- /* Parse x.x.x.x/x */
- rc = parse_ipv4_net(in[CB_FLD_DST_ADDR],
- &v->field_value[DST_FIELD_IPV4].value.u32,
- &v->field_value[DST_FIELD_IPV4].mask_range.u32);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest address/mask: %s\n",
- in[CB_FLD_DST_ADDR]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DST_FIELD_IPV4].value.u32,
- v->field_value[DST_FIELD_IPV4].mask_range.u32);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_SRC_PORT_RANGE],
- &v->field_value[SRCP_FIELD_IPV4].value.u16,
- &v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read source port range: %s\n",
- in[CB_FLD_SRC_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[SRCP_FIELD_IPV4].value.u16,
- v->field_value[SRCP_FIELD_IPV4].mask_range.u16);
- /* Parse n:n */
- rc = parse_port_range(in[CB_FLD_DST_PORT_RANGE],
- &v->field_value[DSTP_FIELD_IPV4].value.u16,
- &v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- if (rc != 0) {
- fprintf(stderr, "failed to read dest port range: %s\n",
- in[CB_FLD_DST_PORT_RANGE]);
- return rc;
- }
-
- printf("V=%u, mask=%u\n", v->field_value[DSTP_FIELD_IPV4].value.u16,
- v->field_value[DSTP_FIELD_IPV4].mask_range.u16);
- /* parse 0/0xnn */
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].value.u8,
- 0, UINT8_MAX, '/');
- GET_CB_FIELD(in[CB_FLD_PROTO],
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8,
- 0, UINT8_MAX, 0);
-
- printf("V=%u, mask=%u\n",
- (unsigned int)v->field_value[PROTO_FIELD_IPV4].value.u8,
- v->field_value[PROTO_FIELD_IPV4].mask_range.u8);
- return 0;
-}
-
-static int
-setup_acl_pipeline(void)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
- uint32_t n;
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_acl_rule_delete_params *delete_params;
- parse_5tuple parser;
- char acl_name[64];
-
- /*
- * The format for these rules DO NOT need the port ranges to be
- * separated by ' : ', just ':'. It's a lot more readable and
- * cleaner, IMO.
- */
- static const char * const lines[] = {
- "@0.0.0.0/0 0.0.0.0/0 0:65535 0:65535 2/0xff", /* Protocol check */
- "@192.168.3.1/32 0.0.0.0/0 0:65535 0:65535 0/0", /* Src IP check */
- "@0.0.0.0/0 10.4.4.1/32 0:65535 0:65535 0/0", /* dst IP check */
- "@0.0.0.0/0 0.0.0.0/0 105:105 0:65535 0/0", /* src port check */
- "@0.0.0.0/0 0.0.0.0/0 0:65535 206:206 0/0", /* dst port check */
- };
- char line[LINE_MAX];
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = port_in_action;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params;
-
- /* Set up defaults for stub */
- table_params.ops = &rte_table_stub_ops;
- table_params.arg_create = NULL;
- table_params.f_action_hit = action_handler_hit;
- table_params.f_action_miss = NULL;
- table_params.action_data_size = 0;
-
- printf("miss_action=%x\n",
- table_entry_miss_action);
-
- printf("RTE_ACL_RULE_SZ(%zu) = %zu\n", DIM(ipv4_defs),
- RTE_ACL_RULE_SZ(DIM(ipv4_defs)));
-
- struct rte_table_acl_params acl_params;
-
- acl_params.n_rules = 1 << 5;
- acl_params.n_rule_fields = DIM(ipv4_defs);
- snprintf(acl_name, sizeof(acl_name), "ACL%d", i);
- acl_params.name = acl_name;
- memcpy(acl_params.field_format, ipv4_defs, sizeof(ipv4_defs));
-
- table_params.ops = &rte_table_acl_ops;
- table_params.arg_create = &acl_params;
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table) {
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
- }
-
- for (i = 0; i < N_PORTS; i++) {
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n",
- port_in_id[i], table_id[i]);
- goto fail;
- }
- }
-
- /* Add bulk entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_add_params keys[5];
- struct rte_pipeline_table_entry entries[5];
- struct rte_table_acl_rule_add_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
- struct rte_pipeline_table_entry *table_entries_ptr[5];
- struct rte_pipeline_table_entry entries_ptr[5];
-
- parser = parse_cb_ipv4_rule;
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_add_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- keys[n].priority = RTE_ACL_MAX_PRIORITY - n - 1;
-
- entries[n].action = RTE_PIPELINE_ACTION_PORT;
- entries[n].port_id = port_out_id[i^1];
- table_entries[n] = &entries[n];
- table_entries_ptr[n] = &entries_ptr[n];
- }
-
- ret = rte_pipeline_table_entry_add_bulk(p, table_id[i],
- (void **)key_array, table_entries, 5, key_found, table_entries_ptr);
- if (ret < 0) {
- rte_panic("Add entry bulk to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* Delete bulk entries from tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_table_acl_rule_delete_params keys[5];
- struct rte_table_acl_rule_delete_params *key_array[5];
- struct rte_pipeline_table_entry *table_entries[5];
- int key_found[5];
-
- memset(table_entries, 0, sizeof(table_entries));
-
- for (n = 0; n < 5; n++) {
- memset(&keys[n], 0, sizeof(struct rte_table_acl_rule_delete_params));
- key_array[n] = &keys[n];
-
- strlcpy(line, lines[n], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parse_cb_ipv4_rule_del(line, &keys[n]);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
- }
-
- ret = rte_pipeline_table_entry_delete_bulk(p, table_id[i],
- (void **)key_array, 5, key_found, table_entries);
- if (ret < 0) {
- rte_panic("Delete bulk entries from table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Bulk deleted rules.\n");
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- int key_found;
- struct rte_pipeline_table_entry *entry_ptr;
-
- memset(&rule_params, 0, sizeof(rule_params));
- parser = parse_cb_ipv4_rule;
-
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse_cb_ipv4vlan_rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
-
- /* delete a few rules */
- for (n = 2; n <= 3; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- delete_params = (struct
- rte_pipeline_table_acl_rule_delete_params *)
- &(rule_params.field_value[0]);
- ret = rte_pipeline_table_entry_delete(p, table_id[i],
- delete_params, &key_found, NULL);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Deleted Rule.\n");
- }
-
-
- /* Try to add duplicates */
- for (n = 1; n <= 5; n++) {
- strlcpy(line, lines[n - 1], sizeof(line));
- printf("PARSING [%s]\n", line);
-
- ret = parser(line, &rule_params);
- if (ret != 0) {
- fprintf(stderr,
- "line %u: parse rule failed, error code: %d (%s)\n",
- n, ret, strerror(-ret));
- return ret;
- }
-
- rule_params.priority = RTE_ACL_MAX_PRIORITY - n;
-
- ret = rte_pipeline_table_entry_add(p, table_id[i],
- &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0) {
- rte_panic("Add entry to table %u failed (%d)\n",
- table_id[i], ret);
- goto fail;
- }
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- }
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int expected_count)
-{
- int i, j, ret, tx_count;
- struct ipv4_5tuple five_tuple;
-
- /* Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++) {
- for (j = 0; j < 8; j++) {
- struct rte_mbuf *mbuf;
-
- mbuf = rte_pktmbuf_alloc(pool);
- if (mbuf == NULL)
- /* this will cause test failure after cleanup
- * of already enqueued mbufs, as the mbuf
- * counts won't match */
- break;
- memset(rte_pktmbuf_mtod(mbuf, char *), 0x00,
- sizeof(struct ipv4_5tuple));
-
- five_tuple.proto = j;
- five_tuple.ip_src = rte_bswap32(RTE_IPV4(192, 168, j, 1));
- five_tuple.ip_dst = rte_bswap32(RTE_IPV4(10, 4, j, 1));
- five_tuple.port_src = rte_bswap16(100 + j);
- five_tuple.port_dst = rte_bswap16(200 + j);
-
- memcpy(rte_pktmbuf_mtod(mbuf, char *), &five_tuple,
- sizeof(struct ipv4_5tuple));
- printf("%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], mbuf);
- }
- }
-
- /* Run pipeline once */
- for (i = 0; i< N_PORTS; i++)
- rte_pipeline_run(p);
-
- rte_pipeline_flush(p);
-
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0) {
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- } else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "mbuf",
- rte_pktmbuf_mtod(mbuf, char *), 64);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets for ACL test, expected %d, got %d\n",
- __func__, expected_count, tx_count);
- goto fail;
- }
-
- rte_pipeline_free(p);
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_acl(void)
-{
-
-
- override_hit_mask = 0xFF; /* All packets are a hit */
-
- setup_acl_pipeline();
- if (test_pipeline_single_filter(10) < 0)
- return -1;
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_acl.h b/app/test/test_table_acl.h
deleted file mode 100644
index a6ae7d28385137fedfbfabe199ad0ac412ca698e..0000000000000000000000000000000000000000
--- a/app/test/test_table_acl.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_acl(void);
diff --git a/app/test/test_table_combined.c b/app/test/test_table_combined.c
deleted file mode 100644
index 04503baa5180fb4e00f536d19315c026008eaf8d..0000000000000000000000000000000000000000
--- a/app/test/test_table_combined.c
+++ /dev/null
@@ -1,846 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include "test_table_combined.h"
-#include "test_table.h"
-#include <rte_table_lpm_ipv6.h>
-
-#define MAX_TEST_KEYS 128
-#define N_PACKETS 50
-
-enum check_table_result {
- CHECK_TABLE_OK,
- CHECK_TABLE_PORT_CONFIG,
- CHECK_TABLE_PORT_ENABLE,
- CHECK_TABLE_TABLE_CONFIG,
- CHECK_TABLE_ENTRY_ADD,
- CHECK_TABLE_DEFAULT_ENTRY_ADD,
- CHECK_TABLE_CONNECT,
- CHECK_TABLE_MANAGE_ERROR,
- CHECK_TABLE_CONSISTENCY,
- CHECK_TABLE_NO_TRAFFIC,
- CHECK_TABLE_INVALID_PARAMETER,
-};
-
-struct table_packets {
- uint32_t hit_packet[MAX_TEST_KEYS];
- uint32_t miss_packet[MAX_TEST_KEYS];
- uint32_t n_hit_packets;
- uint32_t n_miss_packets;
-};
-
-combined_table_test table_tests_combined[] = {
- test_table_lpm_combined,
- test_table_lpm_ipv6_combined,
- test_table_hash8lru,
- test_table_hash8ext,
- test_table_hash16lru,
- test_table_hash16ext,
- test_table_hash32lru,
- test_table_hash32ext,
- test_table_hash_cuckoo_combined,
-};
-
-unsigned n_table_tests_combined = RTE_DIM(table_tests_combined);
-
-/* Generic port tester function */
-static int
-test_table_type(struct rte_table_ops *table_ops, void *table_args,
- void *key, struct table_packets *table_packets,
- struct manage_ops *manage_ops, unsigned n_ops)
-{
- uint32_t ring_in_id, table_id, ring_out_id, ring_out_2_id;
- unsigned i;
-
- RTE_SET_USED(manage_ops);
- RTE_SET_USED(n_ops);
- /* Create pipeline */
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = 0,
- };
-
- struct rte_pipeline *pipeline = rte_pipeline_create(&pipeline_params);
-
- /* Create input ring */
- struct rte_port_ring_reader_params ring_params_rx = {
- .ring = RING_RX,
- };
-
- struct rte_port_ring_writer_params ring_params_tx = {
- .ring = RING_RX,
- .tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- struct rte_pipeline_port_in_params ring_in_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *)&ring_params_rx,
- .f_action = NULL,
- .burst_size = RTE_PORT_IN_BURST_SIZE_MAX,
- };
-
- if (rte_pipeline_port_in_create(pipeline, &ring_in_params,
- &ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Create table */
- struct rte_pipeline_table_params table_params = {
- .ops = table_ops,
- .arg_create = table_args,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(pipeline, &table_params,
- &table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_TABLE_CONFIG;
- }
-
- /* Create output ports */
- ring_params_tx.ring = RING_TX;
-
- struct rte_pipeline_port_out_params ring_out_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *)&ring_params_tx,
- .f_action = NULL,
- };
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- ring_params_tx.ring = RING_TX_2;
-
- if (rte_pipeline_port_out_create(pipeline, &ring_out_params,
- &ring_out_2_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_CONFIG;
- }
-
- /* Add entry to the table */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_DROP,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.table_id = ring_out_id},
- };
-
- struct rte_pipeline_table_entry *default_entry_ptr, *entry_ptr;
-
- int key_found;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_DEFAULT_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Create connections and check consistency */
- if (rte_pipeline_port_in_connect_to_table(pipeline, ring_in_id,
- table_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONNECT;
- }
-
- if (rte_pipeline_port_in_enable(pipeline, ring_in_id) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_PORT_ENABLE;
- }
-
- if (rte_pipeline_check(pipeline) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_CONSISTENCY;
- }
-
-
-
- /* Flow test - All hits */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- /* Flow test - All misses */
- if (table_packets->n_miss_packets) {
- for (i = 0; i < table_packets->n_miss_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
-
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
- /* Flow test - Half hits, half misses */
- if (table_packets->n_hit_packets && table_packets->n_miss_packets) {
- for (i = 0; i < (table_packets->n_hit_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- for (i = 0; i < (table_packets->n_miss_packets) / 2; i++)
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets,
- table_packets->n_hit_packets / 2);
- }
-
- /* Flow test - Single packet */
- if (table_packets->n_hit_packets) {
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 1);
- }
- if (table_packets->n_miss_packets) {
- RING_ENQUEUE(RING_RX, table_packets->miss_packet[0]);
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_miss_packets, 0);
- }
-
-
- /* Change table entry action */
- printf("Change entry action\n");
- table_entry.table_id = ring_out_2_id;
-
- if (rte_pipeline_table_default_entry_add(pipeline, table_id,
- &default_entry, &default_entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- if (rte_pipeline_table_entry_add(pipeline, table_id,
- key ? key : &table_entry, &table_entry, &key_found,
- &entry_ptr) != 0) {
- rte_pipeline_free(pipeline);
- return -CHECK_TABLE_ENTRY_ADD;
- }
-
- /* Check that traffic destination has changed */
- if (table_packets->n_hit_packets) {
- for (i = 0; i < table_packets->n_hit_packets; i++)
- RING_ENQUEUE(RING_RX, table_packets->hit_packet[i]);
-
- RUN_PIPELINE(pipeline);
- VERIFY_TRAFFIC(RING_TX, table_packets->n_hit_packets, 0);
- VERIFY_TRAFFIC(RING_TX_2, table_packets->n_hit_packets,
- table_packets->n_hit_packets);
- }
-
- printf("delete entry\n");
- /* Delete table entry */
- rte_pipeline_table_entry_delete(pipeline, table_id,
- key ? key : &table_entry, &key_found, NULL);
-
- rte_pipeline_free(pipeline);
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub_combined(void)
-{
- int status, i;
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = i;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = 0;
-
- status = test_table_type(&rte_table_stub_ops, NULL, NULL,
- &table_packets, NULL, 1);
- VERIFY(status, CHECK_TABLE_OK);
-
- return 0;
-}
-
-int
-test_table_lpm_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(0),
- };
-
- struct rte_table_lpm_key lpm_key = {
- .ip = 0xadadadad,
- .depth = 16,
- };
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_params.n_rules = 1 << 24;
- lpm_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_key.depth = 33;
-
- status = test_table_type(&rte_table_lpm_ops, (void *)&lpm_params,
- (void *)&lpm_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_lpm_ipv6_params lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 16,
- .number_tbl8s = 1 << 13,
- .entry_unique_size = 8,
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_table_lpm_ipv6_key lpm_ipv6_key = {
- .depth = 16,
- };
- memset(&lpm_ipv6_key.ip, 0xad, 16);
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < N_PACKETS; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < N_PACKETS; i++)
- table_packets.miss_packet[i] = 0xadadadab;
-
- table_packets.n_hit_packets = N_PACKETS;
- table_packets.n_miss_packets = N_PACKETS;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- lpm_ipv6_params.n_rules = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- lpm_ipv6_params.n_rules = 1 << 24;
- lpm_ipv6_key.depth = 0;
-
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- lpm_ipv6_key.depth = 129;
- status = test_table_type(&rte_table_lpm_ipv6_ops,
- (void *)&lpm_ipv6_params,
- (void *)&lpm_ipv6_key, &table_packets, NULL, 0);
- VERIFY(status, CHECK_TABLE_ENTRY_ADD);
-
- return 0;
-}
-
-int
-test_table_hash8lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8lru_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8lru[8];
- uint32_t *k8lru = (uint32_t *) key8lru;
-
- memset(key8lru, 0, sizeof(key8lru));
- k8lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8lru_params.n_keys = 1<<16;
- key8lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_lru_ops,
- (void *)&key8lru_params, (void *)key8lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16lru_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16lru[16];
- uint32_t *k16lru = (uint32_t *) key16lru;
-
- memset(key16lru, 0, sizeof(key16lru));
- k16lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xfefefefe;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16lru_params.n_keys = 1<<16;
- key16lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_lru_ops,
- (void *)&key16lru_params, (void *)key16lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32lru(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32lru_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32lru[32];
- uint32_t *k32lru = (uint32_t *) key32lru;
-
- memset(key32lru, 0, sizeof(key32lru));
- k32lru[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32lru_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32lru_params.n_keys = 1<<16;
- key32lru_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_lru_ops,
- (void *)&key32lru_params, (void *)key32lru, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash8ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key8ext_params = {
- .name = "TABLE",
- .key_size = 8,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key8ext[8];
- uint32_t *k8ext = (uint32_t *) key8ext;
-
- memset(key8ext, 0, sizeof(key8ext));
- k8ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key8ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key8ext_params.n_keys = 1<<16;
- key8ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key8_ext_ops,
- (void *)&key8ext_params, (void *)key8ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash16ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key16ext_params = {
- .name = "TABLE",
- .key_size = 16,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key16ext[16];
- uint32_t *k16ext = (uint32_t *) key16ext;
-
- memset(key16ext, 0, sizeof(key16ext));
- k16ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key16ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key16ext_params.n_keys = 1<<16;
- key16ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key16_ext_ops,
- (void *)&key16ext_params, (void *)key16ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash32ext(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_params key32ext_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- uint8_t key32ext[32];
- uint32_t *k32ext = (uint32_t *) key32ext;
-
- memset(key32ext, 0, sizeof(key32ext));
- k32ext[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- key32ext_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- key32ext_params.n_keys = 1<<16;
- key32ext_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_key32_ext_ops,
- (void *)&key32ext_params, (void *)key32ext, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-int
-test_table_hash_cuckoo_combined(void)
-{
- int status, i;
-
- /* Traffic flow */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) key_cuckoo;
-
- memset(key_cuckoo, 0, sizeof(key_cuckoo));
- kcuckoo[0] = 0xadadadad;
-
- struct table_packets table_packets;
-
- printf("--------------\n");
- printf("RUNNING TEST - %s\n", __func__);
- printf("--------------\n");
- for (i = 0; i < 50; i++)
- table_packets.hit_packet[i] = 0xadadadad;
-
- for (i = 0; i < 50; i++)
- table_packets.miss_packet[i] = 0xbdadadad;
-
- table_packets.n_hit_packets = 50;
- table_packets.n_miss_packets = 50;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_OK);
-
- /* Invalid parameters */
- cuckoo_params.key_size = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- cuckoo_params.n_keys = 1<<16;
- cuckoo_params.f_hash = NULL;
-
- status = test_table_type(&rte_table_hash_cuckoo_ops,
- (void *)&cuckoo_params, (void *)key_cuckoo, &table_packets,
- NULL, 0);
- VERIFY(status, CHECK_TABLE_TABLE_CONFIG);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_combined.h b/app/test/test_table_combined.h
deleted file mode 100644
index fb94dbb94d08c48ba4bc94e6e657c0eb4fe6b8ce..0000000000000000000000000000000000000000
--- a/app/test/test_table_combined.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_stub_combined(void);
-int test_table_lpm_combined(void);
-int test_table_lpm_ipv6_combined(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash8unoptimized(void);
-int test_table_hash8lru(void);
-int test_table_hash8ext(void);
-int test_table_hash16unoptimized(void);
-int test_table_hash16lru(void);
-int test_table_hash16ext(void);
-int test_table_hash32unoptimized(void);
-int test_table_hash32lru(void);
-int test_table_hash32ext(void);
-int test_table_hash_cuckoo_combined(void);
-
-/* Extern variables */
-typedef int (*combined_table_test)(void);
-
-extern combined_table_test table_tests_combined[];
-extern unsigned n_table_tests_combined;
diff --git a/app/test/test_table_pipeline.c b/app/test/test_table_pipeline.c
deleted file mode 100644
index 960f730cf20d261653c8e78b477cc91b462674a6..0000000000000000000000000000000000000000
--- a/app/test/test_table_pipeline.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_pipeline.h>
-#include <inttypes.h>
-#include <rte_hexdump.h>
-#include "test_table.h"
-#include "test_table_pipeline.h"
-
-#if 0
-
-static rte_pipeline_port_out_action_handler port_action_0x00
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_0xFF
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-static rte_pipeline_port_out_action_handler port_action_stub
- (struct rte_mbuf **pkts, uint32_t n, uint64_t *pkts_mask, void *arg);
-
-
-rte_pipeline_port_out_action_handler port_action_0x00(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0x00\n");
- *pkts_mask = 0x00;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_0xFF(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(arg);
- printf("Port Action 0xFF\n");
- *pkts_mask = 0xFF;
- return 0;
-}
-
-rte_pipeline_port_out_action_handler port_action_stub(struct rte_mbuf **pkts,
- uint32_t n,
- uint64_t *pkts_mask,
- void *arg)
-{
- RTE_SET_USED(pkts);
- RTE_SET_USED(n);
- RTE_SET_USED(pkts_mask);
- RTE_SET_USED(arg);
- printf("Port Action stub\n");
- return 0;
-}
-
-#endif
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry **entry, void *arg);
-
-static int
-table_action_stub_miss(struct rte_pipeline *p, struct rte_mbuf **pkts,
- uint64_t pkts_mask, struct rte_pipeline_table_entry *entry, void *arg);
-
-rte_pipeline_table_action_handler_hit
-table_action_0x00(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("Table Action, setting pkts_mask to 0x00\n");
- pkts_mask = ~0x00;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-rte_pipeline_table_action_handler_hit
-table_action_stub_hit(__rte_unused struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry **entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Hit - doing nothing\n");
- printf("STUB Table Action Hit - setting mask to 0x%"PRIx64"\n",
- override_hit_mask);
- pkts_mask = (~override_hit_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-static int
-table_action_stub_miss(struct rte_pipeline *p,
- __rte_unused struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- __rte_unused struct rte_pipeline_table_entry *entry,
- __rte_unused void *arg)
-{
- printf("STUB Table Action Miss - setting mask to 0x%"PRIx64"\n",
- override_miss_mask);
- pkts_mask = (~override_miss_mask) & 0x3;
- rte_pipeline_ah_packet_drop(p, pkts_mask);
- return 0;
-}
-
-enum e_test_type {
- e_TEST_STUB = 0,
- e_TEST_LPM,
- e_TEST_LPM6,
- e_TEST_HASH_LRU_8,
- e_TEST_HASH_LRU_16,
- e_TEST_HASH_LRU_32,
- e_TEST_HASH_EXT_8,
- e_TEST_HASH_EXT_16,
- e_TEST_HASH_EXT_32
-};
-
-char pipeline_test_names[][64] = {
- "Stub",
- "LPM",
- "LPMv6",
- "8-bit LRU Hash",
- "16-bit LRU Hash",
- "32-bit LRU Hash",
- "16-bit Ext Hash",
- "8-bit Ext Hash",
- "32-bit Ext Hash",
- ""
-};
-
-
-static int
-cleanup_pipeline(void)
-{
-
- rte_pipeline_free(p);
-
- return 0;
-}
-
-
-static int check_pipeline_invalid_params(void);
-
-static int
-check_pipeline_invalid_params(void)
-{
- struct rte_pipeline_params pipeline_params_1 = {
- .name = NULL,
- .socket_id = 0,
- };
- struct rte_pipeline_params pipeline_params_2 = {
- .name = "PIPELINE",
- .socket_id = -1,
- };
- struct rte_pipeline_params pipeline_params_3 = {
- .name = "PIPELINE",
- .socket_id = 127,
- };
-
- p = rte_pipeline_create(NULL);
- if (p != NULL) {
- fprintf(stderr,
- "%s: configured pipeline with null params\n",
- __func__);
- goto fail;
- }
- p = rte_pipeline_create(&pipeline_params_1);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with NULL name\n", __func__);
- goto fail;
- }
-
- p = rte_pipeline_create(&pipeline_params_2);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n", __func__);
- goto fail;
- }
-
- if (rte_eal_has_hugepages()) {
- p = rte_pipeline_create(&pipeline_params_3);
- if (p != NULL) {
- fprintf(stderr,
- "%s: Configure pipeline with invalid socket\n",
- __func__);
- goto fail;
- }
- }
-
- /* Check pipeline consistency */
- if (!rte_pipeline_check(p)) {
- rte_panic("Pipeline consistency reported as OK\n");
- goto fail;
- }
-
-
- return 0;
-fail:
- return -1;
-}
-
-
-static int
-setup_pipeline(int test_type)
-{
- int ret;
- int i;
- struct rte_pipeline_params pipeline_params = {
- .name = "PIPELINE",
- .socket_id = 0,
- };
-
- fprintf(stderr, "%s: **** Setting up %s test\n",
- __func__, pipeline_test_names[test_type]);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
- ret = rte_pipeline_free(p);
- if (ret != 0) {
- fprintf(stderr, "%s: Failed to free pipeline\n",
- __func__);
- goto fail;
- }
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL) {
- fprintf(stderr, "%s: Failed to configure pipeline\n",
- __func__);
- goto fail;
- }
-
-
- /* Input port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .burst_size = BURST_SIZE,
- };
-
- /* Put in action for some ports */
- if (i)
- port_params.f_action = NULL;
-
- ret = rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]);
- if (ret) {
- rte_panic("Unable to configure input port %d, ret:%d\n",
- i, ret);
- goto fail;
- }
- }
-
- /* output Port configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = rings_tx[i],
- .tx_burst_sz = BURST_SIZE,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (i)
- port_params.f_action = port_out_action;
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i])) {
- rte_panic("Unable to configure output port %d\n", i);
- goto fail;
- }
- }
-
- /* Table configuration */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = action_handler_hit,
- .f_action_miss = action_handler_miss,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
-
- if (connect_miss_action_to_table)
- if (rte_pipeline_table_create(p, &table_params,
- &table_id[i+2])) {
- rte_panic("Unable to configure table %u\n", i);
- goto fail;
- }
- }
-
- for (i = 0; i < N_PORTS; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i])) {
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
- goto fail;
- }
-
- /* Add entries to tables */
- for (i = 0; i < N_PORTS; i++) {
- struct rte_pipeline_table_entry default_entry = {
- .action = (enum rte_pipeline_action)
- table_entry_default_action,
- {.port_id = port_out_id[i^1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (connect_miss_action_to_table) {
- printf("Setting first table to output to next table\n");
- default_entry.action = RTE_PIPELINE_ACTION_TABLE;
- default_entry.table_id = table_id[i+2];
- }
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p, table_id[i],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to table %u "
- "code %d\n", table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d with "
- "action %x\n",
- table_id[i], default_entry.action);
-
- if (connect_miss_action_to_table) {
- /* We create a second table so the first can pass
- traffic into it */
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i^1]},
- };
- printf("Setting second table to output to port\n");
-
- /* Add the default action for the table. */
- ret = rte_pipeline_table_default_entry_add(p,
- table_id[i+2],
- &default_entry, &default_entry_ptr);
- if (ret < 0) {
- rte_panic("Unable to add default entry to "
- "table %u code %d\n",
- table_id[i], ret);
- goto fail;
- } else
- printf("Added default entry to table id %d "
- "with action %x\n",
- table_id[i], default_entry.action);
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < N_PORTS ; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0) {
- rte_panic("Pipeline consistency check failed\n");
- goto fail;
- } else
- printf("Pipeline Consistency OK!\n");
-
- return 0;
-fail:
-
- return -1;
-}
-
-static int
-test_pipeline_single_filter(int test_type, int expected_count)
-{
- int i;
- int j;
- int ret;
- int tx_count;
-
- fprintf(stderr, "%s: **** Running %s test\n",
- __func__, pipeline_test_names[test_type]);
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
-
- ret = rte_pipeline_flush(NULL);
- if (ret != -EINVAL) {
- fprintf(stderr,
- "%s: No pipeline flush error NULL pipeline (%d)\n",
- __func__, ret);
- goto fail;
- }
-
- /*
- * Allocate a few mbufs and manually insert into the rings. */
- for (i = 0; i < N_PORTS; i++)
- for (j = 0; j < N_PORTS; j++) {
- struct rte_mbuf *m;
- uint8_t *key;
- uint32_t *k32;
-
- m = rte_pktmbuf_alloc(pool);
- if (m == NULL) {
- rte_panic("Failed to alloc mbuf from pool\n");
- return -1;
- }
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- k32 = (uint32_t *) key;
- k32[0] = 0xadadadad >> (j % 2);
-
- fprintf(stderr, "%s: Enqueue onto ring %d\n",
- __func__, i);
- rte_ring_enqueue(rings_rx[i], m);
- }
-
- /* Run pipeline once */
- for (i = 0; i < N_PORTS; i++)
- rte_pipeline_run(p);
-
- /*
- * need to flush the pipeline, as there may be less hits than the burst
- size and they will not have been flushed to the tx rings. */
- rte_pipeline_flush(p);
-
- /*
- * Now we'll see what we got back on the tx rings. We should see whatever
- * packets we had hits on that were destined for the output ports.
- */
- tx_count = 0;
-
- for (i = 0; i < N_PORTS; i++) {
- void *objs[RING_TX_SIZE];
- struct rte_mbuf *mbuf;
-
- ret = rte_ring_sc_dequeue_burst(rings_tx[i], objs, 10, NULL);
- if (ret <= 0)
- printf("Got no objects from ring %d - error code %d\n",
- i, ret);
- else {
- printf("Got %d object(s) from ring %d!\n", ret, i);
- for (j = 0; j < ret; j++) {
- mbuf = objs[j];
- rte_hexdump(stdout, "Object:",
- rte_pktmbuf_mtod(mbuf, char *),
- mbuf->data_len);
- rte_pktmbuf_free(mbuf);
- }
- tx_count += ret;
- }
- }
-
- if (tx_count != expected_count) {
- fprintf(stderr,
- "%s: Unexpected packets out for %s test, expected %d, got %d\n",
- __func__, pipeline_test_names[test_type],
- expected_count, tx_count);
- goto fail;
- }
-
- cleanup_pipeline();
-
- return 0;
-fail:
- return -1;
-
-}
-
-int
-test_table_pipeline(void)
-{
- /* TEST - All packets dropped */
- action_handler_hit = NULL;
- action_handler_miss = NULL;
- table_entry_default_action = RTE_PIPELINE_ACTION_DROP;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 0) < 0)
- return -1;
-
- /* TEST - All packets passed through */
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /* TEST - one packet per port */
- action_handler_hit = NULL;
- action_handler_miss = table_action_stub_miss;
- table_entry_default_action = RTE_PIPELINE_ACTION_PORT;
- override_miss_mask = 0x01; /* one packet per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - one packet per port */
- override_miss_mask = 0x02; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
-
- /* TEST - all packets per port */
- override_miss_mask = 0x03; /*all per port */
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
-
- /*
- * This test will set up two tables in the pipeline. the first table
- * will forward to another table on miss, and the second table will
- * forward to port.
- */
- connect_miss_action_to_table = 1;
- table_entry_default_action = RTE_PIPELINE_ACTION_TABLE;
- action_handler_hit = NULL; /* not for stub, hitmask always zero */
- action_handler_miss = NULL;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 4) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- printf("TEST - two tables, hitmask override to 0x01\n");
- connect_miss_action_to_table = 1;
- action_handler_miss = table_action_stub_miss;
- override_miss_mask = 0x01;
- setup_pipeline(e_TEST_STUB);
- if (test_pipeline_single_filter(e_TEST_STUB, 2) < 0)
- return -1;
- connect_miss_action_to_table = 0;
-
- if (check_pipeline_invalid_params()) {
- fprintf(stderr, "%s: Check pipeline invalid params failed.\n",
- __func__);
- return -1;
- }
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_pipeline.h b/app/test/test_table_pipeline.h
deleted file mode 100644
index d66d09d6f1e61f2d7ec179017932407d4620ed04..0000000000000000000000000000000000000000
--- a/app/test/test_table_pipeline.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_pipeline(void);
diff --git a/app/test/test_table_ports.c b/app/test/test_table_ports.c
deleted file mode 100644
index 282ec2a3d20a84e33c9c9557189304f09d83ead0..0000000000000000000000000000000000000000
--- a/app/test/test_table_ports.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include "test_table_ports.h"
-#include "test_table.h"
-
-port_test port_tests[] = {
- test_port_ring_reader,
- test_port_ring_writer,
-};
-
-unsigned n_port_tests = RTE_DIM(port_tests);
-
-/* Port tests */
-int
-test_port_ring_reader(void)
-{
- int status, i;
- struct rte_port_ring_reader_params port_ring_reader_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_reader_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- /* Create and free */
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
- if (port == NULL)
- return -3;
-
- status = rte_port_ring_reader_ops.f_free(port);
- if (status != 0)
- return -4;
-
- /* -- Traffic RX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- void *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_reader_params.ring = RING_RX;
- port = rte_port_ring_reader_ops.f_create(&port_ring_reader_params, 0);
-
- /* Single packet */
- mbuf[0] = (void *)rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- mbuf, 1, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf, 1);
-
- if (received_pkts < expected_pkts)
- return -5;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
-
- expected_pkts = rte_ring_sp_enqueue_burst(port_ring_reader_params.ring,
- (void * const *) mbuf, RTE_PORT_IN_BURST_SIZE_MAX, NULL);
- received_pkts = rte_port_ring_reader_ops.f_rx(port, res_mbuf,
- RTE_PORT_IN_BURST_SIZE_MAX);
-
- if (received_pkts < expected_pkts)
- return -6;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-int
-test_port_ring_writer(void)
-{
- int status, i;
- struct rte_port_ring_writer_params port_ring_writer_params;
- void *port;
-
- /* Invalid params */
- port = rte_port_ring_writer_ops.f_create(NULL, 0);
- if (port != NULL)
- return -1;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status >= 0)
- return -2;
-
- port_ring_writer_params.ring = NULL;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -3;
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX + 1;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port != NULL)
- return -4;
-
- /* Create and free */
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
-
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
- if (port == NULL)
- return -5;
-
- status = rte_port_ring_writer_ops.f_free(port);
- if (status != 0)
- return -6;
-
- /* -- Traffic TX -- */
- int expected_pkts, received_pkts;
- struct rte_mbuf *mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *res_mbuf[RTE_PORT_IN_BURST_SIZE_MAX];
-
- port_ring_writer_params.ring = RING_TX;
- port_ring_writer_params.tx_burst_sz = RTE_PORT_IN_BURST_SIZE_MAX;
- port = rte_port_ring_writer_ops.f_create(&port_ring_writer_params, 0);
-
- /* Single packet */
- mbuf[0] = rte_pktmbuf_alloc(pool);
-
- rte_port_ring_writer_ops.f_tx(port, mbuf[0]);
- rte_port_ring_writer_ops.f_flush(port);
- expected_pkts = 1;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -7;
-
- rte_pktmbuf_free(res_mbuf[0]);
-
- /* Multiple packets */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx(port, mbuf[i]);
- }
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- /* TX Bulk */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-1);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -8;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- mbuf[i] = rte_pktmbuf_alloc(pool);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)-3);
- rte_port_ring_writer_ops.f_tx_bulk(port, mbuf, (uint64_t)2);
-
- expected_pkts = RTE_PORT_IN_BURST_SIZE_MAX;
- received_pkts = rte_ring_sc_dequeue_burst(port_ring_writer_params.ring,
- (void **)res_mbuf, port_ring_writer_params.tx_burst_sz, NULL);
-
- if (received_pkts < expected_pkts)
- return -9;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(res_mbuf[i]);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_ports.h b/app/test/test_table_ports.h
deleted file mode 100644
index dfa61193197e741a8ac565a81c2e64e0f0c179a4..0000000000000000000000000000000000000000
--- a/app/test/test_table_ports.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-/* Test prototypes */
-int test_port_ring_reader(void);
-int test_port_ring_writer(void);
-
-/* Extern variables */
-typedef int (*port_test)(void);
-
-extern port_test port_tests[];
-extern unsigned n_port_tests;
diff --git a/app/test/test_table_tables.c b/app/test/test_table_tables.c
deleted file mode 100644
index 920aa555cbd286cca72336619e1bfb8c48de9c7c..0000000000000000000000000000000000000000
--- a/app/test/test_table_tables.c
+++ /dev/null
@@ -1,1058 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef RTE_EXEC_ENV_WINDOWS
-
-#include <string.h>
-#include <rte_byteorder.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_lru.h>
-#include <rte_cycles.h>
-#include "test_table_tables.h"
-#include "test_table.h"
-
-table_test table_tests[] = {
- test_table_stub,
- test_table_array,
- test_table_lpm,
- test_table_lpm_ipv6,
- test_table_hash_lru,
- test_table_hash_ext,
- test_table_hash_cuckoo,
-};
-
-#define PREPARE_PACKET(mbuf, value) do { \
- uint32_t *k32, *signature; \
- uint8_t *key; \
- mbuf = rte_pktmbuf_alloc(pool); \
- signature = RTE_MBUF_METADATA_UINT32_PTR(mbuf, \
- APP_METADATA_OFFSET(0)); \
- key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, \
- APP_METADATA_OFFSET(32)); \
- if (mbuf->priv_size + mbuf->buf_len >= 64) \
- memset(key, 0, 32); \
- k32 = (uint32_t *) key; \
- k32[0] = (value); \
- *signature = pipeline_test_hash(key, NULL, 0, 0); \
-} while (0)
-
-unsigned n_table_tests = RTE_DIM(table_tests);
-
-/* Function prototypes */
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size);
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size);
-
-struct rte_bucket_4_8 {
- /* Cache line 0 */
- uint64_t signature;
- uint64_t lru_list;
- struct rte_bucket_4_8 *next;
- uint64_t next_valid;
- uint64_t key[4];
- /* Cache line 1 */
- uint8_t data[];
-};
-
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
-uint64_t shuffles = 0xfffffffdfffbfff9ULL;
-#else
-uint64_t shuffles = 0x0003000200010000ULL;
-#endif
-
-static int test_lru_update(void)
-{
- struct rte_bucket_4_8 b;
- struct rte_bucket_4_8 *bucket;
- uint32_t i;
- uint64_t pos;
- uint64_t iterations;
- uint64_t j;
- int poss;
-
- printf("---------------------------\n");
- printf("Testing lru_update macro...\n");
- printf("---------------------------\n");
- bucket = &b;
- iterations = 10;
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
- bucket->lru_list = 0xFFFFFFFFFFFFFFFFULL;
-#else
- bucket->lru_list = 0x0000000100020003ULL;
-#endif
- poss = 0;
- for (j = 0; j < iterations; j++)
- for (i = 0; i < 9; i++) {
- uint32_t idx = i >> 1;
- lru_update(bucket, idx);
- pos = lru_pos(bucket);
- poss += pos;
- printf("%s: %d lru_list=%016"PRIx64", upd=%d, "
- "pos=%"PRIx64"\n",
- __func__, i, bucket->lru_list, i>>1, pos);
- }
-
- if (bucket->lru_list != shuffles) {
- printf("%s: ERROR: %d lru_list=%016"PRIx64", expected %016"
- PRIx64"\n",
- __func__, i, bucket->lru_list, shuffles);
- return -1;
- }
- printf("%s: output checksum of results =%d\n",
- __func__, poss);
-#if 0
- if (poss != 126) {
- printf("%s: ERROR output checksum of results =%d expected %d\n",
- __func__, poss, 126);
- return -1;
- }
-#endif
-
- fflush(stdout);
-
- uint64_t sc_start = rte_rdtsc();
- iterations = 100000000;
- poss = 0;
- for (j = 0; j < iterations; j++) {
- for (i = 0; i < 4; i++) {
- lru_update(bucket, i);
- pos |= bucket->lru_list;
- }
- }
- uint64_t sc_end = rte_rdtsc();
-
- printf("%s: output checksum of results =%llu\n",
- __func__, (long long unsigned int)pos);
- printf("%s: start=%016"PRIx64", end=%016"PRIx64"\n",
- __func__, sc_start, sc_end);
- printf("\nlru_update: %lu cycles per loop iteration.\n\n",
- (long unsigned int)((sc_end-sc_start)/(iterations*4)));
-
- return 0;
-}
-
-/* Table tests */
-int
-test_table_stub(void)
-{
- int i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
-
- /* Create */
- table = rte_table_stub_ops.f_create(NULL, 0, 1);
- if (table == NULL)
- return -1;
-
- /* Traffic flow */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- expected_mask = 0;
- rte_table_stub_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -2;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- return 0;
-}
-
-int
-test_table_array(void)
-{
- int status, i;
- uint64_t result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry1, entry2;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_array_params array_params = {
- .n_entries = 7,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_array_ops.f_create(NULL, 0, 1);
- if (table != NULL)
- return -1;
-
- array_params.n_entries = 0;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -2;
-
- array_params.n_entries = 7;
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table != NULL)
- return -3;
-
- array_params.n_entries = 1 << 24;
- array_params.offset = APP_METADATA_OFFSET(1);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -4;
-
- array_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = rte_table_array_ops.f_free(table);
- if (status < 0)
- return -6;
-
- status = rte_table_array_ops.f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- struct rte_table_array_key array_key_1 = {
- .pos = 10,
- };
- struct rte_table_array_key array_key_2 = {
- .pos = 20,
- };
- entry1 = 'A';
- entry2 = 'B';
-
- table = rte_table_array_ops.f_create(&array_params, 0, 1);
- if (table == NULL)
- return -8;
-
- status = rte_table_array_ops.f_add(NULL, (void *) &array_key_1, &entry1,
- &key_found, &entry_ptr);
- if (status == 0)
- return -9;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1, NULL,
- &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_array_ops.f_add(table, (void *) &array_key_1,
- &entry1, &key_found, &entry_ptr);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- status = rte_table_array_ops.f_add(table, (void *) &array_key_2,
- &entry2, &key_found, &entry_ptr);
- if (status != 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0)
- PREPARE_PACKET(mbufs[i], 10);
- else
- PREPARE_PACKET(mbufs[i], 20);
-
- rte_table_array_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0 && *entries[i] != 'A')
- return -13;
- else
- if (i % 2 == 1 && *entries[i] != 'B')
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_array_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 8,
- .flags = 0,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(1)
- };
-
- table = rte_table_lpm_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.offset = APP_METADATA_OFFSET(32);
- lpm_params.entry_unique_size = 0;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.entry_unique_size = entry_size + 1;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_lpm_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_lpm_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- struct rte_table_lpm_key lpm_key;
- lpm_key.ip = 0xadadadad;
-
- table = rte_table_lpm_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -9;
-
- status = rte_table_lpm_ops.f_add(NULL, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_lpm_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status != 0)
- return -15;
-
- /* Delete */
- status = rte_table_lpm_ops.f_delete(NULL, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_lpm_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -17;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 33;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -20;
-
- status = rte_table_lpm_ops.f_delete(table, &lpm_key, &key_found, NULL);
- if (status != 0)
- return -21;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ops.f_add(table, &lpm_key, &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -22;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -23;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ops.f_free(table);
-
- return 0;
-}
-
-int
-test_table_lpm_ipv6(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = sizeof(entry);
-
- /* Initialize params and create tables */
- struct rte_table_lpm_ipv6_params lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 18,
- .entry_unique_size = entry_size,
- .offset = APP_METADATA_OFFSET(32)
- };
-
- table = rte_table_lpm_ipv6_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- lpm_params.name = NULL;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -2;
-
- lpm_params.name = "LPM";
- lpm_params.n_rules = 0;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -3;
-
- lpm_params.n_rules = 1 << 24;
- lpm_params.number_tbl8s = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -4;
-
- lpm_params.number_tbl8s = 1 << 18;
- lpm_params.entry_unique_size = 0;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -5;
-
- lpm_params.entry_unique_size = entry_size + 1;
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table != NULL)
- return -6;
-
- lpm_params.entry_unique_size = entry_size;
- lpm_params.offset = APP_METADATA_OFFSET(32);
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -7;
-
- /* Free */
- status = rte_table_lpm_ipv6_ops.f_free(table);
- if (status < 0)
- return -8;
-
- status = rte_table_lpm_ipv6_ops.f_free(NULL);
- if (status == 0)
- return -9;
-
- /* Add */
- struct rte_table_lpm_ipv6_key lpm_key;
-
- lpm_key.ip.a[0] = 0xad;
- lpm_key.ip.a[1] = 0xad;
- lpm_key.ip.a[2] = 0xad;
- lpm_key.ip.a[3] = 0xad;
-
- table = rte_table_lpm_ipv6_ops.f_create(&lpm_params, 0, entry_size);
- if (table == NULL)
- return -10;
-
- status = rte_table_lpm_ipv6_ops.f_add(NULL, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, NULL, &entry, &key_found,
- &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, NULL, &key_found,
- &entry_ptr);
- if (status == 0)
- return -13;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -14;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -15;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status != 0)
- return -16;
-
- /* Delete */
- status = rte_table_lpm_ipv6_ops.f_delete(NULL, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -17;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, NULL, &key_found, NULL);
- if (status == 0)
- return -18;
-
- lpm_key.depth = 0;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -19;
-
- lpm_key.depth = 129;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status == 0)
- return -20;
-
- lpm_key.depth = 16;
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -21;
-
- status = rte_table_lpm_ipv6_ops.f_delete(table, &lpm_key, &key_found,
- NULL);
- if (status != 0)
- return -22;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_lpm_ipv6_ops.f_add(table, &lpm_key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- return -23;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_lpm_ipv6_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -24;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_lpm_ipv6_ops.f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_lru_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-static int
-test_table_hash_ext_generic(struct rte_table_ops *ops, uint32_t key_size)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- int key_found;
- void *entry_ptr;
-
- /* Initialize params and create tables */
- struct rte_table_hash_params hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 10,
- .n_buckets = 1 << 10,
- .f_hash = pipeline_test_hash,
- .seed = 0,
- };
-
- hash_params.n_keys = 0;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -1;
-
- hash_params.n_keys = 1 << 10;
- hash_params.key_offset = APP_METADATA_OFFSET(1);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -3;
-
- hash_params.key_offset = APP_METADATA_OFFSET(32);
- hash_params.f_hash = NULL;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table != NULL)
- return -4;
-
- hash_params.f_hash = pipeline_test_hash;
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -5;
-
- /* Free */
- status = ops->f_free(table);
- if (status < 0)
- return -6;
-
- status = ops->f_free(NULL);
- if (status == 0)
- return -7;
-
- /* Add */
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) &key;
-
- memset(key, 0, 32);
- k32[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = ops->f_create(&hash_params, 0, 1);
- if (table == NULL)
- return -8;
-
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -9;
-
- /* Delete */
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -10;
-
- status = ops->f_delete(table, &key, &key_found, NULL);
- if (status != 0)
- return -11;
-
- /* Traffic flow */
- entry = 'A';
- status = ops->f_add(table, &key, &entry, &key_found, &entry_ptr);
- if (status < 0)
- return -12;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- ops->f_lookup(table, mbufs, -1, &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -13;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = ops->f_free(table);
-
- return 0;
-}
-
-int
-test_table_hash_lru(void)
-{
- int status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key8_lru_ops,
- 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key16_lru_ops,
- 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_lru_generic(
- &rte_table_hash_key32_lru_ops,
- 32);
- if (status < 0)
- return status;
-
- status = test_lru_update();
- if (status < 0)
- return status;
-
- return 0;
-}
-
-int
-test_table_hash_ext(void)
-{
- int status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key8_ext_ops, 8);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key16_ext_ops, 16);
- if (status < 0)
- return status;
-
- status = test_table_hash_ext_generic(&rte_table_hash_key32_ext_ops, 32);
- if (status < 0)
- return status;
-
- return 0;
-}
-
-
-int
-test_table_hash_cuckoo(void)
-{
- int status, i;
- uint64_t expected_mask = 0, result_mask;
- struct rte_mbuf *mbufs[RTE_PORT_IN_BURST_SIZE_MAX];
- void *table;
- char *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- char entry;
- void *entry_ptr;
- int key_found;
- uint32_t entry_size = 1;
-
- /* Initialize params and create tables */
- struct rte_table_hash_cuckoo_params cuckoo_params = {
- .name = "TABLE",
- .key_size = 32,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 16,
- .n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash_cuckoo,
- .seed = 0,
- };
-
- table = rte_table_hash_cuckoo_ops.f_create(NULL, 0, entry_size);
- if (table != NULL)
- return -1;
-
- cuckoo_params.key_size = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -2;
-
- cuckoo_params.key_size = 32;
- cuckoo_params.n_keys = 0;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -3;
-
- cuckoo_params.n_keys = 1 << 24;
- cuckoo_params.f_hash = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -4;
-
- cuckoo_params.f_hash = pipeline_test_hash_cuckoo;
- cuckoo_params.name = NULL;
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table != NULL)
- return -5;
-
- cuckoo_params.name = "CUCKOO";
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,
- 0, entry_size);
- if (table == NULL)
- return -6;
-
- /* Free */
- status = rte_table_hash_cuckoo_ops.f_free(table);
- if (status < 0)
- return -7;
-
- status = rte_table_hash_cuckoo_ops.f_free(NULL);
- if (status == 0)
- return -8;
-
- /* Add */
- uint8_t key_cuckoo[32];
- uint32_t *kcuckoo = (uint32_t *) &key_cuckoo;
-
- memset(key_cuckoo, 0, 32);
- kcuckoo[0] = rte_be_to_cpu_32(0xadadadad);
-
- table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params, 0, 1);
- if (table == NULL)
- return -9;
-
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(NULL, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status == 0)
- return -10;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, NULL, &entry,
- &key_found, &entry_ptr);
- if (status == 0)
- return -11;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- NULL, &key_found, &entry_ptr);
- if (status == 0)
- return -12;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -13;
-
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found, &entry_ptr);
- if (status != 0)
- return -14;
-
- /* Delete */
- status = rte_table_hash_cuckoo_ops.f_delete(NULL, &key_cuckoo,
- &key_found, NULL);
- if (status == 0)
- return -15;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, NULL,
- &key_found, NULL);
- if (status == 0)
- return -16;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != 0)
- return -17;
-
- status = rte_table_hash_cuckoo_ops.f_delete(table, &key_cuckoo,
- &key_found, NULL);
- if (status != -ENOENT)
- return -18;
-
- /* Traffic flow */
- entry = 'A';
- status = rte_table_hash_cuckoo_ops.f_add(table, &key_cuckoo,
- &entry, &key_found,
- &entry_ptr);
- if (status < 0)
- return -19;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- if (i % 2 == 0) {
- expected_mask |= (uint64_t)1 << i;
- PREPARE_PACKET(mbufs[i], 0xadadadad);
- } else
- PREPARE_PACKET(mbufs[i], 0xadadadab);
-
- rte_table_hash_cuckoo_ops.f_lookup(table, mbufs, -1,
- &result_mask, (void **)entries);
- if (result_mask != expected_mask)
- return -20;
-
- /* Free resources */
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++)
- rte_pktmbuf_free(mbufs[i]);
-
- status = rte_table_hash_cuckoo_ops.f_free(table);
-
- return 0;
-}
-
-#endif /* !RTE_EXEC_ENV_WINDOWS */
diff --git a/app/test/test_table_tables.h b/app/test/test_table_tables.h
deleted file mode 100644
index 530633a0136d26c76c59dac8941a862c46068837..0000000000000000000000000000000000000000
--- a/app/test/test_table_tables.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-/* Test prototypes */
-int test_table_hash_cuckoo(void);
-int test_table_lpm(void);
-int test_table_lpm_ipv6(void);
-int test_table_array(void);
-#ifdef RTE_LIB_ACL
-int test_table_acl(void);
-#endif
-int test_table_hash_unoptimized(void);
-int test_table_hash_lru(void);
-int test_table_hash_ext(void);
-int test_table_stub(void);
-
-/* Extern variables */
-typedef int (*table_test)(void);
-
-extern table_test table_tests[];
-extern unsigned n_table_tests;
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 2/7] app/test-pipeline: remove application
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (9 preceding siblings ...)
2026-07-28 16:35 ` [PATCH v4 1/7] app/test: remove packet framework tests Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 3/7] examples/ip_pipeline: remove example Stephen Hemminger
` (4 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon
The test-pipeline application is built on the legacy pipeline
library API (rte_pipeline_*), which was announced for removal
in the 24.11 release. Remove it before removing the library.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
app/meson.build | 1 -
app/test-pipeline/config.c | 230 ----------
app/test-pipeline/init.c | 273 ------------
app/test-pipeline/main.c | 188 --------
app/test-pipeline/main.h | 132 ------
app/test-pipeline/meson.build | 21 -
app/test-pipeline/pipeline_acl.c | 251 -----------
app/test-pipeline/pipeline_hash.c | 471 ---------------------
app/test-pipeline/pipeline_lpm.c | 175 --------
app/test-pipeline/pipeline_lpm_ipv6.c | 168 --------
app/test-pipeline/pipeline_stub.c | 137 ------
app/test-pipeline/runtime.c | 160 -------
doc/guides/rel_notes/release_26_11.rst | 3 +
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/test_pipeline.rst | 237 -----------
16 files changed, 3 insertions(+), 2447 deletions(-)
delete mode 100644 app/test-pipeline/config.c
delete mode 100644 app/test-pipeline/init.c
delete mode 100644 app/test-pipeline/main.c
delete mode 100644 app/test-pipeline/main.h
delete mode 100644 app/test-pipeline/meson.build
delete mode 100644 app/test-pipeline/pipeline_acl.c
delete mode 100644 app/test-pipeline/pipeline_hash.c
delete mode 100644 app/test-pipeline/pipeline_lpm.c
delete mode 100644 app/test-pipeline/pipeline_lpm_ipv6.c
delete mode 100644 app/test-pipeline/pipeline_stub.c
delete mode 100644 app/test-pipeline/runtime.c
delete mode 100644 doc/guides/sample_app_ug/test_pipeline.rst
diff --git a/MAINTAINERS b/MAINTAINERS
index 77a41b3fcf4110042ef69b7ee53351dd3cadb208..4c06f85706ca9204cab6a655a58b6b7b1457160d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,8 +1739,6 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: app/test-pipeline/
-F: doc/guides/sample_app_ug/test_pipeline.rst
F: examples/ip_pipeline/
F: examples/pipeline/
F: doc/guides/sample_app_ug/ip_pipeline.rst
diff --git a/app/meson.build b/app/meson.build
index 1798db3ae43f685d776533329546e4609d9eb565..4515688471328d2ab315f626c4865c4ba372eaad 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -28,7 +28,6 @@ apps = [
'test-flow-perf',
'test-gpudev',
'test-mldev',
- 'test-pipeline',
'test-pmd',
'test-regex',
'test-sad',
diff --git a/app/test-pipeline/config.c b/app/test-pipeline/config.c
deleted file mode 100644
index daf838948b21075dd108798897cf2c24c30fc471..0000000000000000000000000000000000000000
--- a/app/test-pipeline/config.c
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_string_fns.h>
-
-#include "main.h"
-
-static const char usage[] = "\n";
-
-void
-app_print_usage(void)
-{
- printf(usage);
-}
-
-static int
-app_parse_port_mask(const char *arg)
-{
- char *end = NULL;
- uint64_t port_mask;
- uint32_t i;
-
- if (arg[0] == '\0')
- return -1;
-
- port_mask = strtoul(arg, &end, 16);
- if ((end == NULL) || (*end != '\0'))
- return -2;
-
- if (port_mask == 0)
- return -3;
-
- app.n_ports = 0;
- for (i = 0; i < 64; i++) {
- if ((port_mask & (1LLU << i)) == 0)
- continue;
-
- if (app.n_ports >= APP_MAX_PORTS)
- return -4;
-
- app.ports[app.n_ports] = i;
- app.n_ports++;
- }
-
- if (!rte_is_power_of_2(app.n_ports))
- return -5;
-
- return 0;
-}
-
-struct {
- const char *name;
- uint32_t value;
-} app_args_table[] = {
- {"none", e_APP_PIPELINE_NONE},
- {"stub", e_APP_PIPELINE_STUB},
- {"hash-8-ext", e_APP_PIPELINE_HASH_KEY8_EXT},
- {"hash-8-lru", e_APP_PIPELINE_HASH_KEY8_LRU},
- {"hash-16-ext", e_APP_PIPELINE_HASH_KEY16_EXT},
- {"hash-16-lru", e_APP_PIPELINE_HASH_KEY16_LRU},
- {"hash-32-ext", e_APP_PIPELINE_HASH_KEY32_EXT},
- {"hash-32-lru", e_APP_PIPELINE_HASH_KEY32_LRU},
- {"hash-spec-8-ext", e_APP_PIPELINE_HASH_SPEC_KEY8_EXT},
- {"hash-spec-8-lru", e_APP_PIPELINE_HASH_SPEC_KEY8_LRU},
- {"hash-spec-16-ext", e_APP_PIPELINE_HASH_SPEC_KEY16_EXT},
- {"hash-spec-16-lru", e_APP_PIPELINE_HASH_SPEC_KEY16_LRU},
- {"hash-spec-32-ext", e_APP_PIPELINE_HASH_SPEC_KEY32_EXT},
- {"hash-spec-32-lru", e_APP_PIPELINE_HASH_SPEC_KEY32_LRU},
- {"acl", e_APP_PIPELINE_ACL},
- {"lpm", e_APP_PIPELINE_LPM},
- {"lpm-ipv6", e_APP_PIPELINE_LPM_IPV6},
- {"hash-cuckoo-8", e_APP_PIPELINE_HASH_CUCKOO_KEY8},
- {"hash-cuckoo-16", e_APP_PIPELINE_HASH_CUCKOO_KEY16},
- {"hash-cuckoo-32", e_APP_PIPELINE_HASH_CUCKOO_KEY32},
- {"hash-cuckoo-48", e_APP_PIPELINE_HASH_CUCKOO_KEY48},
- {"hash-cuckoo-64", e_APP_PIPELINE_HASH_CUCKOO_KEY64},
- {"hash-cuckoo-80", e_APP_PIPELINE_HASH_CUCKOO_KEY80},
- {"hash-cuckoo-96", e_APP_PIPELINE_HASH_CUCKOO_KEY96},
- {"hash-cuckoo-112", e_APP_PIPELINE_HASH_CUCKOO_KEY112},
- {"hash-cuckoo-128", e_APP_PIPELINE_HASH_CUCKOO_KEY128},
-};
-
-int
-app_parse_args(int argc, char **argv)
-{
- int opt, ret;
- char **argvopt;
- int option_index;
- char *prgname = argv[0];
- static struct option lgopts[] = {
- {"none", 0, 0, 0},
- {"stub", 0, 0, 0},
- {"hash-8-ext", 0, 0, 0},
- {"hash-8-lru", 0, 0, 0},
- {"hash-16-ext", 0, 0, 0},
- {"hash-16-lru", 0, 0, 0},
- {"hash-32-ext", 0, 0, 0},
- {"hash-32-lru", 0, 0, 0},
- {"hash-spec-8-ext", 0, 0, 0},
- {"hash-spec-8-lru", 0, 0, 0},
- {"hash-spec-16-ext", 0, 0, 0},
- {"hash-spec-16-lru", 0, 0, 0},
- {"hash-spec-32-ext", 0, 0, 0},
- {"hash-spec-32-lru", 0, 0, 0},
- {"acl", 0, 0, 0},
- {"lpm", 0, 0, 0},
- {"lpm-ipv6", 0, 0, 0},
- {"hash-cuckoo-8", 0, 0, 0},
- {"hash-cuckoo-16", 0, 0, 0},
- {"hash-cuckoo-32", 0, 0, 0},
- {"hash-cuckoo-48", 0, 0, 0},
- {"hash-cuckoo-64", 0, 0, 0},
- {"hash-cuckoo-80", 0, 0, 0},
- {"hash-cuckoo-96", 0, 0, 0},
- {"hash-cuckoo-112", 0, 0, 0},
- {"hash-cuckoo-128", 0, 0, 0},
- {NULL, 0, 0, 0}
- };
- uint32_t lcores[3], n_lcores, lcore_id, pipeline_type_provided;
-
- /* EAL args */
- n_lcores = 0;
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
- if (rte_lcore_is_enabled(lcore_id) == 0)
- continue;
-
- if (n_lcores >= 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- lcores[n_lcores] = lcore_id;
- n_lcores++;
- }
-
- if (n_lcores != 3) {
- RTE_LOG(ERR, USER1, "Number of cores must be 3\n");
- app_print_usage();
- return -1;
- }
-
- app.core_rx = lcores[0];
- app.core_worker = lcores[1];
- app.core_tx = lcores[2];
-
- /* Non-EAL args */
- argvopt = argv;
-
- app.pipeline_type = e_APP_PIPELINE_HASH_KEY16_LRU;
- pipeline_type_provided = 0;
-
- while ((opt = getopt_long(argc, argvopt, "p:",
- lgopts, &option_index)) != EOF) {
- switch (opt) {
- case 'p':
- if (app_parse_port_mask(optarg) < 0) {
- app_print_usage();
- return -1;
- }
- break;
-
- case 0: /* long options */
- if (!pipeline_type_provided) {
- uint32_t i;
-
- for (i = 0; i < e_APP_PIPELINES; i++) {
- if (!strcmp(lgopts[option_index].name,
- app_args_table[i].name)) {
- app.pipeline_type =
- app_args_table[i].value;
- pipeline_type_provided = 1;
- break;
- }
- }
-
- break;
- }
-
- app_print_usage();
- return -1;
-
- default:
- return -1;
- }
- }
-
- if (optind >= 0)
- argv[optind - 1] = prgname;
-
- ret = optind - 1;
- optind = 1; /* reset getopt lib */
- return ret;
-}
diff --git a/app/test-pipeline/init.c b/app/test-pipeline/init.c
deleted file mode 100644
index 558f0e428d1c4749a625d30a21acccfad672f61c..0000000000000000000000000000000000000000
--- a/app/test-pipeline/init.c
+++ /dev/null
@@ -1,273 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-struct app_params app = {
- /* Ports*/
- .n_ports = APP_MAX_PORTS,
- .port_rx_ring_size = 128,
- .port_tx_ring_size = 512,
-
- /* Rings */
- .ring_rx_size = 128,
- .ring_tx_size = 128,
-
- /* Buffer pool */
- .pool_buffer_size = 2048 + RTE_PKTMBUF_HEADROOM,
- .pool_size = 32 * 1024,
- .pool_cache_size = 256,
-
- /* Burst sizes */
- .burst_size_rx_read = 64,
- .burst_size_rx_write = 64,
- .burst_size_worker_read = 64,
- .burst_size_worker_write = 64,
- .burst_size_tx_read = 64,
- .burst_size_tx_write = 64,
-};
-
-static struct rte_eth_conf port_conf = {
- .rxmode = {
- .offloads = RTE_ETH_RX_OFFLOAD_CHECKSUM,
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_hf = RTE_ETH_RSS_IP,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
-};
-
-static struct rte_eth_rxconf rx_conf = {
- .rx_thresh = {
- .pthresh = 8,
- .hthresh = 8,
- .wthresh = 4,
- },
- .rx_free_thresh = 64,
- .rx_drop_en = 0,
-};
-
-static struct rte_eth_txconf tx_conf = {
- .tx_thresh = {
- .pthresh = 36,
- .hthresh = 0,
- .wthresh = 0,
- },
- .tx_free_thresh = 0,
- .tx_rs_thresh = 0,
-};
-
-static void
-app_init_mbuf_pools(void)
-{
- /* Init the buffer pool */
- RTE_LOG(INFO, USER1, "Creating the mbuf pool ...\n");
- app.pool = rte_pktmbuf_pool_create("mempool", app.pool_size,
- app.pool_cache_size, 0, app.pool_buffer_size, rte_socket_id());
- if (app.pool == NULL)
- rte_panic("Cannot create mbuf pool\n");
-}
-
-static void
-app_init_rings(void)
-{
- uint32_t i;
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_rx_%u", i);
-
- app.rings_rx[i] = rte_ring_create(
- name,
- app.ring_rx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_rx[i] == NULL)
- rte_panic("Cannot create RX ring %u\n", i);
- }
-
- for (i = 0; i < app.n_ports; i++) {
- char name[32];
-
- snprintf(name, sizeof(name), "app_ring_tx_%u", i);
-
- app.rings_tx[i] = rte_ring_create(
- name,
- app.ring_tx_size,
- rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app.rings_tx[i] == NULL)
- rte_panic("Cannot create TX ring %u\n", i);
- }
-
-}
-
-static void
-app_ports_check_link(void)
-{
- uint32_t all_ports_up, i;
- char link_status_text[RTE_ETH_LINK_MAX_STR_LEN];
- all_ports_up = 1;
-
- for (i = 0; i < app.n_ports; i++) {
- struct rte_eth_link link;
- uint16_t port;
- int ret;
-
- port = app.ports[i];
- memset(&link, 0, sizeof(link));
- ret = rte_eth_link_get_nowait(port, &link);
- if (ret < 0) {
- RTE_LOG(INFO, USER1,
- "Failed to get port %u link status: %s\n",
- port, rte_strerror(-ret));
- all_ports_up = 0;
- continue;
- }
- rte_eth_link_to_str(link_status_text, sizeof(link_status_text),
- &link);
- RTE_LOG(INFO, USER1, "Port %u %s\n",
- port,
- link_status_text);
- if (link.link_status == RTE_ETH_LINK_DOWN)
- all_ports_up = 0;
- }
-
- if (all_ports_up == 0)
- rte_panic("Some NIC ports are DOWN\n");
-}
-
-static void
-app_init_ports(void)
-{
- uint32_t i;
- struct rte_eth_dev_info dev_info;
-
- /* Init NIC ports, then start the ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
- int ret;
- struct rte_eth_conf local_port_conf = port_conf;
-
- port = app.ports[i];
- RTE_LOG(INFO, USER1, "Initializing NIC port %u ...\n", port);
-
- ret = rte_eth_dev_info_get(port, &dev_info);
- if (ret != 0)
- rte_panic("Error during getting device (port %u) info: %s\n",
- port, rte_strerror(-ret));
-
- /* Init port */
- local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
- dev_info.flow_type_rss_offloads;
- if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
- port_conf.rx_adv_conf.rss_conf.rss_hf) {
- printf("Warning:"
- "Port %u modified RSS hash function based on hardware support,"
- "requested:%#"PRIx64" configured:%#"PRIx64"\n",
- port,
- port_conf.rx_adv_conf.rss_conf.rss_hf,
- local_port_conf.rx_adv_conf.rss_conf.rss_hf);
- }
-
- ret = rte_eth_dev_configure(
- port,
- 1,
- 1,
- &local_port_conf);
- if (ret < 0)
- rte_panic("Cannot init NIC port %u (%d)\n", port, ret);
-
- ret = rte_eth_promiscuous_enable(port);
- if (ret != 0)
- rte_panic("Cannot enable promiscuous mode for port %u: %s\n",
- port, rte_strerror(-ret));
-
- /* Init RX queues */
- ret = rte_eth_rx_queue_setup(
- port,
- 0,
- app.port_rx_ring_size,
- rte_eth_dev_socket_id(port),
- &rx_conf,
- app.pool);
- if (ret < 0)
- rte_panic("Cannot init RX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Init TX queues */
- ret = rte_eth_tx_queue_setup(
- port,
- 0,
- app.port_tx_ring_size,
- rte_eth_dev_socket_id(port),
- &tx_conf);
- if (ret < 0)
- rte_panic("Cannot init TX for port %u (%d)\n",
- (uint32_t) port, ret);
-
- /* Start port */
- ret = rte_eth_dev_start(port);
- if (ret < 0)
- rte_panic("Cannot start port %u (%d)\n", port, ret);
- }
-
- app_ports_check_link();
-}
-
-void
-app_init(void)
-{
- app_init_mbuf_pools();
- app_init_rings();
- app_init_ports();
-
- RTE_LOG(INFO, USER1, "Initialization completed\n");
-}
diff --git a/app/test-pipeline/main.c b/app/test-pipeline/main.c
deleted file mode 100644
index e5efafdf28a087cc2d8668b0f478710fe1d66e2f..0000000000000000000000000000000000000000
--- a/app/test-pipeline/main.c
+++ /dev/null
@@ -1,188 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <signal.h>
-#include <errno.h>
-#include <getopt.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_lcore.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-
-#include "main.h"
-
-bool force_quit;
-
-static void
-signal_handler(int signum)
-{
- if (signum == SIGINT || signum == SIGTERM)
- force_quit = true;
-}
-
-int
-main(int argc, char **argv)
-{
- uint32_t lcore;
- uint32_t i;
- int ret;
-
- /* Init EAL */
- ret = rte_eal_init(argc, argv);
- if (ret < 0)
- return -1;
- argc -= ret;
- argv += ret;
-
- force_quit = false;
- signal(SIGINT, signal_handler);
- signal(SIGTERM, signal_handler);
-
- /* Parse application arguments (after the EAL ones) */
- ret = app_parse_args(argc, argv);
- if (ret < 0) {
- app_print_usage();
- return -1;
- }
-
- /* Init */
- app_init();
-
- /* Launch per-lcore init on every lcore */
- rte_eal_mp_remote_launch(app_lcore_main_loop, NULL, CALL_MAIN);
- RTE_LCORE_FOREACH_WORKER(lcore) {
- if (rte_eal_wait_lcore(lcore) < 0)
- return -1;
- }
-
- /* Close ports */
- for (i = 0; i < app.n_ports; i++) {
- uint16_t port;
-
- port = app.ports[i];
- printf("Closing port %d...", port);
- ret = rte_eth_dev_stop(port);
- if (ret != 0)
- printf("rte_eth_dev_stop: err=%d, port=%u\n",
- ret, port);
- rte_eth_dev_close(port);
- printf("Done\n");
- }
-
- /* Clean up the EAL */
- rte_eal_cleanup();
-
- return 0;
-}
-
-int
-app_lcore_main_loop(__rte_unused void *arg)
-{
- unsigned lcore;
-
- lcore = rte_lcore_id();
-
- if (lcore == app.core_rx) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_ACL:
- app_main_loop_rx();
- return 0;
-
- default:
- app_main_loop_rx_metadata();
- return 0;
- }
- }
-
- if (lcore == app.core_worker) {
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_STUB:
- app_main_loop_worker_pipeline_stub();
- return 0;
-
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- /* cases for cuckoo hash table types */
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- app_main_loop_worker_pipeline_hash();
- return 0;
-
- case e_APP_PIPELINE_ACL:
-#ifndef RTE_LIB_ACL
- rte_exit(EXIT_FAILURE, "ACL not present in build\n");
-#else
- app_main_loop_worker_pipeline_acl();
- return 0;
-#endif
-
- case e_APP_PIPELINE_LPM:
- app_main_loop_worker_pipeline_lpm();
- return 0;
-
- case e_APP_PIPELINE_LPM_IPV6:
- app_main_loop_worker_pipeline_lpm_ipv6();
- return 0;
-
- case e_APP_PIPELINE_NONE:
- default:
- app_main_loop_worker();
- return 0;
- }
- }
-
- if (lcore == app.core_tx) {
- app_main_loop_tx();
- return 0;
- }
-
- return 0;
-}
diff --git a/app/test-pipeline/main.h b/app/test-pipeline/main.h
deleted file mode 100644
index ee9c58ac4ca90a810f800043c55a53e8f32ce5f1..0000000000000000000000000000000000000000
--- a/app/test-pipeline/main.h
+++ /dev/null
@@ -1,132 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-#ifndef APP_MBUF_ARRAY_SIZE
-#define APP_MBUF_ARRAY_SIZE 256
-#endif
-
-struct app_mbuf_array {
- struct rte_mbuf *array[APP_MBUF_ARRAY_SIZE];
- uint16_t n_mbufs;
-};
-
-#ifndef APP_MAX_PORTS
-#define APP_MAX_PORTS 4
-#endif
-
-struct __rte_cache_aligned app_params {
- /* CPU cores */
- uint32_t core_rx;
- uint32_t core_worker;
- uint32_t core_tx;
-
- /* Ports*/
- uint32_t ports[APP_MAX_PORTS];
- uint32_t n_ports;
- uint32_t port_rx_ring_size;
- uint32_t port_tx_ring_size;
-
- /* Rings */
- struct rte_ring *rings_rx[APP_MAX_PORTS];
- struct rte_ring *rings_tx[APP_MAX_PORTS];
- uint32_t ring_rx_size;
- uint32_t ring_tx_size;
-
- /* Internal buffers */
- struct app_mbuf_array mbuf_rx;
- struct app_mbuf_array mbuf_tx[APP_MAX_PORTS];
-
- /* Buffer pool */
- struct rte_mempool *pool;
- uint32_t pool_buffer_size;
- uint32_t pool_size;
- uint32_t pool_cache_size;
-
- /* Burst sizes */
- uint32_t burst_size_rx_read;
- uint32_t burst_size_rx_write;
- uint32_t burst_size_worker_read;
- uint32_t burst_size_worker_write;
- uint32_t burst_size_tx_read;
- uint32_t burst_size_tx_write;
-
- /* App behavior */
- uint32_t pipeline_type;
-};
-
-extern struct app_params app;
-
-extern bool force_quit;
-
-int app_parse_args(int argc, char **argv);
-void app_print_usage(void);
-void app_init(void);
-int app_lcore_main_loop(void *arg);
-
-/* Pipeline */
-enum {
- e_APP_PIPELINE_NONE = 0,
- e_APP_PIPELINE_STUB,
-
- e_APP_PIPELINE_HASH_KEY8_EXT,
- e_APP_PIPELINE_HASH_KEY8_LRU,
- e_APP_PIPELINE_HASH_KEY16_EXT,
- e_APP_PIPELINE_HASH_KEY16_LRU,
- e_APP_PIPELINE_HASH_KEY32_EXT,
- e_APP_PIPELINE_HASH_KEY32_LRU,
-
- e_APP_PIPELINE_HASH_SPEC_KEY8_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY8_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY16_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY16_LRU,
- e_APP_PIPELINE_HASH_SPEC_KEY32_EXT,
- e_APP_PIPELINE_HASH_SPEC_KEY32_LRU,
-
- e_APP_PIPELINE_ACL,
- e_APP_PIPELINE_LPM,
- e_APP_PIPELINE_LPM_IPV6,
-
- e_APP_PIPELINE_HASH_CUCKOO_KEY8,
- e_APP_PIPELINE_HASH_CUCKOO_KEY16,
- e_APP_PIPELINE_HASH_CUCKOO_KEY32,
- e_APP_PIPELINE_HASH_CUCKOO_KEY48,
- e_APP_PIPELINE_HASH_CUCKOO_KEY64,
- e_APP_PIPELINE_HASH_CUCKOO_KEY80,
- e_APP_PIPELINE_HASH_CUCKOO_KEY96,
- e_APP_PIPELINE_HASH_CUCKOO_KEY112,
- e_APP_PIPELINE_HASH_CUCKOO_KEY128,
- e_APP_PIPELINES
-};
-
-void app_main_loop_rx(void);
-void app_main_loop_rx_metadata(void);
-uint64_t test_hash(void *key,
- void *key_mask,
- uint32_t key_size,
- uint64_t seed);
-
-uint32_t test_hash_cuckoo(const void *key,
- uint32_t key_size,
- uint32_t seed);
-
-void app_main_loop_worker(void);
-void app_main_loop_worker_pipeline_stub(void);
-void app_main_loop_worker_pipeline_hash(void);
-void app_main_loop_worker_pipeline_acl(void);
-void app_main_loop_worker_pipeline_lpm(void);
-void app_main_loop_worker_pipeline_lpm_ipv6(void);
-
-void app_main_loop_tx(void);
-
-#define APP_FLUSH 0
-#ifndef APP_FLUSH
-#define APP_FLUSH 0x3FF
-#endif
-
-#define APP_METADATA_OFFSET(offset) (sizeof(struct rte_mbuf) + (offset))
-
-#endif /* _MAIN_H_ */
diff --git a/app/test-pipeline/meson.build b/app/test-pipeline/meson.build
deleted file mode 100644
index 3add6b637bdb5ec81013140a2011b95b22b7eaaf..0000000000000000000000000000000000000000
--- a/app/test-pipeline/meson.build
+++ /dev/null
@@ -1,21 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2019 Intel Corporation
-
-if is_windows
- build = false
- reason = 'not supported on Windows'
- subdir_done()
-endif
-
-sources = files(
- 'config.c',
- 'init.c',
- 'main.c',
- 'pipeline_acl.c',
- 'pipeline_hash.c',
- 'pipeline_lpm.c',
- 'pipeline_lpm_ipv6.c',
- 'pipeline_stub.c',
- 'runtime.c',
-)
-deps += ['pipeline', 'pci']
diff --git a/app/test-pipeline/pipeline_acl.c b/app/test-pipeline/pipeline_acl.c
deleted file mode 100644
index 9eb4053e23a0b7ebb38b9dfa19de15f4aaa12662..0000000000000000000000000000000000000000
--- a/app/test-pipeline/pipeline_acl.c
+++ /dev/null
@@ -1,251 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_acl.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-enum {
- PROTO_FIELD_IPV4,
- SRC_FIELD_IPV4,
- DST_FIELD_IPV4,
- SRCP_FIELD_IPV4,
- DSTP_FIELD_IPV4,
- NUM_FIELDS_IPV4
-};
-
-/*
- * Here we define the 'shape' of the data we're searching for,
- * by defining the meta-data of the ACL rules.
- * in this case, we're defining 5 tuples. IP addresses, ports,
- * and protocol.
- */
-struct rte_acl_field_def ipv4_field_formats[NUM_FIELDS_IPV4] = {
- {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = PROTO_FIELD_IPV4,
- .input_index = PROTO_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = SRC_FIELD_IPV4,
- .input_index = SRC_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, src_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = DST_FIELD_IPV4,
- .input_index = DST_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- offsetof(struct rte_ipv4_hdr, dst_addr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = SRCP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr),
- },
- {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = DSTP_FIELD_IPV4,
- .input_index = SRCP_FIELD_IPV4,
- .offset = sizeof(struct rte_ether_hdr) +
- sizeof(struct rte_ipv4_hdr) + sizeof(uint16_t),
- },
-};
-
-
-
-void
-app_main_loop_worker_pipeline_acl(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with ACL table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_acl_params table_acl_params = {
- .name = "test", /* unique identifier for acl contexts */
- .n_rules = 1 << 5,
- .n_rule_fields = DIM(ipv4_field_formats),
- };
-
- /* Copy in the rule meta-data defined above into the params */
- memcpy(table_acl_params.field_format, ipv4_field_formats,
- sizeof(ipv4_field_formats));
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_acl_ops,
- .arg_create = &table_acl_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the ACL table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry table_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_table_acl_rule_add_params rule_params;
- struct rte_pipeline_table_entry *entry_ptr;
- int key_found, ret;
-
- memset(&rule_params, 0, sizeof(rule_params));
-
- /* Set the rule values */
- rule_params.field_value[SRC_FIELD_IPV4].value.u32 = 0;
- rule_params.field_value[SRC_FIELD_IPV4].mask_range.u32 = 0;
- rule_params.field_value[DST_FIELD_IPV4].value.u32 =
- i << (24 - rte_popcount32(app.n_ports - 1));
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32 =
- 8 + rte_popcount32(app.n_ports - 1);
- rule_params.field_value[SRCP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[SRCP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[DSTP_FIELD_IPV4].value.u16 = 0;
- rule_params.field_value[DSTP_FIELD_IPV4].mask_range.u16 =
- UINT16_MAX;
- rule_params.field_value[PROTO_FIELD_IPV4].value.u8 = 0;
- rule_params.field_value[PROTO_FIELD_IPV4].mask_range.u8 = 0;
-
- rule_params.priority = 0;
-
- uint32_t dst_addr = rule_params.field_value[DST_FIELD_IPV4].
- value.u32;
- uint32_t dst_mask =
- rule_params.field_value[DST_FIELD_IPV4].mask_range.u32;
-
- printf("Adding rule to ACL table (IPv4 destination = "
- "%u.%u.%u.%u/%u => port out = %u)\n",
- (dst_addr & 0xFF000000) >> 24,
- (dst_addr & 0x00FF0000) >> 16,
- (dst_addr & 0x0000FF00) >> 8,
- dst_addr & 0x000000FF,
- dst_mask,
- table_entry.port_id);
-
- /* For ACL, add needs an rte_table_acl_rule_add_params struct */
- ret = rte_pipeline_table_entry_add(p, table_id, &rule_params,
- &table_entry, &key_found, &entry_ptr);
- if (ret < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, ret);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_hash.c b/app/test-pipeline/pipeline_hash.c
deleted file mode 100644
index 194e5c5dcc53e5d83f8f70fc8325e4820c8a2c66..0000000000000000000000000000000000000000
--- a/app/test-pipeline/pipeline_hash.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_hash.h>
-#include <rte_hash.h>
-#include <rte_table_hash_cuckoo.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-static void
-translate_options(uint32_t *special, uint32_t *ext, uint32_t *key_size)
-{
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- *special = 0; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- *special = 0; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- *special = 0; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- *special = 0; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- *special = 1; *ext = 1; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- *special = 1; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- *special = 1; *ext = 1; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- *special = 1; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- *special = 1; *ext = 1; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- *special = 1; *ext = 0; *key_size = 32; return;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- *special = 0; *ext = 0; *key_size = 8; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- *special = 0; *ext = 0; *key_size = 16; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- *special = 0; *ext = 0; *key_size = 32; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- *special = 0; *ext = 0; *key_size = 48; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- *special = 0; *ext = 0; *key_size = 64; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- *special = 0; *ext = 0; *key_size = 80; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- *special = 0; *ext = 0; *key_size = 96; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- *special = 0; *ext = 0; *key_size = 112; return;
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- *special = 0; *ext = 0; *key_size = 128; return;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-}
-void
-app_main_loop_worker_pipeline_hash(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
- uint32_t special, ext, key_size;
-
- translate_options(&special, &ext, &key_size);
-
- RTE_LOG(INFO, USER1, "Core %u is doing work "
- "(pipeline with hash table, %s, %s, %d-byte key)\n",
- rte_lcore_id(),
- special ? "specialized" : "non-specialized",
- ext ? "extendible bucket" : "LRU",
- key_size);
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- struct rte_table_hash_params table_hash_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash,
- .seed = 0,
- };
-
- struct rte_table_hash_cuckoo_params table_hash_cuckoo_params = {
- .name = "TABLE",
- .key_size = key_size,
- .key_offset = APP_METADATA_OFFSET(32),
- .key_mask = NULL,
- .n_keys = 1 << 24,
- .n_buckets = 1 << 22,
- .f_hash = test_hash_cuckoo,
- .seed = 0,
- };
-
- /* Table configuration */
- switch (app.pipeline_type) {
- case e_APP_PIPELINE_HASH_KEY8_EXT:
- case e_APP_PIPELINE_HASH_KEY16_EXT:
- case e_APP_PIPELINE_HASH_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_KEY8_LRU:
- case e_APP_PIPELINE_HASH_KEY16_LRU:
- case e_APP_PIPELINE_HASH_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY8_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table)\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY16_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key16_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_EXT:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_ext_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
-
- case e_APP_PIPELINE_HASH_SPEC_KEY32_LRU:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key32_lru_ops,
- .arg_create = &table_hash_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- case e_APP_PIPELINE_HASH_CUCKOO_KEY8:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY16:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY32:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY48:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY64:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY80:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY96:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY112:
- case e_APP_PIPELINE_HASH_CUCKOO_KEY128:
- {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_cuckoo_ops,
- .arg_create = &table_hash_cuckoo_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the hash table\n");
- }
- break;
-
- default:
- rte_panic("Invalid hash table type or key size\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < (1 << 24); i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
- struct rte_pipeline_table_entry *entry_ptr;
- uint8_t key[32];
- uint32_t *k32 = (uint32_t *) key;
- int key_found, status;
-
- memset(key, 0, sizeof(key));
- k32[0] = rte_be_to_cpu_32(i);
-
- status = rte_pipeline_table_entry_add(p, table_id, key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
-
-uint64_t test_hash(
- void *key,
- __rte_unused void *key_mask,
- __rte_unused uint32_t key_size,
- __rte_unused uint64_t seed)
-{
- uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint64_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-uint32_t test_hash_cuckoo(
- const void *key,
- __rte_unused uint32_t key_size,
- __rte_unused uint32_t seed)
-{
- const uint32_t *k32 = key;
- uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
- uint32_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
-
- return signature;
-}
-
-void
-app_main_loop_rx_metadata(void) {
- uint32_t i, j;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX (with meta-data)\n",
- rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- for (j = 0; j < n_mbufs; j++) {
- struct rte_mbuf *m;
- uint8_t *m_data, *key;
- struct rte_ipv4_hdr *ip_hdr;
- struct rte_ipv6_hdr *ipv6_hdr;
- uint32_t ip_dst;
- uint32_t *signature, *k32;
-
- m = app.mbuf_rx.array[j];
- m_data = rte_pktmbuf_mtod(m, uint8_t *);
- signature = RTE_MBUF_METADATA_UINT32_PTR(m,
- APP_METADATA_OFFSET(0));
- key = RTE_MBUF_METADATA_UINT8_PTR(m,
- APP_METADATA_OFFSET(32));
-
- if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
- ip_hdr = (struct rte_ipv4_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
- ip_dst = ip_hdr->dst_addr;
-
- k32 = (uint32_t *) key;
- k32[0] = ip_dst & 0xFFFFFF00;
- } else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
- ipv6_hdr = (struct rte_ipv6_hdr *)
- &m_data[sizeof(struct rte_ether_hdr)];
-
- memcpy(key, &ipv6_hdr->dst_addr, 16);
- } else
- continue;
-
- *signature = test_hash(key, NULL, 0, 0);
- }
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
diff --git a/app/test-pipeline/pipeline_lpm.c b/app/test-pipeline/pipeline_lpm.c
deleted file mode 100644
index 8a59bd00420685d5c577f9b9fa39fe4cbd4f31ca..0000000000000000000000000000000000000000
--- a/app/test-pipeline/pipeline_lpm.c
+++ /dev/null
@@ -1,175 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-#ifndef PIPELINE_LPM_TABLE_NUMBER_TABLE8s
-#define PIPELINE_LPM_TABLE_NUMBER_TABLE8s 256
-#endif
-
-void
-app_main_loop_worker_pipeline_lpm(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with "
- "LPM table)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_params table_lpm_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = PIPELINE_LPM_TABLE_NUMBER_TABLE8s,
- .flags = 0,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ops,
- .arg_create = &table_lpm_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_key key = {
- .ip = i << (24 - rte_popcount32(app.n_ports - 1)),
- .depth = 8 + rte_popcount32(app.n_ports - 1),
- };
-
- struct rte_pipeline_table_entry *entry_ptr;
-
- int key_found, status;
-
- printf("Adding rule to LPM table (IPv4 destination = %"
- PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 "/%" PRIu8
- " => port out = %" PRIu32 ")\n",
- (key.ip & 0xFF000000) >> 24,
- (key.ip & 0x00FF0000) >> 16,
- (key.ip & 0x0000FF00) >> 8,
- key.ip & 0x000000FF,
- key.depth,
- i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_lpm_ipv6.c b/app/test-pipeline/pipeline_lpm_ipv6.c
deleted file mode 100644
index 6558e887c85929d859cc94289c4e63f46d5e1c12..0000000000000000000000000000000000000000
--- a/app/test-pipeline/pipeline_lpm_ipv6.c
+++ /dev/null
@@ -1,168 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-
-#include <rte_port_ring.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_lpm_ipv6(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id;
- uint32_t i;
-
- RTE_LOG(INFO, USER1,
- "Core %u is doing work (pipeline with IPv6 LPM table)\n",
- rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- {
- struct rte_table_lpm_ipv6_params table_lpm_ipv6_params = {
- .name = "LPM",
- .n_rules = 1 << 24,
- .number_tbl8s = 1 << 21,
- .entry_unique_size =
- sizeof(struct rte_pipeline_table_entry),
- .offset = APP_METADATA_OFFSET(32),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ipv6_ops,
- .arg_create = &table_lpm_ipv6_params,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id))
- rte_panic("Unable to configure the IPv6 LPM table\n");
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i & (app.n_ports - 1)]},
- };
-
- struct rte_table_lpm_ipv6_key key;
- struct rte_pipeline_table_entry *entry_ptr;
- uint32_t ip;
- int key_found, status;
-
- key.depth = 8 + rte_popcount32(app.n_ports - 1);
-
- ip = rte_bswap32(i << (24 -
- rte_popcount32(app.n_ports - 1)));
- memcpy(&key.ip, &ip, sizeof(uint32_t));
-
- printf("Adding rule to IPv6 LPM table (IPv6 destination = "
- RTE_IPV6_ADDR_FMT "/%u => port out = %u)\n",
- RTE_IPV6_ADDR_SPLIT(&key.ip),
- key.depth, i);
-
- status = rte_pipeline_table_entry_add(p, table_id, &key, &entry,
- &key_found, &entry_ptr);
- if (status < 0)
- rte_panic("Unable to add entry to table %u (%d)\n",
- table_id, status);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/pipeline_stub.c b/app/test-pipeline/pipeline_stub.c
deleted file mode 100644
index 48a638aad76ebd2a4fd4c2b2350764a43753bb80..0000000000000000000000000000000000000000
--- a/app/test-pipeline/pipeline_stub.c
+++ /dev/null
@@ -1,137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#include <rte_log.h>
-#include <rte_port_ring.h>
-#include <rte_table_stub.h>
-#include <rte_pipeline.h>
-
-#include "main.h"
-
-void
-app_main_loop_worker_pipeline_stub(void) {
- struct rte_pipeline_params pipeline_params = {
- .name = "pipeline",
- .socket_id = rte_socket_id(),
- };
-
- struct rte_pipeline *p;
- uint32_t port_in_id[APP_MAX_PORTS];
- uint32_t port_out_id[APP_MAX_PORTS];
- uint32_t table_id[APP_MAX_PORTS];
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (pipeline with stub "
- "tables)\n", rte_lcore_id());
-
- /* Pipeline configuration */
- p = rte_pipeline_create(&pipeline_params);
- if (p == NULL)
- rte_panic("Unable to configure the pipeline\n");
-
- /* Input port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_reader_params port_ring_params = {
- .ring = app.rings_rx[i],
- };
-
- struct rte_pipeline_port_in_params port_params = {
- .ops = &rte_port_ring_reader_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = app.burst_size_worker_read,
- };
-
- if (rte_pipeline_port_in_create(p, &port_params,
- &port_in_id[i]))
- rte_panic("Unable to configure input port for "
- "ring %d\n", i);
- }
-
- /* Output port configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_port_ring_writer_params port_ring_params = {
- .ring = app.rings_tx[i],
- .tx_burst_sz = app.burst_size_worker_write,
- };
-
- struct rte_pipeline_port_out_params port_params = {
- .ops = &rte_port_ring_writer_ops,
- .arg_create = (void *) &port_ring_params,
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- if (rte_pipeline_port_out_create(p, &port_params,
- &port_out_id[i]))
- rte_panic("Unable to configure output port for "
- "ring %d\n", i);
- }
-
- /* Table configuration */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_stub_ops,
- .arg_create = NULL,
- .f_action_hit = NULL,
- .f_action_miss = NULL,
- .arg_ah = NULL,
- .action_data_size = 0,
- };
-
- if (rte_pipeline_table_create(p, &table_params, &table_id[i]))
- rte_panic("Unable to configure table %u\n", i);
- }
-
- /* Interconnecting ports and tables */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_connect_to_table(p, port_in_id[i],
- table_id[i]))
- rte_panic("Unable to connect input port %u to "
- "table %u\n", port_in_id[i], table_id[i]);
-
- /* Add entries to tables */
- for (i = 0; i < app.n_ports; i++) {
- struct rte_pipeline_table_entry entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = port_out_id[i ^ 1]},
- };
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- if (rte_pipeline_table_default_entry_add(p, table_id[i], &entry,
- &default_entry_ptr))
- rte_panic("Unable to add default entry to table %u\n",
- table_id[i]);
- }
-
- /* Enable input ports */
- for (i = 0; i < app.n_ports; i++)
- if (rte_pipeline_port_in_enable(p, port_in_id[i]))
- rte_panic("Unable to enable input port %u\n",
- port_in_id[i]);
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p) < 0)
- rte_panic("Pipeline consistency check failed\n");
-
- /* Run-time */
-#if APP_FLUSH == 0
- while (!force_quit)
- rte_pipeline_run(p);
-#else
- i = 0;
- while (!force_quit) {
- rte_pipeline_run(p);
-
- if ((i & APP_FLUSH) == 0)
- rte_pipeline_flush(p);
- i++;
- }
-#endif
-}
diff --git a/app/test-pipeline/runtime.c b/app/test-pipeline/runtime.c
deleted file mode 100644
index 752f78337031d4f7ddc94d63047b6d5de56a00cb..0000000000000000000000000000000000000000
--- a/app/test-pipeline/runtime.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <sys/types.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <getopt.h>
-
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memcpy.h>
-#include <rte_eal.h>
-#include <rte_per_lcore.h>
-#include <rte_launch.h>
-#include <rte_cycles.h>
-#include <rte_prefetch.h>
-#include <rte_branch_prediction.h>
-#include <rte_interrupts.h>
-#include <rte_pci.h>
-#include <rte_random.h>
-#include <rte_debug.h>
-#include <rte_ether.h>
-#include <rte_ethdev.h>
-#include <rte_ring.h>
-#include <rte_mempool.h>
-#include <rte_mbuf.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_lpm.h>
-#include <rte_lpm6.h>
-#include <rte_malloc.h>
-
-#include "main.h"
-
-void
-app_main_loop_rx(void) {
- uint32_t i;
- int ret;
-
- RTE_LOG(INFO, USER1, "Core %u is doing RX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs;
-
- n_mbufs = rte_eth_rx_burst(
- app.ports[i],
- 0,
- app.mbuf_rx.array,
- app.burst_size_rx_read);
-
- if (n_mbufs == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_rx[i],
- (void **) app.mbuf_rx.array,
- n_mbufs, NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_worker(void) {
- struct app_mbuf_array *worker_mbuf;
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing work (no pipeline)\n",
- rte_lcore_id());
-
- worker_mbuf = rte_malloc_socket(NULL, sizeof(struct app_mbuf_array),
- RTE_CACHE_LINE_SIZE, rte_socket_id());
- if (worker_mbuf == NULL)
- rte_panic("Worker thread: cannot allocate buffer space\n");
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- int ret;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_rx[i],
- (void **) worker_mbuf->array,
- app.burst_size_worker_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- do {
- ret = rte_ring_sp_enqueue_bulk(
- app.rings_tx[i ^ 1],
- (void **) worker_mbuf->array,
- app.burst_size_worker_write,
- NULL);
- } while (ret == 0 && !force_quit);
- }
- }
-}
-
-void
-app_main_loop_tx(void) {
- uint32_t i;
-
- RTE_LOG(INFO, USER1, "Core %u is doing TX\n", rte_lcore_id());
-
- while (!force_quit) {
- for (i = 0; i < app.n_ports; i++) {
- uint16_t n_mbufs, n_pkts;
- int ret;
-
- n_mbufs = app.mbuf_tx[i].n_mbufs;
-
- ret = rte_ring_sc_dequeue_bulk(
- app.rings_tx[i],
- (void **) &app.mbuf_tx[i].array[n_mbufs],
- app.burst_size_tx_read,
- NULL);
-
- if (ret == 0)
- continue;
-
- n_mbufs += app.burst_size_tx_read;
-
- if (n_mbufs < app.burst_size_tx_write) {
- app.mbuf_tx[i].n_mbufs = n_mbufs;
- continue;
- }
-
- n_pkts = rte_eth_tx_burst(
- app.ports[i],
- 0,
- app.mbuf_tx[i].array,
- n_mbufs);
-
- if (n_pkts < n_mbufs) {
- uint16_t k;
-
- for (k = n_pkts; k < n_mbufs; k++) {
- struct rte_mbuf *pkt_to_free;
-
- pkt_to_free = app.mbuf_tx[i].array[k];
- rte_pktmbuf_free(pkt_to_free);
- }
- }
-
- app.mbuf_tx[i].n_mbufs = 0;
- }
- }
-}
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index c8cc86295da2d08b56e1464ca4a3122bbb599068..6ad0cf6eeca19f32429e60c2637b06274d43754a 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -77,6 +77,9 @@ Removed Items
``rte_rib6_is_equal``
* table: ``RTE_LPM_IPV6_ADDR_SIZE``
+* Removed the ``dpdk-test-pipeline`` application, which was based on
+ the legacy pipeline library API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index f12623bb669b75c39117f65dad781fe00e4534e9..c8b50b801c5ca317c8107b182a4633a4918fb199 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -45,7 +45,6 @@ Sample Applications User Guides
vhost_crypto
vdpa
ip_pipeline
- test_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/test_pipeline.rst b/doc/guides/sample_app_ug/test_pipeline.rst
deleted file mode 100644
index e53d77a170f1155743b8cb082cfd129848a0a4fa..0000000000000000000000000000000000000000
--- a/doc/guides/sample_app_ug/test_pipeline.rst
+++ /dev/null
@@ -1,237 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2010-2014 Intel Corporation.
-
-Test Pipeline Application
-=========================
-
-The Test Pipeline application illustrates the use of the DPDK Packet Framework tool suite.
-Its purpose is to demonstrate the performance of single-table DPDK pipelines.
-
-Overview
---------
-
-The application uses three CPU cores:
-
-* Core A ("RX core") receives traffic from the NIC ports and feeds core B with traffic through SW queues.
-
-* Core B ("Pipeline core") implements a single-table DPDK pipeline
- whose type is selectable through specific command line parameter.
- Core B receives traffic from core A through software queues,
- processes it according to the actions configured in the table entries that
- are hit by the input packets and feeds it to core C through another set of software queues.
-
-* Core C ("TX core") receives traffic from core B through software queues and sends it to the NIC ports for transmission.
-
-.. figure:: img/test_pipeline_app.*
-
- Test Pipeline Application
-
-Compiling the Application
--------------------------
-To compile the sample application see :doc:`compiling`
-
-The application is located in the ``dpdk/<build_dir>/app`` directory.
-
-
-Running the Application
------------------------
-
-Application Command Line
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-The application execution command line is:
-
-.. code-block:: console
-
- ./dpdk-test-pipeline [EAL options] -- -p PORTMASK --TABLE_TYPE
-
-The ``-l/--lcores`` EAL CPU corelist option has to contain exactly 3 CPU cores.
-The first CPU core in the core mask is assigned for core A, the second for core B and the third for core C.
-
-The PORTMASK parameter must contain 2 or 4 ports.
-
-Table Types and Behavior
-~~~~~~~~~~~~~~~~~~~~~~~~
-
-:numref:`test_pipeline_table_1` describes the table types used and how they are populated.
-
-The hash tables are pre-populated with 16 million keys.
-For hash tables, the following parameters can be selected:
-
-* **Configurable key size implementation or fixed (specialized) key size implementation (e.g. hash-8-ext or hash-spec-8-ext).**
- The key size specialized implementations are expected to provide better performance for 8-byte and 16-byte key sizes,
- while the key-size-non-specialized implementation is expected to provide better performance for larger key sizes;
-
-* **Key size (e.g. hash-spec-8-ext or hash-spec-16-ext).**
- The available options are 8, 16 and 32 bytes;
-
-* **Table type (e.g. hash-spec-16-ext or hash-spec-16-lru).**
- The available options are ext (extendable bucket) or lru (least recently used).
-
-.. _test_pipeline_table_1:
-
-.. table:: Table Types
-
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | **#** | **TABLE_TYPE** | **Description of Core B Table** | **Pre-added Table Entries** |
- | | | | |
- +=======+========================+==========================================================+=======================================================+
- | 1 | none | Core B is not implementing a DPDK pipeline. | N/A |
- | | | Core B is implementing a pass-through from its input set | |
- | | | of software queues to its output set of software queues. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 2 | stub | Stub table. Core B is implementing the same pass-through | N/A |
- | | | functionality as described for the "none" option by | |
- | | | using the DPDK Packet Framework by using one | |
- | | | stub table for each input NIC port. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 3 | hash-[spec]-8-lru | LRU hash table with 8-byte key size and 16 million | 16 million entries are successfully added to the |
- | | | entries. | hash table with the following key format: |
- | | | | |
- | | | | [4-byte index, 4 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Sendto output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | core B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 4 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 4 | hash-[spec]-8-ext | Extendable bucket hash table with 8-byte key size | Same as hash-[spec]-8-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 5 | hash-[spec]-16-lru | LRU hash table with 16-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 12 bytes of 0] |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for core |
- | | | | B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 12 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 6 | hash-[spec]-16-ext | Extendable bucket hash table with 16-byte key size | Same as hash-[spec]-16-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 7 | hash-[spec]-32-lru | LRU hash table with 32-byte key size and 16 million | 16 million entries are successfully added to the hash |
- | | | entries. | table with the following key format: |
- | | | | |
- | | | | [4-byte index, 28 bytes of 0]. |
- | | | | |
- | | | | The action configured for all table entries is |
- | | | | "Send to output port", with the output port index |
- | | | | uniformly distributed for the range of output ports. |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is creating the following lookup |
- | | | | key and storing it into the packet meta data for |
- | | | | Lpmcore B to use for table lookup: |
- | | | | |
- | | | | [destination IPv4 address, 28 bytes of 0] |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 8 | hash-[spec]-32-ext | Extendable bucket hash table with 32-byte key size | Same as hash-[spec]-32-lru table entries, above. |
- | | | and 16 million entries. | |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 9 | lpm | Longest Prefix Match (LPM) IPv4 table. | In the case of two ports, two routes |
- | | | | are added to the table: |
- | | | | |
- | | | | [0.0.0.0/9 => send to output port 0] |
- | | | | |
- | | | | [0.128.0.0/9 => send to output port 1] |
- | | | | |
- | | | | In case of four ports, four entries are added to the |
- | | | | table: |
- | | | | |
- | | | | [0.0.0.0/10 => send to output port 0] |
- | | | | |
- | | | | [0.64.0.0/10 => send to output port 1] |
- | | | | |
- | | | | [0.128.0.0/10 => send to output port 2] |
- | | | | |
- | | | | [0.192.0.0/10 => send to output port 3] |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- | | | | At run time, core A is storing the IPv4 destination |
- | | | | within the packet meta data to be later used by core |
- | | | | B as the lookup key. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
- | 10 | acl | Access Control List (ACL) table | In the case of two ports, two ACL rules are added to |
- | | | | the table: |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.0.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0] |
- | | | | |
- | | | | |
- | | | | [priority = 0 (highest), |
- | | | | |
- | | | | IPv4 source = ANY, |
- | | | | |
- | | | | IPv4 destination = 0.128.0.0/9, |
- | | | | |
- | | | | L4 protocol = ANY, |
- | | | | |
- | | | | TCP source port = ANY, |
- | | | | |
- | | | | TCP destination port = ANY |
- | | | | |
- | | | | => send to output port 0]. |
- | | | | |
- | | | | |
- | | | | The default table rule (used in the case of a lookup |
- | | | | miss) is to drop the packet. |
- | | | | |
- +-------+------------------------+----------------------------------------------------------+-------------------------------------------------------+
-
-Input Traffic
-~~~~~~~~~~~~~
-
-Regardless of the table type used for the core B pipeline,
-the same input traffic can be used to hit all table entries with uniform distribution,
-which results in uniform distribution of packets sent out on the set of output NIC ports.
-The profile for input traffic is TCP/IPv4 packets with:
-
-* destination IP address as A.B.C.D with A fixed to 0 and B, C,D random
-
-* source IP address fixed to 0.0.0.0
-
-* destination TCP port fixed to 0
-
-* source TCP port fixed to 0
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 3/7] examples/ip_pipeline: remove example
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (10 preceding siblings ...)
2026-07-28 16:35 ` [PATCH v4 2/7] app/test-pipeline: remove application Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 4/7] pipeline: remove legacy API Stephen Hemminger
` (3 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Thomas Monjalon, Cristian Dumitrescu
The ip_pipeline example is built on the legacy pipeline library
API (rte_pipeline_*) and the associated port and table action
APIs, which were announced for removal in the 24.11 release.
The pipeline example covers the SWX pipeline API.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
MAINTAINERS | 2 -
doc/guides/nics/softnic.rst | 3 +-
doc/guides/rel_notes/release_26_11.rst | 4 +
doc/guides/sample_app_ug/index.rst | 1 -
doc/guides/sample_app_ug/ip_pipeline.rst | 531 --
examples/ip_pipeline/Makefile | 60 -
examples/ip_pipeline/action.c | 391 -
examples/ip_pipeline/action.h | 78 -
examples/ip_pipeline/cli.c | 6791 -----------------
examples/ip_pipeline/cli.h | 18 -
examples/ip_pipeline/common.h | 12 -
examples/ip_pipeline/conn.c | 330 -
examples/ip_pipeline/conn.h | 47 -
examples/ip_pipeline/cryptodev.c | 160 -
examples/ip_pipeline/cryptodev.h | 46 -
examples/ip_pipeline/examples/firewall.cli | 59 -
examples/ip_pipeline/examples/flow.cli | 60 -
examples/ip_pipeline/examples/flow_crypto.cli | 57 -
examples/ip_pipeline/examples/l2fwd.cli | 51 -
examples/ip_pipeline/examples/route.cli | 60 -
examples/ip_pipeline/examples/route_ecmp.cli | 57 -
| 112 -
examples/ip_pipeline/examples/tap.cli | 66 -
examples/ip_pipeline/link.c | 270 -
examples/ip_pipeline/link.h | 66 -
examples/ip_pipeline/main.c | 260 -
examples/ip_pipeline/mempool.c | 82 -
examples/ip_pipeline/mempool.h | 40 -
examples/ip_pipeline/meson.build | 30 -
examples/ip_pipeline/parser.c | 506 --
examples/ip_pipeline/parser.h | 56 -
examples/ip_pipeline/pipeline.c | 1078 ---
examples/ip_pipeline/pipeline.h | 425 --
examples/ip_pipeline/swq.c | 76 -
examples/ip_pipeline/swq.h | 37 -
examples/ip_pipeline/tap.c | 102 -
examples/ip_pipeline/tap.h | 29 -
examples/ip_pipeline/thread.c | 3137 --------
examples/ip_pipeline/thread.h | 24 -
examples/ip_pipeline/tmgr.c | 248 -
examples/ip_pipeline/tmgr.h | 74 -
examples/meson.build | 1 -
42 files changed, 5 insertions(+), 15532 deletions(-)
delete mode 100644 doc/guides/sample_app_ug/ip_pipeline.rst
delete mode 100644 examples/ip_pipeline/Makefile
delete mode 100644 examples/ip_pipeline/action.c
delete mode 100644 examples/ip_pipeline/action.h
delete mode 100644 examples/ip_pipeline/cli.c
delete mode 100644 examples/ip_pipeline/cli.h
delete mode 100644 examples/ip_pipeline/common.h
delete mode 100644 examples/ip_pipeline/conn.c
delete mode 100644 examples/ip_pipeline/conn.h
delete mode 100644 examples/ip_pipeline/cryptodev.c
delete mode 100644 examples/ip_pipeline/cryptodev.h
delete mode 100644 examples/ip_pipeline/examples/firewall.cli
delete mode 100644 examples/ip_pipeline/examples/flow.cli
delete mode 100644 examples/ip_pipeline/examples/flow_crypto.cli
delete mode 100644 examples/ip_pipeline/examples/l2fwd.cli
delete mode 100644 examples/ip_pipeline/examples/route.cli
delete mode 100644 examples/ip_pipeline/examples/route_ecmp.cli
delete mode 100644 examples/ip_pipeline/examples/rss.cli
delete mode 100644 examples/ip_pipeline/examples/tap.cli
delete mode 100644 examples/ip_pipeline/link.c
delete mode 100644 examples/ip_pipeline/link.h
delete mode 100644 examples/ip_pipeline/main.c
delete mode 100644 examples/ip_pipeline/mempool.c
delete mode 100644 examples/ip_pipeline/mempool.h
delete mode 100644 examples/ip_pipeline/meson.build
delete mode 100644 examples/ip_pipeline/parser.c
delete mode 100644 examples/ip_pipeline/parser.h
delete mode 100644 examples/ip_pipeline/pipeline.c
delete mode 100644 examples/ip_pipeline/pipeline.h
delete mode 100644 examples/ip_pipeline/swq.c
delete mode 100644 examples/ip_pipeline/swq.h
delete mode 100644 examples/ip_pipeline/tap.c
delete mode 100644 examples/ip_pipeline/tap.h
delete mode 100644 examples/ip_pipeline/thread.c
delete mode 100644 examples/ip_pipeline/thread.h
delete mode 100644 examples/ip_pipeline/tmgr.c
delete mode 100644 examples/ip_pipeline/tmgr.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 4c06f85706ca9204cab6a655a58b6b7b1457160d..ae84e7f289468ac7a6f3f727732377260781ceb4 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1739,9 +1739,7 @@ F: lib/pipeline/
F: lib/port/
F: lib/table/
F: doc/guides/prog_guide/packet_framework.rst
-F: examples/ip_pipeline/
F: examples/pipeline/
-F: doc/guides/sample_app_ug/ip_pipeline.rst
Algorithms
diff --git a/doc/guides/nics/softnic.rst b/doc/guides/nics/softnic.rst
index 603fdb49c461dba89d2d445c8a521485a367ff95..87f3e5adc0e237a31e0048ca75f0eaa5438ae4ce 100644
--- a/doc/guides/nics/softnic.rst
+++ b/doc/guides/nics/softnic.rst
@@ -10,8 +10,7 @@ is DIY and reconfigurable through ``firmware`` (DPDK Packet Framework script).
The Soft NIC leverages the DPDK Packet Framework libraries (librte_port,
librte_table and librte_pipeline) to make it modular, flexible and extensible
with new functionality.
-Please refer to :doc:`/prog_guide/packet_framework` and
-:doc:`/sample_app_ug/ip_pipeline` for more details.
+Please refer to :doc:`/prog_guide/packet_framework` for more details.
The Soft NIC is configured through the standard DPDK ethdev API (ethdev, flow,
QoS, security). The internal framework is not externally visible.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 6ad0cf6eeca19f32429e60c2637b06274d43754a..fc84ba367ea730c393caf11883a09024b6c07688 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -80,6 +80,10 @@ Removed Items
* Removed the ``dpdk-test-pipeline`` application, which was based on
the legacy pipeline library API.
+* Removed the ``ip_pipeline`` example application, which was based on
+ the legacy pipeline library API.
+ The ``pipeline`` example application covers the SWX pipeline API.
+
API Changes
-----------
diff --git a/doc/guides/sample_app_ug/index.rst b/doc/guides/sample_app_ug/index.rst
index c8b50b801c5ca317c8107b182a4633a4918fb199..28c4c9a5b2636037304d3b63ca19861e0bfd6d21 100644
--- a/doc/guides/sample_app_ug/index.rst
+++ b/doc/guides/sample_app_ug/index.rst
@@ -44,7 +44,6 @@ Sample Applications User Guides
vhost_blk
vhost_crypto
vdpa
- ip_pipeline
pipeline
eventdev_pipeline
dist_app
diff --git a/doc/guides/sample_app_ug/ip_pipeline.rst b/doc/guides/sample_app_ug/ip_pipeline.rst
deleted file mode 100644
index 9a5cb517a2baa97afb059827c39b56087e81d81d..0000000000000000000000000000000000000000
--- a/doc/guides/sample_app_ug/ip_pipeline.rst
+++ /dev/null
@@ -1,531 +0,0 @@
-.. SPDX-License-Identifier: BSD-3-Clause
- Copyright(c) 2015-2018 Intel Corporation.
-
-Internet Protocol (IP) Pipeline Application
-===========================================
-
-Application overview
---------------------
-
-The *Internet Protocol (IP) Pipeline* application is intended to be a vehicle for rapid development of packet processing
-applications on multi-core CPUs.
-
-Following OpenFlow and P4 design principles, the application can be used to create functional blocks called pipelines out
-of input/output ports, tables and actions in a modular way. Multiple pipelines can be inter-connected through packet queues
-to create complete applications (super-pipelines).
-
-The pipelines are mapped to application threads, with each pipeline executed by a single thread and each thread able to run
-one or several pipelines. The possibilities of creating pipelines out of ports, tables and actions, connecting multiple
-pipelines together and mapping the pipelines to execution threads are endless, therefore this application can be seen as
-a true application generator.
-
-Pipelines are created and managed through Command Line Interface (CLI):
-
- * Any standard TCP client (e.g. telnet, netcat, custom script, etc) is typically able to connect to the application, send
- commands through the network and wait for the response before pushing the next command.
-
- * All the application objects are created and managed through CLI commands:
- * 'Primitive' objects used to create pipeline ports: memory pools, links (i.e. network interfaces), SW queues, traffic managers, etc.
- * Action profiles: used to define the actions to be executed by pipeline input/output ports and tables.
- * Pipeline components: input/output ports, tables, pipelines, mapping of pipelines to execution threads.
-
-Running the application
------------------------
-
-The application startup command line is::
-
- dpdk-ip_pipeline [EAL_ARGS] -- [-s SCRIPT_FILE] [-h HOST] [-p PORT]
-
-The application startup arguments are:
-
-``-s SCRIPT_FILE``
-
- * Optional: Yes
-
- * Default: Not present
-
- * Argument: Path to the CLI script file to be run at application startup.
- No CLI script file will run at startup if this argument is not present.
-
-``-h HOST``
-
- * Optional: Yes
-
- * Default: ``0.0.0.0``
-
- * Argument: IP Address of the host running ip pipeline application to be used by
- remote TCP based client (telnet, netcat, etc.) for connection.
-
-``-p PORT``
-
- * Optional: Yes
-
- * Default: ``8086``
-
- * Argument: TCP port number at which the ip pipeline is running.
- This port number should be used by remote TCP client (such as telnet, netcat, etc.) to connect to host application.
-
-Refer to *DPDK Getting Started Guide* for general information on running applications and the Environment Abstraction Layer (EAL) options.
-
-The following is an example command to run ip pipeline application configured for layer 2 forwarding:
-
-.. code-block:: console
-
- $ ./<build_dir>/examples/dpdk-ip_pipeline -l 0,1 -- -s examples/route_ecmp.cli
-
-The application should start successfully and display as follows:
-
-.. code-block:: console
-
- EAL: Detected 40 lcore(s)
- EAL: Detected 2 NUMA nodes
- EAL: Multi-process socket /var/run/.rte_unix
- EAL: Probing VFIO support...
- EAL: PCI device 0000:02:00.0 on NUMA socket 0
- EAL: probe driver: 8086:10fb net_ixgbe
- ...
-
-To run remote client (e.g. telnet) to communicate with the ip pipeline application:
-
-.. code-block:: console
-
- $ telnet 127.0.0.1 8086
-
-When running a telnet client as above, command prompt is displayed:
-
-.. code-block:: console
-
- Trying 127.0.0.1...
- Connected to 127.0.0.1.
- Escape character is '^]'.
-
- Welcome to IP Pipeline!
-
- pipeline>
-
-Once application and telnet client start running, messages can be sent from client to application.
-At any stage, telnet client can be terminated using the quit command.
-
-
-Application stages
-------------------
-
-Initialization
-~~~~~~~~~~~~~~
-
-During this stage, EAL layer is initialised and application specific arguments are parsed. Furthermore, the data structures
-(i.e. linked lists) for application objects are initialized. In case of any initialization error, an error message
-is displayed and the application is terminated.
-
-Run-time
-~~~~~~~~
-
-The main thread is creating and managing all the application objects based on CLI input.
-
-Each data plane thread runs one or several pipelines previously assigned to it in round-robin order. Each data plane thread
-executes two tasks in time-sharing mode:
-
-#. *Packet processing task*: Process bursts of input packets read from the pipeline input ports.
-
-#. *Message handling task*: Periodically, the data plane thread pauses the packet processing task and polls for request
- messages send by the main thread. Examples: add/remove pipeline to/from current data plane thread, add/delete rules
- to/from given table of a specific pipeline owned by the current data plane thread, read statistics, etc.
-
-Examples
---------
-
-.. tabularcolumns:: |p{3cm}|p{5cm}|p{4cm}|p{4cm}|
-
-.. table:: Pipeline examples provided with the application
-
- +-----------------------+----------------------+----------------+------------------------------------+
- | Name | Table(s) | Actions | Messages |
- +=======================+======================+================+====================================+
- | L2fwd | Stub | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | Note: Implemented | | | 3. Pipeline create |
- | using pipeline with | | | 4. Pipeline port in/out |
- | a simple pass-through | | | 5. Pipeline table |
- | connection between | | | 6. Pipeline port in table |
- | input and output | | | 7. Pipeline enable |
- | ports. | | | 8. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Flow classification | Exact match | Forward | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = byte array | | 3. Pipeline create |
- | | (16 bytes) | | 4. Pipeline port in/out |
- | | * Offset = 278 | | 5. Pipeline table |
- | | * Table size = 64K | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Firewall | ACL | Allow/Drop | 1. Mempool create |
- | | | | 2. Link create |
- | | * Key = n-tuple | | 3. Pipeline create |
- | | * Offset = 270 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | IP routing | LPM (IPv4) | Forward | 1. Mempool Create |
- | | | | 2. Link create |
- | | * Key = IP dest addr | | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table |
- | | | | 6. Pipeline port in table |
- | | | | 7. Pipeline enable |
- | | | | 8. Pipeline table rule add default |
- | | | | 9. Pipeline table rule add |
- +-----------------------+----------------------+----------------+------------------------------------+
- | Equal-cost multi-path | LPM (IPv4) | Forward, | 1. Mempool Create |
- | routing (ECMP) | | load balance, | 2. Link create |
- | | * Key = IP dest addr | encap ether | 3. Pipeline create |
- | | * Offset = 286 | | 4. Pipeline port in/out |
- | | * Table size = 4K | | 5. Pipeline table (LPM) |
- | | | | 6. Pipeline table (Array) |
- | | | | 7. Pipeline port in table (LPM) |
- | | Array | | 8. Pipeline enable |
- | | | | 9. Pipeline table rule add default |
- | | * Key = Array index | | 10. Pipeline table rule add(LPM) |
- | | * Offset = 256 | | 11. Pipeline table rule add(Array) |
- | | * Size = 64K | | |
- | | | | |
- +-----------------------+----------------------+----------------+------------------------------------+
-
-Command Line Interface (CLI)
-----------------------------
-
-Link
-~~~~
-
- Link configuration ::
-
- link <link_name>
- dev <device_name>|port <port_id>
- rxq <n_queues> <queue_size> <mempool_name>
- txq <n_queues> <queue_size> promiscuous on | off
- [rss <qid_0> ... <qid_n>]
-
- Note: The PCI device name must be specified in the Domain:Bus:Device.Function format.
-
-
-Mempool
-~~~~~~~
-
- Mempool create ::
-
- mempool <mempool_name> buffer <buffer_size>
- pool <pool_size> cache <cache_size> cpu <cpu_id>
-
-
-Software queue
-~~~~~~~~~~~~~~
-
- Create software queue ::
-
- swq <swq_name> size <size> cpu <cpu_id>
-
-
-Traffic manager
-~~~~~~~~~~~~~~~
-
- Add traffic manager subport profile ::
-
- tmgr subport profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
-
- Add traffic manager pipe profile ::
-
- tmgr pipe profile
- <tb_rate> <tb_size>
- <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>
- <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>
- <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>
- <tc_period>
- <tc_ov_weight>
- <wrr_weight0..3>
-
- Create traffic manager port ::
-
- tmgr <tmgr_name>
- rate <rate>
- spp <n_subports_per_port>
- pps <n_pipes_per_subport>
- fo <frame_overhead>
- mtu <mtu>
- cpu <cpu_id>
-
- Configure traffic manager subport ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- profile <subport_profile_id>
-
- Configure traffic manager pipe ::
-
- tmgr <tmgr_name>
- subport <subport_id>
- pipe from <pipe_id_first> to <pipe_id_last>
- profile <pipe_profile_id>
-
-
-Tap
-~~~
-
- Create tap port ::
-
- tap <name>
-
-
-Cryptodev
-~~~~~~~~~
-
- Create cryptodev port ::
-
- cryptodev <cryptodev_name>
- dev <DPDK Cryptodev PMD name>
- queue <n_queues> <queue_size>
-
-Action profile
-~~~~~~~~~~~~~~
-
- Create action profile for pipeline input port ::
-
- port in action profile <profile_name>
- [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]
- [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]
-
- Create action profile for the pipeline table ::
-
- table action profile <profile_name>
- ipv4 | ipv6
- offset <ip_offset>
- fwd
- [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]
- [meter srtcm | trtcm
- tc <n_tc>
- stats none | pkts | bytes | both]
- [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]
- [encap ether | vlan | qinq | mpls | pppoe]
- [nat src | dst
- proto udp | tcp]
- [ttl drop | fwd
- stats none | pkts]
- [stats pkts | bytes | both]
- [sym_crypto cryptodev <cryptodev_name>
- mempool_create <mempool_name> mempool_init <mempool_name>]
- [time]
-
-
-Pipeline
-~~~~~~~~
-
-Create pipeline ::
-
- pipeline <pipeline_name>
- period <timer_period_ms>
- offset_port_id <offset_port_id>
- cpu <cpu_id>
-
-Create pipeline input port ::
-
- pipeline <pipeline_name> port in
- bsz <burst_size>
- link <link_name> rxq <queue_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name> mempool <mempool_name> mtu <mtu>
- | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>
- [action <port_in_action_profile_name>]
- [disabled]
-
-Create pipeline output port ::
-
- pipeline <pipeline_name> port out
- bsz <burst_size>
- link <link_name> txq <txq_id>
- | swq <swq_name>
- | tmgr <tmgr_name>
- | tap <tap_name>
- | sink [file <file_name> pkts <max_n_pkts>]
-
-Create pipeline table ::
-
- pipeline <pipeline_name> table
- match
- acl
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | array
- offset <key_offset>
- size <n_keys>
- | hash
- ext | lru
- key <key_size>
- mask <key_mask>
- offset <key_offset>
- buckets <n_buckets>
- size <n_keys>
- | lpm
- ipv4 | ipv6
- offset <ip_header_offset>
- size <n_rules>
- | stub
- [action <table_action_profile_name>]
-
-Connect pipeline input port to table ::
-
- pipeline <pipeline_name> port in <port_id> table <table_id>
-
-Display statistics for specific pipeline input port, output port
-or table ::
-
- pipeline <pipeline_name> port in <port_id> stats read [clear]
- pipeline <pipeline_name> port out <port_id> stats read [clear]
- pipeline <pipeline_name> table <table_id> stats read [clear]
-
-Enable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Disable given input port for specific pipeline instance ::
-
- pipeline <pipeline_name> port out <port_id> disable
-
-Add default rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
- match
- default
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
-
-Add rule to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add
-
- match
- acl
- priority <priority>
- ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- <sp0> <sp1> <dp0> <dp1> <proto>
- | array <pos>
- | hash
- raw <key>
- | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- | ipv4_addr <addr>
- | ipv6_addr <addr>
- | qinq <svlan> <cvlan>
- | lpm
- ipv4 | ipv6 <addr> <depth>
-
- action
- fwd
- drop
- | port <port_id>
- | meta
- | table <table_id>
- [balance <out0> ... <out7>]
- [meter
- tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- [tm subport <subport_id> pipe <pipe_id>]
- [encap
- ether <da> <sa>
- | vlan <da> <sa> <pcp> <dei> <vid>
- | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- | mpls unicast | multicast
- <da> <sa>
- label0 <label> <tc> <ttl>
- [label1 <label> <tc> <ttl>
- [label2 <label> <tc> <ttl>
- [label3 <label> <tc> <ttl>]]]
- | pppoe <da> <sa> <session_id>]
- [nat ipv4 | ipv6 <addr> <port>]
- [ttl dec | keep]
- [stats]
- [time]
- [sym_crypto
- encrypt | decrypt
- type
- | cipher
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- | cipher_auth
- cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- auth_algo <algo> auth_key <key> digest_size <size>
- | aead
- aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- digest_size <size>
- data_offset <data_offset>]
-
- where:
- <pa> ::= g | y | r | drop
-
-Add bulk rules to table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule add bulk <file_name> <n_rules>
-
- Where:
- - file_name = path to file
- - File line format = match <match> action <action>
-
-Delete table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match <match>
-
-Delete default table rule for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> rule delete
- match
- default
-
-Add meter profile to the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>
- add srtcm cir <cir> cbs <cbs> ebs <ebs>
- | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>
-
-Delete meter profile from the table for specific pipeline instance ::
-
- pipeline <pipeline_name> table <table_id>
- meter profile <meter_profile_id> delete
-
-
-Update the dscp table for meter or traffic manager action for specific
-pipeline instance ::
-
- pipeline <pipeline_name> table <table_id> dscp <file_name>
-
- Where:
- - file_name = path to file
- - exactly 64 lines
- - File line format = <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r
-
-
-Pipeline enable/disable
-~~~~~~~~~~~~~~~~~~~~~~~
-
- Enable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> enable
-
-
- Disable given pipeline instance for specific data plane thread ::
-
- thread <thread_id> pipeline <pipeline_name> disable
diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
deleted file mode 100644
index 438aa6b37fb81f309f904af85fed31b7f49c5a78..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/Makefile
+++ /dev/null
@@ -1,60 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2010-2018 Intel Corporation
-
-# binary name
-APP = ip_pipeline
-
-# all source are stored in SRCS-y
-SRCS-y := action.c
-SRCS-y += cli.c
-SRCS-y += conn.c
-SRCS-y += link.c
-SRCS-y += main.c
-SRCS-y += mempool.c
-SRCS-y += parser.c
-SRCS-y += pipeline.c
-SRCS-y += swq.c
-SRCS-y += tap.c
-SRCS-y += thread.c
-SRCS-y += tmgr.c
-SRCS-y += cryptodev.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)
-
-CFLAGS += -I. -DALLOW_EXPERIMENTAL_API -D_GNU_SOURCE
-
-OBJS := $(patsubst %.c,build/%.o,$(SRCS-y))
-
-build/%.o: %.c Makefile $(PC_FILE) | build
- $(CC) $(CFLAGS) -c $< -o $@
-
-build/$(APP)-shared: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
-
-build/$(APP)-static: $(OBJS)
- $(CC) $(OBJS) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
-
-build:
- @mkdir -p $@
-
-.PHONY: clean
-clean:
- rm -f build/$(APP)* build/*.o
- test -d build && rmdir -p build || true
diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
deleted file mode 100644
index d2104aad6e8be51b60bbdea7c6f08061d40331dd..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/action.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-#include <rte_table_hash_func.h>
-
-#include "action.h"
-
-/**
- * Input port
- */
-static struct port_in_action_profile_list port_in_action_profile_list;
-
-int
-port_in_action_profile_init(void)
-{
- TAILQ_INIT(&port_in_action_profile_list);
-
- return 0;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name)
-{
- struct port_in_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &port_in_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params)
-{
- struct port_in_action_profile *profile;
- struct rte_port_in_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- port_in_action_profile_find(name) ||
- (params == NULL))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
- /* Resource */
- ap = rte_port_in_action_profile_create(0);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_FLTR,
- ¶ms->fltr);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_port_in_action_profile_freeze(ap);
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct port_in_action_profile));
- if (profile == NULL) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&port_in_action_profile_list, profile, node);
-
- return profile;
-}
-
-/**
- * Table
- */
-static struct table_action_profile_list table_action_profile_list;
-
-int
-table_action_profile_init(void)
-{
- TAILQ_INIT(&table_action_profile_list);
-
- return 0;
-}
-
-struct table_action_profile *
-table_action_profile_find(const char *name)
-{
- struct table_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &table_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params)
-{
- struct table_action_profile *profile;
- struct rte_table_action_profile *ap;
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- table_action_profile_find(name) ||
- (params == NULL) ||
- ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
- (params->lb.f_hash == NULL)) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
-
- /* Resource */
- ap = rte_table_action_profile_create(¶ms->common);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_FWD,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_MTR,
- ¶ms->mtr);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TM,
- ¶ms->tm);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_ENCAP,
- ¶ms->encap);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_NAT,
- ¶ms->nat);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TTL,
- ¶ms->ttl);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_STATS,
- ¶ms->stats);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TIME,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- ¶ms->sym_crypto);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TAG,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_DECAP,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_table_action_profile_freeze(ap);
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct table_action_profile));
- if (profile == NULL) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(profile->name, name, sizeof(profile->name));
- memcpy(&profile->params, params, sizeof(*params));
- profile->ap = ap;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&table_action_profile_list, profile, node);
-
- return profile;
-}
diff --git a/examples/ip_pipeline/action.h b/examples/ip_pipeline/action.h
deleted file mode 100644
index cde17e69a3e30471ab682df3239bf9cf80b98ef2..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/action.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_ACTION_H_
-#define _INCLUDE_ACTION_H_
-
-#include <sys/queue.h>
-
-#include <rte_port_in_action.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-
-/**
- * Input port action
- */
-struct port_in_action_profile_params {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-struct port_in_action_profile {
- TAILQ_ENTRY(port_in_action_profile) node;
- char name[NAME_SIZE];
- struct port_in_action_profile_params params;
- struct rte_port_in_action_profile *ap;
-};
-
-TAILQ_HEAD(port_in_action_profile_list, port_in_action_profile);
-
-int
-port_in_action_profile_init(void);
-
-struct port_in_action_profile *
-port_in_action_profile_find(const char *name);
-
-struct port_in_action_profile *
-port_in_action_profile_create(const char *name,
- struct port_in_action_profile_params *params);
-
-/**
- * Table action
- */
-struct table_action_profile_params {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-struct table_action_profile {
- TAILQ_ENTRY(table_action_profile) node;
- char name[NAME_SIZE];
- struct table_action_profile_params params;
- struct rte_table_action_profile *ap;
-};
-
-TAILQ_HEAD(table_action_profile_list, table_action_profile);
-
-int
-table_action_profile_init(void);
-
-struct table_action_profile *
-table_action_profile_find(const char *name);
-
-struct table_action_profile *
-table_action_profile_create(const char *name,
- struct table_action_profile_params *params);
-
-#endif /* _INCLUDE_ACTION_H_ */
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
deleted file mode 100644
index 935c9b39d5ec455f06c2b3e863e0523b2d48fb84..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/cli.c
+++ /dev/null
@@ -1,6791 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-
-#include "cli.h"
-
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "parser.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-#ifndef CMD_MAX_TOKENS
-#define CMD_MAX_TOKENS 256
-#endif
-
-#define MSG_OUT_OF_MEMORY "Not enough memory.\n"
-#define MSG_CMD_UNKNOWN "Unknown command \"%s\".\n"
-#define MSG_CMD_UNIMPLEM "Command \"%s\" not implemented.\n"
-#define MSG_ARG_NOT_ENOUGH "Not enough arguments for command \"%s\".\n"
-#define MSG_ARG_TOO_MANY "Too many arguments for command \"%s\".\n"
-#define MSG_ARG_MISMATCH "Wrong number of arguments for command \"%s\".\n"
-#define MSG_ARG_NOT_FOUND "Argument \"%s\" not found.\n"
-#define MSG_ARG_INVALID "Invalid value for argument \"%s\".\n"
-#define MSG_FILE_ERR "Error in file \"%s\" at line %u.\n"
-#define MSG_FILE_NOT_ENOUGH "Not enough rules in file \"%s\".\n"
-#define MSG_CMD_FAIL "Command \"%s\" failed.\n"
-
-static int
-is_comment(char *in)
-{
- if ((strlen(in) && index("!#%;", in[0])) ||
- (strncmp(in, "//", 2) == 0) ||
- (strncmp(in, "--", 2) == 0))
- return 1;
-
- return 0;
-}
-
-static const char cmd_mempool_help[] =
-"mempool <mempool_name>\n"
-" buffer <buffer_size>\n"
-" pool <pool_size>\n"
-" cache <cache_size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_mempool(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct mempool_params p;
- char *name;
- struct mempool *mempool;
-
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "buffer") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer");
- return;
- }
-
- if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size");
- return;
- }
-
- if (strcmp(tokens[4], "pool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool");
- return;
- }
-
- if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pool_size");
- return;
- }
-
- if (strcmp(tokens[6], "cache") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache");
- return;
- }
-
- if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cache_size");
- return;
- }
-
- if (strcmp(tokens[8], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- mempool = mempool_create(name, &p);
- if (mempool == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_link_help[] =
-"link <link_name>\n"
-" dev <device_name> | port <port_id>\n"
-" rxq <n_queues> <queue_size> <mempool_name>\n"
-" txq <n_queues> <queue_size>\n"
-" promiscuous on | off\n"
-" [rss <qid_0> ... <qid_n>]\n";
-
-static void
-cmd_link(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct link_params p;
- struct link_params_rss rss;
- struct link *link;
- char *name;
-
- memset(&p, 0, sizeof(p));
-
- if ((n_tokens < 13) || (n_tokens > 14 + LINK_RXQ_RSS_MAX)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- p.dev_name = tokens[3];
- else if (strcmp(tokens[2], "port") == 0) {
- p.dev_name = NULL;
-
- if (parser_read_uint16(&p.port_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dev or port");
- return;
- }
-
- if (strcmp(tokens[4], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint32(&p.rx.n_queues, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
- if (parser_read_uint32(&p.rx.queue_size, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- p.rx.mempool_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint32(&p.tx.n_queues, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_queues");
- return;
- }
-
- if (parser_read_uint32(&p.tx.queue_size, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_size");
- return;
- }
-
- if (strcmp(tokens[11], "promiscuous") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "promiscuous");
- return;
- }
-
- if (strcmp(tokens[12], "on") == 0)
- p.promiscuous = 1;
- else if (strcmp(tokens[12], "off") == 0)
- p.promiscuous = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "on or off");
- return;
- }
-
- /* RSS */
- p.rx.rss = NULL;
- if (n_tokens > 13) {
- uint32_t queue_id, i;
-
- if (strcmp(tokens[13], "rss") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rss");
- return;
- }
-
- p.rx.rss = &rss;
-
- rss.n_queues = 0;
- for (i = 14; i < n_tokens; i++) {
- if (parser_read_uint32(&queue_id, tokens[i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
-
- rss.queue_id[rss.n_queues] = queue_id;
- rss.n_queues++;
- }
- }
-
- link = link_create(name, &p);
- if (link == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-/* Print the link stats and info */
-static void
-print_link_info(struct link *link, char *out, size_t out_size)
-{
- struct rte_eth_stats stats;
- struct rte_ether_addr mac_addr;
- struct rte_eth_link eth_link;
- uint16_t mtu;
- int ret;
-
- memset(&stats, 0, sizeof(stats));
- rte_eth_stats_get(link->port_id, &stats);
-
- ret = rte_eth_macaddr_get(link->port_id, &mac_addr);
- if (ret != 0) {
- snprintf(out, out_size, "\n%s: MAC address get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- ret = rte_eth_link_get(link->port_id, ð_link);
- if (ret < 0) {
- snprintf(out, out_size, "\n%s: link get failed: %s",
- link->name, rte_strerror(-ret));
- return;
- }
-
- rte_eth_dev_get_mtu(link->port_id, &mtu);
-
- snprintf(out, out_size,
- "\n"
- "%s: flags=<%s> mtu %u\n"
- "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n"
- "\tport# %u speed %s\n"
- "\tRX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n"
- "\tTX packets %" PRIu64" bytes %" PRIu64"\n"
- "\tTX errors %" PRIu64"\n",
- link->name,
- eth_link.link_status == 0 ? "DOWN" : "UP",
- mtu,
- RTE_ETHER_ADDR_BYTES(&mac_addr),
- link->n_rxq,
- link->n_txq,
- link->port_id,
- rte_eth_link_speed_to_str(eth_link.link_speed),
- stats.ipackets,
- stats.ibytes,
- stats.ierrors,
- stats.imissed,
- stats.rx_nombuf,
- stats.opackets,
- stats.obytes,
- stats.oerrors);
-}
-
-/*
- * link show [<link_name>]
- */
-static void
-cmd_link_show(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- struct link *link;
- char *link_name;
-
- if (n_tokens != 2 && n_tokens != 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (n_tokens == 2) {
- link = link_next(NULL);
-
- while (link != NULL) {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- print_link_info(link, out, out_size);
- link = link_next(link);
- }
- } else {
- out_size = out_size - strlen(out);
- out = &out[strlen(out)];
-
- link_name = tokens[2];
- link = link_find(link_name);
-
- if (link == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "Link does not exist");
- return;
- }
- print_link_info(link, out, out_size);
- }
-}
-
-static const char cmd_swq_help[] =
-"swq <swq_name>\n"
-" size <size>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_swq(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct swq_params p;
- char *name;
- struct swq *swq;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.size, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "size");
- return;
- }
-
- if (strcmp(tokens[4], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- swq = swq_create(name, &p);
- if (swq == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_profile_help[] =
-"tmgr subport profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n";
-
-static void
-cmd_tmgr_subport_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_subport_profile_params subport_profile;
- int status, i;
-
- if (n_tokens != 19) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&subport_profile.tc_rate[i],
- tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&subport_profile.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- status = tmgr_subport_profile_add(&subport_profile);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_pipe_profile_help[] =
-"tmgr pipe profile\n"
-" <tb_rate> <tb_size>\n"
-" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>"
-" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>"
-" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n"
-" <tc_period>\n"
-" <tc_ov_weight>\n"
-" <wrr_weight0..3>\n";
-
-static void
-cmd_tmgr_pipe_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_sched_pipe_params p;
- int status, i;
-
- if (n_tokens != 24) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint64(&p.tb_rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tb_size, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tb_size");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- if (parser_read_uint64(&p.tc_rate[i], tokens[5 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
- return;
- }
-
- if (parser_read_uint64(&p.tc_period, tokens[18]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
- return;
- }
-
- if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
- return;
- }
-
- for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++)
- if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights");
- return;
- }
-
- status = tmgr_pipe_profile_add(&p);
- if (status != 0) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_help[] =
-"tmgr <tmgr_name>\n"
-" rate <rate>\n"
-" spp <n_subports_per_port>\n"
-" pps <n_pipes_per_subport>\n"
-" fo <frame_overhead>\n"
-" mtu <mtu>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_tmgr(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct tmgr_port_params p;
- char *name;
- struct tmgr_port *tmgr_port;
-
- if (n_tokens != 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "rate") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rate");
- return;
- }
-
- if (parser_read_uint64(&p.rate, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "rate");
- return;
- }
-
- if (strcmp(tokens[4], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_subports_per_port, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[6], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.n_pipes_per_subport, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_pipes_per_subport");
- return;
- }
-
- if (strcmp(tokens[8], "fo") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
- return;
- }
-
- if (parser_read_uint32(&p.frame_overhead, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
- return;
- }
-
- if (strcmp(tokens[10], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.mtu, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- if (strcmp(tokens[12], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- tmgr_port = tmgr_port_create(name, &p);
- if (tmgr_port == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_tmgr_subport_help[] =
-"tmgr <tmgr_name> subport <subport_id>\n"
-" profile <subport_profile_id>\n";
-
-static void
-cmd_tmgr_subport(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, subport_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (parser_read_uint32(&subport_profile_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_profile_id");
- return;
- }
-
- status = tmgr_subport_config(name, subport_id, subport_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tmgr_subport_pipe_help[] =
-"tmgr <tmgr_name> subport <subport_id> pipe\n"
-" from <pipe_id_first> to <pipe_id_last>\n"
-" profile <pipe_profile_id>\n";
-
-static void
-cmd_tmgr_subport_pipe(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint32_t subport_id, pipe_id_first, pipe_id_last, pipe_profile_id;
- int status;
- char *name;
-
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (parser_read_uint32(&subport_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "subport_id");
- return;
- }
-
- if (strcmp(tokens[4], "pipe") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipe");
- return;
- }
-
- if (strcmp(tokens[5], "from") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "from");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_first, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_first");
- return;
- }
-
- if (strcmp(tokens[7], "to") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "to");
- return;
- }
-
- if (parser_read_uint32(&pipe_id_last, tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_id_last");
- return;
- }
-
- if (strcmp(tokens[9], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&pipe_profile_id, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pipe_profile_id");
- return;
- }
-
- status = tmgr_pipe_config(name, subport_id, pipe_id_first,
- pipe_id_last, pipe_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_tap_help[] =
-"tap <tap_name>\n";
-
-static void
-cmd_tap(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *name;
- struct tap *tap;
-
- if (n_tokens != 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- tap = tap_create(name);
- if (tap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_cryptodev_help[] =
-"cryptodev <cryptodev_name>\n"
-" dev <device_name> | dev_id <device_id>\n"
-" queue <n_queues> <queue_size>\n"
-" max_sessions <n_sessions>";
-
-static void
-cmd_cryptodev(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct cryptodev_params params;
- char *name;
-
- memset(¶ms, 0, sizeof(params));
- if (n_tokens != 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "dev") == 0)
- params.dev_name = tokens[3];
- else if (strcmp(tokens[2], "dev_id") == 0) {
- if (parser_read_uint32(¶ms.dev_id, tokens[3]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "dev_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cryptodev");
- return;
- }
-
- if (strcmp(tokens[4], "queue")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "queue");
- return;
- }
-
- if (parser_read_uint32(¶ms.n_queues, tokens[5]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "q");
- return;
- }
-
- if (parser_read_uint32(¶ms.queue_size, tokens[6]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (strcmp(tokens[7], "max_sessions")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "max_sessions");
- return;
- }
-
- if (parser_read_uint32(¶ms.session_pool_size, tokens[8]) < 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_size");
- return;
- }
-
- if (cryptodev_create(name, ¶ms) == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_port_in_action_profile_help[] =
-"port in action profile <profile_name>\n"
-" [filter match | mismatch offset <key_offset> mask <key_mask> key <key_value> port <port_id>]\n"
-" [balance offset <key_offset> mask <key_mask> port <port_id0> ... <port_id15>]\n";
-
-static void
-cmd_port_in_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_action_profile_params p;
- struct port_in_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[2], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[3], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[4];
-
- t0 = 5;
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "filter") == 0)) {
- uint32_t size;
-
- if (n_tokens < t0 + 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "port in action profile filter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "match") == 0)
- p.fltr.filter_on_match = 1;
- else if (strcmp(tokens[t0 + 1], "mismatch") == 0)
- p.fltr.filter_on_match = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "match or mismatch");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.key_offset, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 5], p.fltr.key_mask, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 6], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- size = RTE_PORT_IN_ACTION_FLTR_KEY_SIZE;
- if ((parse_hex_string(tokens[t0 + 7], p.fltr.key, &size) != 0) ||
- (size != RTE_PORT_IN_ACTION_FLTR_KEY_SIZE)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_value");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&p.fltr.port_id, tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_FLTR;
- t0 += 10;
- } /* filter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- uint32_t i;
-
- if (n_tokens < t0 + 22) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "port in action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- for (i = 0; i < 16; i++)
- if (parser_read_uint32(&p.lb.port_id[i], tokens[t0 + 6 + i]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_PORT_IN_ACTION_LB;
- t0 += 22;
- } /* balance */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = port_in_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_table_action_profile_help[] =
-"table action profile <profile_name>\n"
-" ipv4 | ipv6\n"
-" offset <ip_offset>\n"
-" fwd\n"
-" [balance offset <key_offset> mask <key_mask> outoffset <out_offset>]\n"
-" [meter srtcm | trtcm\n"
-" tc <n_tc>\n"
-" stats none | pkts | bytes | both]\n"
-" [tm spp <n_subports_per_port> pps <n_pipes_per_subport>]\n"
-" [encap ether | vlan | qinq | mpls | pppoe | qinq_pppoe \n"
-" vxlan offset <ether_offset> ipv4 | ipv6 vlan on | off]\n"
-" [nat src | dst\n"
-" proto udp | tcp]\n"
-" [ttl drop | fwd\n"
-" stats none | pkts]\n"
-" [stats pkts | bytes | both]\n"
-" [time]\n"
-" [sym_crypto dev <CRYPTODEV_NAME> offset <op_offset>]\n"
-" [tag]\n"
-" [decap]\n";
-
-static void
-cmd_table_action_profile(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_action_profile_params p;
- struct table_action_profile *ap;
- char *name;
- uint32_t t0;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (strcmp(tokens[1], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "action");
- return;
- }
-
- if (strcmp(tokens[2], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- name = tokens[3];
-
- if (strcmp(tokens[4], "ipv4") == 0)
- p.common.ip_version = 1;
- else if (strcmp(tokens[4], "ipv6") == 0)
- p.common.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID, "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[5], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.common.ip_offset, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ip_offset");
- return;
- }
-
- if (strcmp(tokens[7], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fwd");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
-
- t0 = 8;
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "balance") == 0)) {
- if (n_tokens < t0 + 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "table action profile balance");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.key_offset, tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- p.lb.key_size = RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX;
- if (parse_hex_string(tokens[t0 + 4], p.lb.key_mask, &p.lb.key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "outoffset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "outoffset");
- return;
- }
-
- if (parser_read_uint32(&p.lb.out_offset, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "out_offset");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_LB;
- t0 += 7;
- } /* balance */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "meter") == 0)) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile meter");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "srtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_SRTCM;
- else if (strcmp(tokens[t0 + 1], "trtcm") == 0)
- p.mtr.alg = RTE_TABLE_ACTION_METER_TRTCM;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "srtcm or trtcm");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "tc") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc");
- return;
- }
-
- if (parser_read_uint32(&p.mtr.n_tc, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_tc");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 5], "none") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "pkts") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 5], "bytes") == 0) {
- p.mtr.n_packets_enabled = 0;
- p.mtr.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 5], "both") == 0) {
- p.mtr.n_packets_enabled = 1;
- p.mtr.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_MTR;
- t0 += 6;
- } /* meter */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tm") == 0)) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile tm");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "spp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "spp");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_subports_per_port,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_subports_per_port");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "pps") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pps");
- return;
- }
-
- if (parser_read_uint32(&p.tm.n_pipes_per_subport,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_pipes_per_subport");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TM;
- t0 += 5;
- } /* tm */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "encap") == 0)) {
- uint32_t n_extra_tokens = 0;
-
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "ether") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER;
- else if (strcmp(tokens[t0 + 1], "vlan") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN;
- else if (strcmp(tokens[t0 + 1], "qinq") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ;
- else if (strcmp(tokens[t0 + 1], "mpls") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS;
- else if (strcmp(tokens[t0 + 1], "pppoe") == 0)
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE;
- else if (strcmp(tokens[t0 + 1], "vxlan") == 0) {
- if (n_tokens < t0 + 2 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "action profile encap vxlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: offset");
- return;
- }
-
- if (parser_read_uint32(&p.encap.vxlan.data_offset,
- tokens[t0 + 2 + 1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ether_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 2], "ipv4") == 0)
- p.encap.vxlan.ip_version = 1;
- else if (strcmp(tokens[t0 + 2 + 2], "ipv6") == 0)
- p.encap.vxlan.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 3], "vlan") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "vxlan: vlan");
- return;
- }
-
- if (strcmp(tokens[t0 + 2 + 4], "on") == 0)
- p.encap.vxlan.vlan = 1;
- else if (strcmp(tokens[t0 + 2 + 4], "off") == 0)
- p.encap.vxlan.vlan = 0;
- else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "vxlan: on or off");
- return;
- }
-
- p.encap.encap_mask = 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN;
- n_extra_tokens = 5;
- } else if (strcmp(tokens[t0 + 1], "qinq_pppoe") == 0)
- p.encap.encap_mask =
- 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
- t0 += 2 + n_extra_tokens;
- } /* encap */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "nat") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile nat");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "src") == 0)
- p.nat.source_nat = 1;
- else if (strcmp(tokens[t0 + 1], "dst") == 0)
- p.nat.source_nat = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "src or dst");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "proto") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "proto");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "tcp") == 0)
- p.nat.proto = 0x06;
- else if (strcmp(tokens[t0 + 3], "udp") == 0)
- p.nat.proto = 0x11;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "tcp or udp");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_NAT;
- t0 += 4;
- } /* nat */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "ttl") == 0)) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile ttl");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "drop") == 0)
- p.ttl.drop = 1;
- else if (strcmp(tokens[t0 + 1], "fwd") == 0)
- p.ttl.drop = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "drop or fwd");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "none") == 0)
- p.ttl.n_packets_enabled = 0;
- else if (strcmp(tokens[t0 + 3], "pkts") == 0)
- p.ttl.n_packets_enabled = 1;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "none or pkts");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TTL;
- t0 += 4;
- } /* ttl */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "stats") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile stats");
- return;
- }
-
- if (strcmp(tokens[t0 + 1], "pkts") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 0;
- } else if (strcmp(tokens[t0 + 1], "bytes") == 0) {
- p.stats.n_packets_enabled = 0;
- p.stats.n_bytes_enabled = 1;
- } else if (strcmp(tokens[t0 + 1], "both") == 0) {
- p.stats.n_packets_enabled = 1;
- p.stats.n_bytes_enabled = 1;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "pkts or bytes or both");
- return;
- }
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_STATS;
- t0 += 2;
- } /* stats */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "time") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TIME;
- t0 += 1;
- } /* time */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "sym_crypto") == 0)) {
- struct cryptodev *cryptodev;
-
- if (n_tokens < t0 + 5 ||
- strcmp(tokens[t0 + 1], "dev") ||
- strcmp(tokens[t0 + 3], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "table action profile sym_crypto");
- return;
- }
-
- cryptodev = cryptodev_find(tokens[t0 + 2]);
- if (cryptodev == NULL) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.cryptodev_id = cryptodev->dev_id;
-
- if (parser_read_uint32(&p.sym_crypto.op_offset,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "table action profile sym_crypto");
- return;
- }
-
- p.sym_crypto.mp_create = cryptodev->mp_create;
- p.sym_crypto.mp_init = cryptodev->mp_init;
-
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- t0 += 5;
- } /* sym_crypto */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "tag") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_TAG;
- t0 += 1;
- } /* tag */
-
- if ((t0 < n_tokens) && (strcmp(tokens[t0], "decap") == 0)) {
- p.action_mask |= 1LLU << RTE_TABLE_ACTION_DECAP;
- t0 += 1;
- } /* decap */
-
- if (t0 < n_tokens) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- ap = table_action_profile_create(name, &p);
- if (ap == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_help[] =
-"pipeline <pipeline_name>\n"
-" period <timer_period_ms>\n"
-" offset_port_id <offset_port_id>\n"
-" cpu <cpu_id>\n";
-
-static void
-cmd_pipeline(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct pipeline_params p;
- char *name;
- struct pipeline *pipeline;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- name = tokens[1];
-
- if (strcmp(tokens[2], "period") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period");
- return;
- }
-
- if (parser_read_uint32(&p.timer_period_ms, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms");
- return;
- }
-
- if (strcmp(tokens[4], "offset_port_id") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset_port_id");
- return;
- }
-
- if (parser_read_uint32(&p.offset_port_id, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "offset_port_id");
- return;
- }
-
- if (strcmp(tokens[6], "cpu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
- return;
- }
-
- if (parser_read_uint32(&p.cpu_id, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id");
- return;
- }
-
- pipeline = pipeline_create(name, &p);
- if (pipeline == NULL) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_help[] =
-"pipeline <pipeline_name> port in\n"
-" bsz <burst_size>\n"
-" link <link_name> rxq <queue_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name> mempool <mempool_name> mtu <mtu>\n"
-" | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\n"
-" | cryptodev <cryptodev_name> rxq <queue_id>\n"
-" [action <port_in_action_profile_name>]\n"
-" [disabled]\n";
-
-static void
-cmd_pipeline_port_in(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_in_params p;
- char *pipeline_name;
- uint32_t t0;
- int enabled, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- t0 = 6;
-
- if (strcmp(tokens[t0], "link") == 0) {
- if (n_tokens < t0 + 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in link");
- return;
- }
-
- p.type = PORT_IN_RXQ;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "rxq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rxq");
- return;
- }
-
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "queue_id");
- return;
- }
- t0 += 4;
- } else if (strcmp(tokens[t0], "swq") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in swq");
- return;
- }
-
- p.type = PORT_IN_SWQ;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tmgr") == 0) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tmgr");
- return;
- }
-
- p.type = PORT_IN_TMGR;
-
- p.dev_name = tokens[t0 + 1];
-
- t0 += 2;
- } else if (strcmp(tokens[t0], "tap") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in tap");
- return;
- }
-
- p.type = PORT_IN_TAP;
-
- p.dev_name = tokens[t0 + 1];
-
- if (strcmp(tokens[t0 + 2], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.tap.mempool_name = tokens[t0 + 3];
-
- if (strcmp(tokens[t0 + 4], "mtu") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mtu");
- return;
- }
-
- if (parser_read_uint32(&p.tap.mtu, tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "source") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in source");
- return;
- }
-
- p.type = PORT_IN_SOURCE;
-
- p.dev_name = NULL;
-
- if (strcmp(tokens[t0 + 1], "mempool") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "mempool");
- return;
- }
-
- p.source.mempool_name = tokens[t0 + 2];
-
- if (strcmp(tokens[t0 + 3], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.source.file_name = tokens[t0 + 4];
-
- if (strcmp(tokens[t0 + 5], "bpp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "bpp");
- return;
- }
-
- if (parser_read_uint32(&p.source.n_bytes_per_pkt, tokens[t0 + 6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "n_bytes_per_pkt");
- return;
- }
-
- t0 += 7;
- } else if (strcmp(tokens[t0], "cryptodev") == 0) {
- if (n_tokens < t0 + 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port in cryptodev");
- return;
- }
-
- p.type = PORT_IN_CRYPTODEV;
-
- p.dev_name = tokens[t0 + 1];
- if (parser_read_uint16(&p.rxq.queue_id, tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "rxq");
- return;
- }
-
- p.cryptodev.arg_callback = NULL;
- p.cryptodev.f_callback = NULL;
-
- t0 += 4;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- enabled = 1;
- if ((n_tokens > t0) &&
- (strcmp(tokens[t0], "disabled") == 0)) {
- enabled = 0;
-
- t0 += 1;
- }
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_port_in_create(pipeline_name,
- &p, enabled);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_out_help[] =
-"pipeline <pipeline_name> port out\n"
-" bsz <burst_size>\n"
-" link <link_name> txq <txq_id>\n"
-" | swq <swq_name>\n"
-" | tmgr <tmgr_name>\n"
-" | tap <tap_name>\n"
-" | sink [file <file_name> pkts <max_n_pkts>]\n"
-" | cryptodev <cryptodev_name> txq <txq_id> offset <crypto_op_offset>\n";
-
-static void
-cmd_pipeline_port_out(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct port_out_params p;
- char *pipeline_name;
- int status;
-
- memset(&p, 0, sizeof(p));
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (strcmp(tokens[4], "bsz") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz");
- return;
- }
-
- if (parser_read_uint32(&p.burst_size, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "burst_size");
- return;
- }
-
- if (strcmp(tokens[6], "link") == 0) {
- if (n_tokens != 10) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out link");
- return;
- }
-
- p.type = PORT_OUT_TXQ;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "txq");
- return;
- }
-
- if (parser_read_uint16(&p.txq.queue_id, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else if (strcmp(tokens[6], "swq") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out swq");
- return;
- }
-
- p.type = PORT_OUT_SWQ;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tmgr") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tmgr");
- return;
- }
-
- p.type = PORT_OUT_TMGR;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "tap") == 0) {
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out tap");
- return;
- }
-
- p.type = PORT_OUT_TAP;
-
- p.dev_name = tokens[7];
- } else if (strcmp(tokens[6], "sink") == 0) {
- if ((n_tokens != 7) && (n_tokens != 11)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out sink");
- return;
- }
-
- p.type = PORT_OUT_SINK;
-
- p.dev_name = NULL;
-
- if (n_tokens == 7) {
- p.sink.file_name = NULL;
- p.sink.max_n_pkts = 0;
- } else {
- if (strcmp(tokens[7], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "file");
- return;
- }
-
- p.sink.file_name = tokens[8];
-
- if (strcmp(tokens[9], "pkts") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkts");
- return;
- }
-
- if (parser_read_uint32(&p.sink.max_n_pkts, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "max_n_pkts");
- return;
- }
- }
-
- } else if (strcmp(tokens[6], "cryptodev") == 0) {
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- p.type = PORT_OUT_CRYPTODEV;
-
- p.dev_name = tokens[7];
-
- if (strcmp(tokens[8], "txq")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint16(&p.cryptodev.queue_id, tokens[9])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
-
- if (strcmp(tokens[10], "offset")) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline port out cryptodev");
- return;
- }
-
- if (parser_read_uint32(&p.cryptodev.op_offset, tokens[11])
- != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "queue_id");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_port_out_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_help[] =
-"pipeline <pipeline_name> table\n"
-" match\n"
-" acl\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | array\n"
-" offset <key_offset>\n"
-" size <n_keys>\n"
-" | hash\n"
-" ext | lru\n"
-" key <key_size>\n"
-" mask <key_mask>\n"
-" offset <key_offset>\n"
-" buckets <n_buckets>\n"
-" size <n_keys>\n"
-" | lpm\n"
-" ipv4 | ipv6\n"
-" offset <ip_header_offset>\n"
-" size <n_rules>\n"
-" | stub\n"
-" [action <table_action_profile_name>]\n";
-
-static void
-cmd_pipeline_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
- struct table_params p;
- char *pipeline_name;
- uint32_t t0;
- int status;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (strcmp(tokens[3], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- t0 = 4;
- if (strcmp(tokens[t0], "acl") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table acl");
- return;
- }
-
- p.match_type = TABLE_ACL;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.acl.ip_version = 1;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.acl.ip_version = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.ip_header_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "ip_header_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.acl.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "array") == 0) {
- if (n_tokens < t0 + 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table array");
- return;
- }
-
- p.match_type = TABLE_ARRAY;
-
- if (strcmp(tokens[t0 + 1], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.key_offset,
- tokens[t0 + 2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 3], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.array.n_keys,
- tokens[t0 + 4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 5;
- } else if (strcmp(tokens[t0], "hash") == 0) {
- uint32_t key_mask_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < t0 + 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table hash");
- return;
- }
-
- p.match_type = TABLE_HASH;
-
- if (strcmp(tokens[t0 + 1], "ext") == 0)
- p.match.hash.extendable_bucket = 1;
- else if (strcmp(tokens[t0 + 1], "lru") == 0)
- p.match.hash.extendable_bucket = 0;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ext or lru");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "key") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "key");
- return;
- }
-
- if ((parser_read_uint32(&p.match.hash.key_size,
- tokens[t0 + 3]) != 0) ||
- (p.match.hash.key_size == 0) ||
- (p.match.hash.key_size > TABLE_RULE_MATCH_SIZE_MAX)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_size");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "mask") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mask");
- return;
- }
-
- if ((parse_hex_string(tokens[t0 + 5],
- key_mask, &key_mask_size) != 0) ||
- (key_mask_size != p.match.hash.key_size)) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_mask");
- return;
- }
- p.match.hash.key_mask = key_mask;
-
- if (strcmp(tokens[t0 + 6], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.key_offset,
- tokens[t0 + 7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 8], "buckets") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buckets");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_buckets,
- tokens[t0 + 9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_buckets");
- return;
- }
-
- if (strcmp(tokens[t0 + 10], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.hash.n_keys,
- tokens[t0 + 11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_keys");
- return;
- }
-
- t0 += 12;
- } else if (strcmp(tokens[t0], "lpm") == 0) {
- if (n_tokens < t0 + 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "pipeline table lpm");
- return;
- }
-
- p.match_type = TABLE_LPM;
-
- if (strcmp(tokens[t0 + 1], "ipv4") == 0)
- p.match.lpm.key_size = 4;
- else if (strcmp(tokens[t0 + 1], "ipv6") == 0)
- p.match.lpm.key_size = 16;
- else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return;
- }
-
- if (strcmp(tokens[t0 + 2], "offset") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "offset");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.key_offset,
- tokens[t0 + 3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key_offset");
- return;
- }
-
- if (strcmp(tokens[t0 + 4], "size") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size");
- return;
- }
-
- if (parser_read_uint32(&p.match.lpm.n_rules,
- tokens[t0 + 5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
- return;
- }
-
- t0 += 6;
- } else if (strcmp(tokens[t0], "stub") == 0) {
- p.match_type = TABLE_STUB;
-
- t0 += 1;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- p.action_profile_name = NULL;
- if ((n_tokens > t0) && (strcmp(tokens[t0], "action") == 0)) {
- if (n_tokens < t0 + 2) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, "action");
- return;
- }
-
- p.action_profile_name = tokens[t0 + 1];
-
- t0 += 2;
- }
-
- if (n_tokens > t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_create(pipeline_name, &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_port_in_table_help[] =
-"pipeline <pipeline_name> port in <port_id> table <table_id>\n";
-
-static void
-cmd_pipeline_port_in_table(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id, table_id;
- int status;
-
- if (n_tokens != 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- status = pipeline_port_in_connect_to_table(pipeline_name,
- port_id,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_stats_help[] =
-"pipeline <pipeline_name> port in <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_IN_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_in_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_in_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_in_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_IN_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_port_in_enable_help[] =
-"pipeline <pipeline_name> port in <port_id> enable\n";
-
-static void
-cmd_pipeline_port_in_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = pipeline_port_in_enable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_in_disable_help[] =
-"pipeline <pipeline_name> port in <port_id> disable\n";
-
-static void
-cmd_pipeline_port_in_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t port_id;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "in") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = pipeline_port_in_disable(pipeline_name, port_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_port_out_stats_help[] =
-"pipeline <pipeline_name> port out <port_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_PORT_OUT_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts dropped by AH: %" PRIu64 "\n" \
- "Pkts dropped by other: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_port_out_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_port_out_stats stats;
- char *pipeline_name;
- uint32_t port_id;
- int clear, status;
-
- if ((n_tokens != 7) && (n_tokens != 8)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "port") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (strcmp(tokens[3], "out") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- if (strcmp(tokens[5], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[6], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 8) {
- if (strcmp(tokens[7], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_port_out_stats_read(pipeline_name,
- port_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_PORT_OUT_STATS,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-
-static const char cmd_pipeline_table_stats_help[] =
-"pipeline <pipeline_name> table <table_id> stats read [clear]\n";
-
-#define MSG_PIPELINE_TABLE_STATS \
- "Pkts in: %" PRIu64 "\n" \
- "Pkts in with lookup miss: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup hit dropped by others: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by AH: %" PRIu64 "\n" \
- "Pkts in with lookup miss dropped by others: %" PRIu64 "\n"
-
-static void
-cmd_pipeline_table_stats(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_pipeline_table_stats stats;
- char *pipeline_name;
- uint32_t table_id;
- int clear, status;
-
- if ((n_tokens != 6) && (n_tokens != 7)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- clear = 0;
- if (n_tokens == 7) {
- if (strcmp(tokens[6], "clear") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "clear");
- return;
- }
-
- clear = 1;
- }
-
- status = pipeline_table_stats_read(pipeline_name,
- table_id,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, MSG_PIPELINE_TABLE_STATS,
- stats.stats.n_pkts_in,
- stats.stats.n_pkts_lookup_miss,
- stats.n_pkts_dropped_by_lkp_hit_ah,
- stats.n_pkts_dropped_lkp_hit,
- stats.n_pkts_dropped_by_lkp_miss_ah,
- stats.n_pkts_dropped_lkp_miss);
-}
-
-/**
- * <match> ::=
- *
- * match
- * acl
- * priority <priority>
- * ipv4 | ipv6 <sa> <sa_depth> <da> <da_depth>
- * <sp0> <sp1> <dp0> <dp1> <proto>
- * | array <pos>
- * | hash
- * raw <key>
- * | ipv4_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv6_5tuple <sa> <da> <sp> <dp> <proto>
- * | ipv4_addr <addr>
- * | ipv6_addr <addr>
- * | qinq <svlan> <cvlan>
- * | lpm
- * ipv4 | ipv6 <addr> <depth>
- */
-struct pkt_key_qinq {
- uint16_t ethertype_svlan;
- uint16_t svlan;
- uint16_t ethertype_cvlan;
- uint16_t cvlan;
-};
-
-struct pkt_key_ipv4_5tuple {
- uint8_t time_to_live;
- uint8_t proto;
- uint16_t hdr_checksum;
- uint32_t sa;
- uint32_t da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv6_5tuple {
- uint16_t payload_length;
- uint8_t proto;
- uint8_t hop_limit;
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- uint16_t sp;
- uint16_t dp;
-};
-
-struct pkt_key_ipv4_addr {
- uint32_t addr;
-};
-
-struct pkt_key_ipv6_addr {
- struct rte_ipv6_addr addr;
-};
-
-static uint32_t
-parse_match(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_match *m)
-{
- memset(m, 0, sizeof(*m));
-
- if (n_tokens < 2)
- return 0;
-
- if (strcmp(tokens[0], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return 0;
- }
-
- if (strcmp(tokens[1], "acl") == 0) {
- if (n_tokens < 14) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ACL;
-
- if (strcmp(tokens[2], "priority") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "priority");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.priority,
- tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "priority");
- return 0;
- }
-
- if (strcmp(tokens[4], "ipv4") == 0) {
- struct in_addr saddr, daddr;
-
- m->match.acl.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv4.sa = rte_be_to_cpu_32(saddr.s_addr);
-
- if (parse_ipv4_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv4.da = rte_be_to_cpu_32(daddr.s_addr);
- } else if (strcmp(tokens[4], "ipv6") == 0) {
- struct rte_ipv6_addr saddr, daddr;
-
- m->match.acl.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[5], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
- m->match.acl.ipv6.sa = saddr;
-
- if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
- m->match.acl.ipv6.da = daddr;
- } else {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.sa_depth,
- tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa_depth");
- return 0;
- }
-
- if (parser_read_uint32(&m->match.acl.da_depth,
- tokens[8]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da_depth");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp0, tokens[9]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.sp1, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp1");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp0, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp0");
- return 0;
- }
-
- if (parser_read_uint16(&m->match.acl.dp1, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp1");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.acl.proto, tokens[13]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "proto");
- return 0;
- }
-
- m->match.acl.proto_mask = 0xff;
-
- return 14;
- } /* acl */
-
- if (strcmp(tokens[1], "array") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_ARRAY;
-
- if (parser_read_uint32(&m->match.array.pos, tokens[2]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pos");
- return 0;
- }
-
- return 3;
- } /* array */
-
- if (strcmp(tokens[1], "hash") == 0) {
- if (n_tokens < 3) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_HASH;
-
- if (strcmp(tokens[2], "raw") == 0) {
- uint32_t key_size = TABLE_RULE_MATCH_SIZE_MAX;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_hex_string(tokens[3],
- m->match.hash.key, &key_size) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "key");
- return 0;
- }
-
- return 4;
- } /* hash raw */
-
- if (strcmp(tokens[2], "ipv4_5tuple") == 0) {
- struct pkt_key_ipv4_5tuple *ipv4 =
- (struct pkt_key_ipv4_5tuple *) m->match.hash.key;
- struct in_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv4->sa = saddr.s_addr;
- ipv4->da = daddr.s_addr;
- ipv4->sp = rte_cpu_to_be_16(sp);
- ipv4->dp = rte_cpu_to_be_16(dp);
- ipv4->proto = proto;
-
- return 8;
- } /* hash ipv4_5tuple */
-
- if (strcmp(tokens[2], "ipv6_5tuple") == 0) {
- struct pkt_key_ipv6_5tuple *ipv6 =
- (struct pkt_key_ipv6_5tuple *) m->match.hash.key;
- struct rte_ipv6_addr saddr, daddr;
- uint16_t sp, dp;
- uint8_t proto;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &saddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sa");
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[4], &daddr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "da");
- return 0;
- }
-
- if (parser_read_uint16(&sp, tokens[5]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "sp");
- return 0;
- }
-
- if (parser_read_uint16(&dp, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "dp");
- return 0;
- }
-
- if (parser_read_uint8(&proto, tokens[7]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "proto");
- return 0;
- }
-
- ipv6->sa = saddr;
- ipv6->da = daddr;
- ipv6->sp = rte_cpu_to_be_16(sp);
- ipv6->dp = rte_cpu_to_be_16(dp);
- ipv6->proto = proto;
-
- return 8;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "ipv4_addr") == 0) {
- struct pkt_key_ipv4_addr *ipv4_addr =
- (struct pkt_key_ipv4_addr *) m->match.hash.key;
- struct in_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv4_addr->addr = addr.s_addr;
-
- return 4;
- } /* hash ipv4_addr */
-
- if (strcmp(tokens[2], "ipv6_addr") == 0) {
- struct pkt_key_ipv6_addr *ipv6_addr =
- (struct pkt_key_ipv6_addr *) m->match.hash.key;
- struct rte_ipv6_addr addr;
-
- if (n_tokens < 4) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- ipv6_addr->addr = addr;
-
- return 4;
- } /* hash ipv6_5tuple */
-
- if (strcmp(tokens[2], "qinq") == 0) {
- struct pkt_key_qinq *qinq =
- (struct pkt_key_qinq *) m->match.hash.key;
- uint16_t svlan, cvlan;
-
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return 0;
- }
-
- if ((parser_read_uint16(&svlan, tokens[3]) != 0) ||
- (svlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "svlan");
- return 0;
- }
-
- if ((parser_read_uint16(&cvlan, tokens[4]) != 0) ||
- (cvlan > 0xFFF)) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "cvlan");
- return 0;
- }
-
- qinq->svlan = rte_cpu_to_be_16(svlan);
- qinq->cvlan = rte_cpu_to_be_16(cvlan);
-
- return 5;
- } /* hash qinq */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- } /* hash */
-
- if (strcmp(tokens[1], "lpm") == 0) {
- if (n_tokens < 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return 0;
- }
-
- m->match_type = TABLE_LPM;
-
- if (strcmp(tokens[2], "ipv4") == 0) {
- struct in_addr addr;
-
- m->match.lpm.ip_version = 1;
-
- if (parse_ipv4_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- } else if (strcmp(tokens[2], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
-
- m->match.lpm.ip_version = 0;
-
- if (parse_ipv6_addr(tokens[3], &addr) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "addr");
- return 0;
- }
-
- m->match.lpm.ipv6 = addr;
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "ipv4 or ipv6");
- return 0;
- }
-
- if (parser_read_uint8(&m->match.lpm.depth, tokens[4]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "depth");
- return 0;
- }
-
- return 5;
- } /* lpm */
-
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- "acl or array or hash or lpm");
- return 0;
-}
-
-/**
- * table_action ::=
- *
- * action
- * fwd
- * drop
- * | port <port_id>
- * | meta
- * | table <table_id>
- * [balance <out0> ... <out7>]
- * [meter
- * tc0 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * [tc1 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc2 meter <meter_profile_id> policer g <pa> y <pa> r <pa>
- * tc3 meter <meter_profile_id> policer g <pa> y <pa> r <pa>]]
- * [tm subport <subport_id> pipe <pipe_id>]
- * [encap
- * ether <da> <sa>
- * | vlan <da> <sa> <pcp> <dei> <vid>
- * | qinq <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid>
- * | qinq_pppoe <da> <sa> <pcp> <dei> <vid> <pcp> <dei> <vid> <session_id>
- * | mpls unicast | multicast
- * <da> <sa>
- * label0 <label> <tc> <ttl>
- * [label1 <label> <tc> <ttl>
- * [label2 <label> <tc> <ttl>
- * [label3 <label> <tc> <ttl>]]]
- * | pppoe <da> <sa> <session_id>
- * | vxlan ether <da> <sa>
- * [vlan <pcp> <dei> <vid>]
- * ipv4 <sa> <da> <dscp> <ttl>
- * | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit>
- * udp <sp> <dp>
- * vxlan <vni>]
- * [nat ipv4 | ipv6 <addr> <port>]
- * [ttl dec | keep]
- * [stats]
- * [time]
- * [sym_crypto
- * encrypt | decrypt
- * type
- * | cipher
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * | cipher_auth
- * cipher_algo <algo> cipher_key <key> cipher_iv <iv>
- * auth_algo <algo> auth_key <key> digest_size <size>
- * | aead
- * aead_algo <algo> aead_key <key> aead_iv <iv> aead_aad <aad>
- * digest_size <size>
- * data_offset <data_offset>]
- * [tag <tag>]
- * [decap <n>]
- *
- * where:
- * <pa> ::= g | y | r | drop
- */
-static uint32_t
-parse_table_action_fwd(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || (strcmp(tokens[0], "fwd") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "drop") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_DROP;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "port") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_PORT;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meta") == 0)) {
- a->fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 1;
- }
-
- if (n_tokens && (strcmp(tokens[0], "table") == 0)) {
- uint32_t id;
-
- if ((n_tokens < 2) ||
- parser_read_uint32(&id, tokens[1]))
- return 0;
-
- a->fwd.action = RTE_PIPELINE_ACTION_TABLE;
- a->fwd.id = id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_FWD;
- return 1 + 2;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_balance(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t i;
-
- if ((n_tokens == 0) || (strcmp(tokens[0], "balance") != 0))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens < RTE_TABLE_ACTION_LB_TABLE_SIZE)
- return 0;
-
- for (i = 0; i < RTE_TABLE_ACTION_LB_TABLE_SIZE; i++)
- if (parser_read_uint32(&a->lb.out[i], tokens[i]) != 0)
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_LB;
- return 1 + RTE_TABLE_ACTION_LB_TABLE_SIZE;
-
-}
-
-static int
-parse_policer_action(char *token, enum rte_table_action_policer *a)
-{
- if (strcmp(token, "g") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_GREEN;
- return 0;
- }
-
- if (strcmp(token, "y") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_YELLOW;
- return 0;
- }
-
- if (strcmp(token, "r") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_COLOR_RED;
- return 0;
- }
-
- if (strcmp(token, "drop") == 0) {
- *a = RTE_TABLE_ACTION_POLICER_DROP;
- return 0;
- }
-
- return -1;
-}
-
-static uint32_t
-parse_table_action_meter_tc(char **tokens,
- uint32_t n_tokens,
- struct rte_table_action_mtr_tc_params *mtr)
-{
- if ((n_tokens < 9) ||
- strcmp(tokens[0], "meter") ||
- parser_read_uint32(&mtr->meter_profile_id, tokens[1]) ||
- strcmp(tokens[2], "policer") ||
- strcmp(tokens[3], "g") ||
- parse_policer_action(tokens[4], &mtr->policer[RTE_COLOR_GREEN]) ||
- strcmp(tokens[5], "y") ||
- parse_policer_action(tokens[6], &mtr->policer[RTE_COLOR_YELLOW]) ||
- strcmp(tokens[7], "r") ||
- parse_policer_action(tokens[8], &mtr->policer[RTE_COLOR_RED]))
- return 0;
-
- return 9;
-}
-
-static uint32_t
-parse_table_action_meter(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "meter"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if ((n_tokens < 10) ||
- strcmp(tokens[0], "tc0") ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1,
- &a->mtr.mtr[0]) == 0))
- return 0;
-
- tokens += 10;
- n_tokens -= 10;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "tc1")) {
- a->mtr.tc_mask = 1;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10;
- }
-
- if ((n_tokens < 30) ||
- (parse_table_action_meter_tc(tokens + 1,
- n_tokens - 1, &a->mtr.mtr[1]) == 0) ||
- strcmp(tokens[10], "tc2") ||
- (parse_table_action_meter_tc(tokens + 11,
- n_tokens - 11, &a->mtr.mtr[2]) == 0) ||
- strcmp(tokens[20], "tc3") ||
- (parse_table_action_meter_tc(tokens + 21,
- n_tokens - 21, &a->mtr.mtr[3]) == 0))
- return 0;
-
- a->mtr.tc_mask = 0xF;
- a->action_mask |= 1 << RTE_TABLE_ACTION_MTR;
- return 1 + 10 + 3 * 10;
-}
-
-static uint32_t
-parse_table_action_tm(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- uint32_t subport_id, pipe_id;
-
- if ((n_tokens < 5) ||
- strcmp(tokens[0], "tm") ||
- strcmp(tokens[1], "subport") ||
- parser_read_uint32(&subport_id, tokens[2]) ||
- strcmp(tokens[3], "pipe") ||
- parser_read_uint32(&pipe_id, tokens[4]))
- return 0;
-
- a->tm.subport_id = subport_id;
- a->tm.pipe_id = pipe_id;
- a->action_mask |= 1 << RTE_TABLE_ACTION_TM;
- return 5;
-}
-
-static uint32_t
-parse_table_action_encap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens == 0) || strcmp(tokens[0], "encap"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- /* ether */
- if (n_tokens && (strcmp(tokens[0], "ether") == 0)) {
- if ((n_tokens < 3) ||
- parse_mac_addr(tokens[1], &a->encap.ether.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.ether.ether.sa))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_ETHER;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 3;
- }
-
- /* vlan */
- if (n_tokens && (strcmp(tokens[0], "vlan") == 0)) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 6) ||
- parse_mac_addr(tokens[1], &a->encap.vlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vlan.ether.sa) ||
- parser_read_uint32(&pcp, tokens[3]) ||
- (pcp > 0x7) ||
- parser_read_uint32(&dei, tokens[4]) ||
- (dei > 0x1) ||
- parser_read_uint32(&vid, tokens[5]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vlan.vlan.pcp = pcp & 0x7;
- a->encap.vlan.vlan.dei = dei & 0x1;
- a->encap.vlan.vlan.vid = vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 6;
- }
-
- /* qinq */
- if (n_tokens && (strcmp(tokens[0], "qinq") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 9) ||
- parse_mac_addr(tokens[1], &a->encap.qinq.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.qinq.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF))
- return 0;
-
- a->encap.qinq.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 9;
- }
-
- /* qinq_pppoe */
- if (n_tokens && (strcmp(tokens[0], "qinq_pppoe") == 0)) {
- uint32_t svlan_pcp, svlan_dei, svlan_vid;
- uint32_t cvlan_pcp, cvlan_dei, cvlan_vid;
-
- if ((n_tokens < 10) ||
- parse_mac_addr(tokens[1],
- &a->encap.qinq_pppoe.ether.da) ||
- parse_mac_addr(tokens[2],
- &a->encap.qinq_pppoe.ether.sa) ||
- parser_read_uint32(&svlan_pcp, tokens[3]) ||
- (svlan_pcp > 0x7) ||
- parser_read_uint32(&svlan_dei, tokens[4]) ||
- (svlan_dei > 0x1) ||
- parser_read_uint32(&svlan_vid, tokens[5]) ||
- (svlan_vid > 0xFFF) ||
- parser_read_uint32(&cvlan_pcp, tokens[6]) ||
- (cvlan_pcp > 0x7) ||
- parser_read_uint32(&cvlan_dei, tokens[7]) ||
- (cvlan_dei > 0x1) ||
- parser_read_uint32(&cvlan_vid, tokens[8]) ||
- (cvlan_vid > 0xFFF) ||
- parser_read_uint16(&a->encap.qinq_pppoe.pppoe.session_id,
- tokens[9]))
- return 0;
-
- a->encap.qinq_pppoe.svlan.pcp = svlan_pcp & 0x7;
- a->encap.qinq_pppoe.svlan.dei = svlan_dei & 0x1;
- a->encap.qinq_pppoe.svlan.vid = svlan_vid & 0xFFF;
- a->encap.qinq_pppoe.cvlan.pcp = cvlan_pcp & 0x7;
- a->encap.qinq_pppoe.cvlan.dei = cvlan_dei & 0x1;
- a->encap.qinq_pppoe.cvlan.vid = cvlan_vid & 0xFFF;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 10;
-
- }
-
- /* mpls */
- if (n_tokens && (strcmp(tokens[0], "mpls") == 0)) {
- uint32_t label, tc, ttl;
-
- if (n_tokens < 8)
- return 0;
-
- if (strcmp(tokens[1], "unicast") == 0)
- a->encap.mpls.unicast = 1;
- else if (strcmp(tokens[1], "multicast") == 0)
- a->encap.mpls.unicast = 0;
- else
- return 0;
-
- if (parse_mac_addr(tokens[2], &a->encap.mpls.ether.da) ||
- parse_mac_addr(tokens[3], &a->encap.mpls.ether.sa) ||
- strcmp(tokens[4], "label0") ||
- parser_read_uint32(&label, tokens[5]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[6]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[7]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[0].label = label;
- a->encap.mpls.mpls[0].tc = tc;
- a->encap.mpls.mpls[0].ttl = ttl;
-
- tokens += 8;
- n_tokens -= 8;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label1")) {
- a->encap.mpls.mpls_count = 1;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[1].label = label;
- a->encap.mpls.mpls[1].tc = tc;
- a->encap.mpls.mpls[1].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label2")) {
- a->encap.mpls.mpls_count = 2;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[2].label = label;
- a->encap.mpls.mpls[2].tc = tc;
- a->encap.mpls.mpls[2].ttl = ttl;
-
- tokens += 4;
- n_tokens -= 4;
-
- if ((n_tokens == 0) || strcmp(tokens[0], "label3")) {
- a->encap.mpls.mpls_count = 3;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4;
- }
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&label, tokens[1]) ||
- (label > 0xFFFFF) ||
- parser_read_uint32(&tc, tokens[2]) ||
- (tc > 0x7) ||
- parser_read_uint32(&ttl, tokens[3]) ||
- (ttl > 0x3F))
- return 0;
-
- a->encap.mpls.mpls[3].label = label;
- a->encap.mpls.mpls[3].tc = tc;
- a->encap.mpls.mpls[3].ttl = ttl;
-
- a->encap.mpls.mpls_count = 4;
- a->encap.type = RTE_TABLE_ACTION_ENCAP_MPLS;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 8 + 4 + 4 + 4;
- }
-
- /* pppoe */
- if (n_tokens && (strcmp(tokens[0], "pppoe") == 0)) {
- if ((n_tokens < 4) ||
- parse_mac_addr(tokens[1], &a->encap.pppoe.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.pppoe.ether.sa) ||
- parser_read_uint16(&a->encap.pppoe.pppoe.session_id,
- tokens[3]))
- return 0;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_PPPOE;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + 4;
- }
-
- /* vxlan */
- if (n_tokens && (strcmp(tokens[0], "vxlan") == 0)) {
- uint32_t n = 0;
-
- n_tokens--;
- tokens++;
- n++;
-
- /* ether <da> <sa> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "ether") ||
- parse_mac_addr(tokens[1], &a->encap.vxlan.ether.da) ||
- parse_mac_addr(tokens[2], &a->encap.vxlan.ether.sa))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* [vlan <pcp> <dei> <vid>] */
- if (strcmp(tokens[0], "vlan") == 0) {
- uint32_t pcp, dei, vid;
-
- if ((n_tokens < 4) ||
- parser_read_uint32(&pcp, tokens[1]) ||
- (pcp > 7) ||
- parser_read_uint32(&dei, tokens[2]) ||
- (dei > 1) ||
- parser_read_uint32(&vid, tokens[3]) ||
- (vid > 0xFFF))
- return 0;
-
- a->encap.vxlan.vlan.pcp = pcp;
- a->encap.vxlan.vlan.dei = dei;
- a->encap.vxlan.vlan.vid = vid;
-
- n_tokens -= 4;
- tokens += 4;
- n += 4;
- }
-
- /* ipv4 <sa> <da> <dscp> <ttl>
- | ipv6 <sa> <da> <flow_label> <dscp> <hop_limit> */
- if (strcmp(tokens[0], "ipv4") == 0) {
- struct in_addr sa, da;
- uint8_t dscp, ttl;
-
- if ((n_tokens < 5) ||
- parse_ipv4_addr(tokens[1], &sa) ||
- parse_ipv4_addr(tokens[2], &da) ||
- parser_read_uint8(&dscp, tokens[3]) ||
- (dscp > 64) ||
- parser_read_uint8(&ttl, tokens[4]))
- return 0;
-
- a->encap.vxlan.ipv4.sa = rte_be_to_cpu_32(sa.s_addr);
- a->encap.vxlan.ipv4.da = rte_be_to_cpu_32(da.s_addr);
- a->encap.vxlan.ipv4.dscp = dscp;
- a->encap.vxlan.ipv4.ttl = ttl;
-
- n_tokens -= 5;
- tokens += 5;
- n += 5;
- } else if (strcmp(tokens[0], "ipv6") == 0) {
- struct rte_ipv6_addr sa, da;
- uint32_t flow_label;
- uint8_t dscp, hop_limit;
-
- if ((n_tokens < 6) ||
- parse_ipv6_addr(tokens[1], &sa) ||
- parse_ipv6_addr(tokens[2], &da) ||
- parser_read_uint32(&flow_label, tokens[3]) ||
- parser_read_uint8(&dscp, tokens[4]) ||
- (dscp > 64) ||
- parser_read_uint8(&hop_limit, tokens[5]))
- return 0;
-
- a->encap.vxlan.ipv6.sa = sa;
- a->encap.vxlan.ipv6.da = da;
- a->encap.vxlan.ipv6.flow_label = flow_label;
- a->encap.vxlan.ipv6.dscp = dscp;
- a->encap.vxlan.ipv6.hop_limit = hop_limit;
-
- n_tokens -= 6;
- tokens += 6;
- n += 6;
- } else
- return 0;
-
- /* udp <sp> <dp> */
- if ((n_tokens < 3) ||
- strcmp(tokens[0], "udp") ||
- parser_read_uint16(&a->encap.vxlan.udp.sp, tokens[1]) ||
- parser_read_uint16(&a->encap.vxlan.udp.dp, tokens[2]))
- return 0;
-
- n_tokens -= 3;
- tokens += 3;
- n += 3;
-
- /* vxlan <vni> */
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "vxlan") ||
- parser_read_uint32(&a->encap.vxlan.vxlan.vni, tokens[1]) ||
- (a->encap.vxlan.vxlan.vni > 0xFFFFFF))
- return 0;
-
- n_tokens -= 2;
- tokens += 2;
- n += 2;
-
- a->encap.type = RTE_TABLE_ACTION_ENCAP_VXLAN;
- a->action_mask |= 1 << RTE_TABLE_ACTION_ENCAP;
- return 1 + n;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_nat(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 4) ||
- strcmp(tokens[0], "nat"))
- return 0;
-
- if (strcmp(tokens[1], "ipv4") == 0) {
- struct in_addr addr;
- uint16_t port;
-
- if (parse_ipv4_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 1;
- a->nat.addr.ipv4 = rte_be_to_cpu_32(addr.s_addr);
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- if (strcmp(tokens[1], "ipv6") == 0) {
- struct rte_ipv6_addr addr;
- uint16_t port;
-
- if (parse_ipv6_addr(tokens[2], &addr) ||
- parser_read_uint16(&port, tokens[3]))
- return 0;
-
- a->nat.ip_version = 0;
- a->nat.addr.ipv6 = addr;
- a->nat.port = port;
- a->action_mask |= 1 << RTE_TABLE_ACTION_NAT;
- return 4;
- }
-
- return 0;
-}
-
-static uint32_t
-parse_table_action_ttl(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "ttl"))
- return 0;
-
- if (strcmp(tokens[1], "dec") == 0)
- a->ttl.decrement = 1;
- else if (strcmp(tokens[1], "keep") == 0)
- a->ttl.decrement = 0;
- else
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TTL;
- return 2;
-}
-
-static uint32_t
-parse_table_action_stats(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "stats"))
- return 0;
-
- a->stats.n_packets = 0;
- a->stats.n_bytes = 0;
- a->action_mask |= 1 << RTE_TABLE_ACTION_STATS;
- return 1;
-}
-
-static uint32_t
-parse_table_action_time(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 1) ||
- strcmp(tokens[0], "time"))
- return 0;
-
- a->time.time = rte_rdtsc();
- a->action_mask |= 1 << RTE_TABLE_ACTION_TIME;
- return 1;
-}
-
-static void
-parse_free_sym_crypto_param_data(struct rte_table_action_sym_crypto_params *p)
-{
- struct rte_crypto_sym_xform *xform[2] = {NULL};
- uint32_t i;
-
- xform[0] = p->xform;
- if (xform[0])
- xform[1] = xform[0]->next;
-
- for (i = 0; i < 2; i++) {
- if (xform[i] == NULL)
- continue;
-
- switch (xform[i]->type) {
- case RTE_CRYPTO_SYM_XFORM_CIPHER:
- free(p->cipher_auth.cipher_iv.val);
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AUTH:
- if (p->cipher_auth.auth_iv.val)
- free(p->cipher_auth.cipher_iv.val);
- if (p->cipher_auth.auth_iv_update.val)
- free(p->cipher_auth.cipher_iv_update.val);
- break;
- case RTE_CRYPTO_SYM_XFORM_AEAD:
- free(p->aead.iv.val);
- free(p->aead.aad.val);
- break;
- default:
- continue;
- }
- }
-
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- int status;
- size_t len;
-
- if (n_tokens < 7 || strcmp(tokens[1], "cipher_algo") ||
- strcmp(tokens[3], "cipher_key") ||
- strcmp(tokens[5], "cipher_iv"))
- return NULL;
-
- xform_cipher = calloc(1, sizeof(*xform_cipher));
- if (xform_cipher == NULL)
- return NULL;
-
- xform_cipher->type = RTE_CRYPTO_SYM_XFORM_CIPHER;
- xform_cipher->cipher.op = encrypt ? RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- /* cipher_algo */
- status = rte_cryptodev_get_cipher_algo_enum(
- &xform_cipher->cipher.algo, tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* cipher_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.key.data = key;
- xform_cipher->cipher.key.length = (uint16_t)len;
-
- /* cipher_iv */
- len = strlen(tokens[6]);
-
- p->cipher_auth.cipher_iv.val = calloc(1, len / 2 + 1);
- if (p->cipher_auth.cipher_iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6],
- p->cipher_auth.cipher_iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_cipher->cipher.iv.length = (uint16_t)len;
- xform_cipher->cipher.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->cipher_auth.cipher_iv.length = (uint32_t)len;
- *used_n_tokens = 7;
-
- return xform_cipher;
-
-error_exit:
- if (p->cipher_auth.cipher_iv.val) {
- free(p->cipher_auth.cipher_iv.val);
- p->cipher_auth.cipher_iv.val = NULL;
- }
-
- free(xform_cipher);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_cipher_auth(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_cipher;
- struct rte_crypto_sym_xform *xform_auth;
- int status;
- size_t len;
-
- if (n_tokens < 13 ||
- strcmp(tokens[7], "auth_algo") ||
- strcmp(tokens[9], "auth_key") ||
- strcmp(tokens[11], "digest_size"))
- return NULL;
-
- xform_auth = calloc(1, sizeof(*xform_auth));
- if (xform_auth == NULL)
- return NULL;
-
- xform_auth->type = RTE_CRYPTO_SYM_XFORM_AUTH;
- xform_auth->auth.op = encrypt ? RTE_CRYPTO_AUTH_OP_GENERATE :
- RTE_CRYPTO_AUTH_OP_VERIFY;
-
- /* auth_algo */
- status = rte_cryptodev_get_auth_algo_enum(&xform_auth->auth.algo,
- tokens[8]);
- if (status < 0)
- goto error_exit;
-
- /* auth_key */
- len = strlen(tokens[10]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[10], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_auth->auth.key.data = key;
- xform_auth->auth.key.length = (uint16_t)len;
-
- key += xform_auth->auth.key.length;
- max_key_len -= xform_auth->auth.key.length;
-
- if (strcmp(tokens[11], "digest_size"))
- goto error_exit;
-
- status = parser_read_uint16(&xform_auth->auth.digest_length,
- tokens[12]);
- if (status < 0)
- goto error_exit;
-
- xform_cipher = parse_table_action_cipher(p, key, max_key_len, tokens,
- 7, encrypt, used_n_tokens);
- if (xform_cipher == NULL)
- goto error_exit;
-
- *used_n_tokens += 6;
-
- if (encrypt) {
- xform_cipher->next = xform_auth;
- return xform_cipher;
- } else {
- xform_auth->next = xform_cipher;
- return xform_auth;
- }
-
-error_exit:
- if (p->cipher_auth.auth_iv.val) {
- free(p->cipher_auth.auth_iv.val);
- p->cipher_auth.auth_iv.val = 0;
- }
-
- free(xform_auth);
-
- return NULL;
-}
-
-static struct rte_crypto_sym_xform *
-parse_table_action_aead(struct rte_table_action_sym_crypto_params *p,
- uint8_t *key, uint32_t max_key_len, char **tokens,
- uint32_t n_tokens, uint32_t encrypt, uint32_t *used_n_tokens)
-{
- struct rte_crypto_sym_xform *xform_aead;
- int status;
- size_t len;
-
- if (n_tokens < 11 || strcmp(tokens[1], "aead_algo") ||
- strcmp(tokens[3], "aead_key") ||
- strcmp(tokens[5], "aead_iv") ||
- strcmp(tokens[7], "aead_aad") ||
- strcmp(tokens[9], "digest_size"))
- return NULL;
-
- xform_aead = calloc(1, sizeof(*xform_aead));
- if (xform_aead == NULL)
- return NULL;
-
- xform_aead->type = RTE_CRYPTO_SYM_XFORM_AEAD;
- xform_aead->aead.op = encrypt ? RTE_CRYPTO_AEAD_OP_ENCRYPT :
- RTE_CRYPTO_AEAD_OP_DECRYPT;
-
- /* aead_algo */
- status = rte_cryptodev_get_aead_algo_enum(&xform_aead->aead.algo,
- tokens[2]);
- if (status < 0)
- goto error_exit;
-
- /* aead_key */
- len = strlen(tokens[4]);
- if (len / 2 > max_key_len) {
- status = -ENOMEM;
- goto error_exit;
- }
-
- status = parse_hex_string(tokens[4], key, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.key.data = key;
- xform_aead->aead.key.length = (uint16_t)len;
-
- /* aead_iv */
- len = strlen(tokens[6]);
- p->aead.iv.val = calloc(1, len / 2 + 1);
- if (p->aead.iv.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[6], p->aead.iv.val,
- (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.iv.length = (uint16_t)len;
- xform_aead->aead.iv.offset = RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET;
- p->aead.iv.length = (uint32_t)len;
-
- /* aead_aad */
- len = strlen(tokens[8]);
- p->aead.aad.val = calloc(1, len / 2 + 1);
- if (p->aead.aad.val == NULL)
- goto error_exit;
-
- status = parse_hex_string(tokens[8], p->aead.aad.val, (uint32_t *)&len);
- if (status < 0)
- goto error_exit;
-
- xform_aead->aead.aad_length = (uint16_t)len;
- p->aead.aad.length = (uint32_t)len;
-
- /* digest_size */
- status = parser_read_uint16(&xform_aead->aead.digest_length,
- tokens[10]);
- if (status < 0)
- goto error_exit;
-
- *used_n_tokens = 11;
-
- return xform_aead;
-
-error_exit:
- if (p->aead.iv.val) {
- free(p->aead.iv.val);
- p->aead.iv.val = NULL;
- }
- if (p->aead.aad.val) {
- free(p->aead.aad.val);
- p->aead.aad.val = NULL;
- }
-
- free(xform_aead);
-
- return NULL;
-}
-
-
-static uint32_t
-parse_table_action_sym_crypto(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- struct rte_table_action_sym_crypto_params *p = &a->sym_crypto;
- struct rte_crypto_sym_xform *xform = NULL;
- uint8_t *key = a->sym_crypto_key;
- uint32_t max_key_len = SYM_CRYPTO_MAX_KEY_SIZE;
- uint32_t used_n_tokens;
- uint32_t encrypt;
- int status;
-
- if ((n_tokens < 12) ||
- strcmp(tokens[0], "sym_crypto") ||
- strcmp(tokens[2], "type"))
- return 0;
-
- memset(p, 0, sizeof(*p));
-
- if (strcmp(tokens[1], "encrypt") == 0)
- encrypt = 1;
- else
- encrypt = 0;
-
- status = parser_read_uint32(&p->data_offset, tokens[n_tokens - 1]);
- if (status < 0)
- return 0;
-
- if (strcmp(tokens[3], "cipher") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "cipher_auth") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_cipher_auth(p, key, max_key_len,
- tokens, n_tokens, encrypt, &used_n_tokens);
- } else if (strcmp(tokens[3], "aead") == 0) {
- tokens += 3;
- n_tokens -= 3;
-
- xform = parse_table_action_aead(p, key, max_key_len, tokens,
- n_tokens, encrypt, &used_n_tokens);
- }
-
- if (xform == NULL)
- return 0;
-
- p->xform = xform;
-
- if (strcmp(tokens[used_n_tokens], "data_offset")) {
- parse_free_sym_crypto_param_data(p);
- return 0;
- }
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_SYM_CRYPTO;
-
- return used_n_tokens + 5;
-}
-
-static uint32_t
-parse_table_action_tag(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "tag"))
- return 0;
-
- if (parser_read_uint32(&a->tag.tag, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_TAG;
- return 2;
-}
-
-static uint32_t
-parse_table_action_decap(char **tokens,
- uint32_t n_tokens,
- struct table_rule_action *a)
-{
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "decap"))
- return 0;
-
- if (parser_read_uint16(&a->decap.n, tokens[1]))
- return 0;
-
- a->action_mask |= 1 << RTE_TABLE_ACTION_DECAP;
- return 2;
-}
-
-static uint32_t
-parse_table_action(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size,
- struct table_rule_action *a)
-{
- uint32_t n_tokens0 = n_tokens;
-
- memset(a, 0, sizeof(*a));
-
- if ((n_tokens < 2) ||
- strcmp(tokens[0], "action"))
- return 0;
-
- tokens++;
- n_tokens--;
-
- if (n_tokens && (strcmp(tokens[0], "fwd") == 0)) {
- uint32_t n;
-
- n = parse_table_action_fwd(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action fwd");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "balance") == 0)) {
- uint32_t n;
-
- n = parse_table_action_balance(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action balance");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "meter") == 0)) {
- uint32_t n;
-
- n = parse_table_action_meter(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action meter");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tm") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tm(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tm");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "encap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_encap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action encap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "nat") == 0)) {
- uint32_t n;
-
- n = parse_table_action_nat(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action nat");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "ttl") == 0)) {
- uint32_t n;
-
- n = parse_table_action_ttl(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action ttl");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "stats") == 0)) {
- uint32_t n;
-
- n = parse_table_action_stats(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action stats");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "time") == 0)) {
- uint32_t n;
-
- n = parse_table_action_time(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action time");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "sym_crypto") == 0)) {
- uint32_t n;
-
- n = parse_table_action_sym_crypto(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action sym_crypto");
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "tag") == 0)) {
- uint32_t n;
-
- n = parse_table_action_tag(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action tag");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens && (strcmp(tokens[0], "decap") == 0)) {
- uint32_t n;
-
- n = parse_table_action_decap(tokens, n_tokens, a);
- if (n == 0) {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "action decap");
- return 0;
- }
-
- tokens += n;
- n_tokens -= n;
- }
-
- if (n_tokens0 - n_tokens == 1) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return 0;
- }
-
- return n_tokens0 - n_tokens;
-}
-
-
-static const char cmd_pipeline_table_rule_add_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match <match>\n"
-" action <table_action>\n";
-
-static void
-cmd_pipeline_table_rule_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct table_rule_action a;
- char *pipeline_name;
- uint32_t table_id, t0, n_tokens_parsed;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- /* action */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &a);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (t0 != n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_add(pipeline_name, table_id, &m, &a);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- if (a.action_mask & 1 << RTE_TABLE_ACTION_SYM_CRYPTO)
- parse_free_sym_crypto_param_data(&a.sym_crypto);
-}
-
-
-static const char cmd_pipeline_table_rule_add_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule add\n"
-" match\n"
-" default\n"
-" action\n"
-" fwd\n"
-" drop\n"
-" | port <port_id>\n"
-" | meta\n"
-" | table <table_id>\n";
-
-static void
-cmd_pipeline_table_rule_add_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_action action;
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if ((n_tokens != 11) && (n_tokens != 12)) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- if (strcmp(tokens[8], "action") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "action");
- return;
- }
-
- if (strcmp(tokens[9], "fwd") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "fwd");
- return;
- }
-
- action.action_mask = 1 << RTE_TABLE_ACTION_FWD;
-
- if (strcmp(tokens[10], "drop") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_DROP;
- } else if (strcmp(tokens[10], "port") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "port_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT;
- action.fwd.id = id;
- } else if (strcmp(tokens[10], "meta") == 0) {
- if (n_tokens != 11) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_PORT_META;
- } else if (strcmp(tokens[10], "table") == 0) {
- uint32_t id;
-
- if (n_tokens != 12) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&id, tokens[11]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- action.fwd.action = RTE_PIPELINE_ACTION_TABLE;
- action.fwd.id = id;
- } else {
- snprintf(out, out_size, MSG_ARG_INVALID,
- "drop or port or meta or table");
- return;
- }
-
- status = pipeline_table_rule_add_default(pipeline_name,
- table_id,
- &action);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_add_bulk_help[] =
-"pipeline <pipeline_name> table <table_id> rule add bulk <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - line format: match <match> action <action>\n";
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size);
-
-static void
-cmd_pipeline_table_rule_add_bulk(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *pipeline_name, *file_name;
- uint32_t table_id, n_rules, n_rules_added, n_rules_not_added, line_number;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[6], "bulk") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "bulk");
- return;
- }
-
- file_name = tokens[7];
-
- /* Load rules from file. */
- status = cli_rule_file_process(file_name,
- 1024,
- &list,
- &n_rules,
- &line_number,
- out,
- out_size);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- /* Rule bulk add */
- status = pipeline_table_rule_add_bulk(pipeline_name,
- table_id,
- list,
- &n_rules_added,
- &n_rules_not_added);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- snprintf(out, out_size, "Added %u rules out of %u.\n",
- n_rules_added,
- n_rules);
-}
-
-
-static const char cmd_pipeline_table_rule_delete_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed, t0;
- int status;
-
- if (n_tokens < 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- t0 = 6;
-
- /* match */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- t0 += n_tokens_parsed;
-
- if (n_tokens != t0) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_rule_delete(pipeline_name,
- table_id,
- &m);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_delete_default_help[] =
-"pipeline <pipeline_name> table <table_id> rule delete\n"
-" match\n"
-" default\n";
-
-static void
-cmd_pipeline_table_rule_delete_default(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- if (strcmp(tokens[6], "match") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "match");
- return;
- }
-
- if (strcmp(tokens[7], "default") != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "default");
- return;
- }
-
- status = pipeline_table_rule_delete_default(pipeline_name,
- table_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static void
-ether_addr_show(FILE *f, struct rte_ether_addr *addr)
-{
- fprintf(f, RTE_ETHER_ADDR_PRT_FMT, RTE_ETHER_ADDR_BYTES(addr));
-}
-
-static void
-ipv4_addr_show(FILE *f, uint32_t addr)
-{
- fprintf(f, "%u.%u.%u.%u",
- addr >> 24,
- (addr >> 16) & 0xFF,
- (addr >> 8) & 0xFF,
- addr & 0xFF);
-}
-
-static void
-ipv6_addr_show(FILE *f, const struct rte_ipv6_addr *ip)
-{
- fprintf(f, RTE_IPV6_ADDR_FMT ":", RTE_IPV6_ADDR_SPLIT(ip));
-}
-
-static const char *
-policer_action_string(enum rte_table_action_policer action) {
- switch (action) {
- case RTE_TABLE_ACTION_POLICER_COLOR_GREEN: return "G";
- case RTE_TABLE_ACTION_POLICER_COLOR_YELLOW: return "Y";
- case RTE_TABLE_ACTION_POLICER_COLOR_RED: return "R";
- case RTE_TABLE_ACTION_POLICER_DROP: return "D";
- default: return "?";
- }
-}
-
-static int
-table_rule_show(const char *pipeline_name,
- uint32_t table_id,
- const char *file_name)
-{
- struct pipeline *pipeline;
- struct table *table;
- struct table_rule *rule;
- FILE *f = NULL;
- uint32_t i;
-
- /* Check input params. */
- if ((pipeline_name == NULL) ||
- (file_name == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL || table_id >= pipeline->n_tables)
- return -1;
-
- table = &pipeline->table[table_id];
-
- /* Open file. */
- f = fopen(file_name, "w");
- if (f == NULL)
- return -1;
-
- /* Write table rules to file. */
- TAILQ_FOREACH(rule, &table->rules, node) {
- struct table_rule_match *m = &rule->match;
- struct table_rule_action *a = &rule->action;
-
- fprintf(f, "match ");
- switch (m->match_type) {
- case TABLE_ACL:
- fprintf(f, "acl priority %u ",
- m->match.acl.priority);
-
- fprintf(f, m->match.acl.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.sa);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.sa);
-
- fprintf(f, "%u", m->match.acl.sa_depth);
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.acl.ipv4.da);
- else
- ipv6_addr_show(f, &m->match.acl.ipv6.da);
-
- fprintf(f, "%u", m->match.acl.da_depth);
-
- fprintf(f, "%u %u %u %u %u ",
- (uint32_t)m->match.acl.sp0,
- (uint32_t)m->match.acl.sp1,
- (uint32_t)m->match.acl.dp0,
- (uint32_t)m->match.acl.dp1,
- (uint32_t)m->match.acl.proto);
- break;
-
- case TABLE_ARRAY:
- fprintf(f, "array %u ",
- m->match.array.pos);
- break;
-
- case TABLE_HASH:
- fprintf(f, "hash raw ");
- for (i = 0; i < table->params.match.hash.key_size; i++)
- fprintf(f, "%02x", m->match.hash.key[i]);
- fprintf(f, " ");
- break;
-
- case TABLE_LPM:
- fprintf(f, "lpm ");
-
- fprintf(f, m->match.lpm.ip_version ? "ipv4 " : "ipv6 ");
-
- if (m->match.acl.ip_version)
- ipv4_addr_show(f, m->match.lpm.ipv4);
- else
- ipv6_addr_show(f, &m->match.lpm.ipv6);
-
- fprintf(f, "%u ",
- (uint32_t)m->match.lpm.depth);
- break;
-
- default:
- fprintf(f, "unknown ");
- }
-
- fprintf(f, "action ");
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- fprintf(f, "fwd ");
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- fprintf(f, "balance ");
- for (i = 0; i < RTE_DIM(a->lb.out); i++)
- fprintf(f, "%u ", a->lb.out[i]);
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- fprintf(f, "mtr ");
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++)
- if (a->mtr.tc_mask & (1 << i)) {
- struct rte_table_action_mtr_tc_params *p =
- &a->mtr.mtr[i];
- enum rte_table_action_policer ga =
- p->policer[RTE_COLOR_GREEN];
- enum rte_table_action_policer ya =
- p->policer[RTE_COLOR_YELLOW];
- enum rte_table_action_policer ra =
- p->policer[RTE_COLOR_RED];
-
- fprintf(f, "tc%u meter %u policer g %s y %s r %s ",
- i,
- a->mtr.mtr[i].meter_profile_id,
- policer_action_string(ga),
- policer_action_string(ya),
- policer_action_string(ra));
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TM))
- fprintf(f, "tm subport %u pipe %u ",
- a->tm.subport_id,
- a->tm.pipe_id);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- fprintf(f, "encap ");
- switch (a->encap.type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- fprintf(f, "ether ");
- ether_addr_show(f, &a->encap.ether.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.ether.ether.sa);
- fprintf(f, " ");
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- fprintf(f, "vlan ");
- ether_addr_show(f, &a->encap.vlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vlan.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u ",
- a->encap.vlan.vlan.pcp,
- a->encap.vlan.vlan.dei,
- a->encap.vlan.vlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- fprintf(f, "qinq ");
- ether_addr_show(f, &a->encap.qinq.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.qinq.ether.sa);
- fprintf(f, " pcp %u dei %u vid %u pcp %u dei %u vid %u ",
- a->encap.qinq.svlan.pcp,
- a->encap.qinq.svlan.dei,
- a->encap.qinq.svlan.vid,
- a->encap.qinq.cvlan.pcp,
- a->encap.qinq.cvlan.dei,
- a->encap.qinq.cvlan.vid);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- fprintf(f, "mpls %s ", (a->encap.mpls.unicast) ?
- "unicast " : "multicast ");
- ether_addr_show(f, &a->encap.mpls.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.mpls.ether.sa);
- fprintf(f, " ");
- for (i = 0; i < a->encap.mpls.mpls_count; i++) {
- struct rte_table_action_mpls_hdr *l =
- &a->encap.mpls.mpls[i];
-
- fprintf(f, "label%u %u %u %u ",
- i,
- l->label,
- l->tc,
- l->ttl);
- }
- break;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- fprintf(f, "pppoe ");
- ether_addr_show(f, &a->encap.pppoe.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.pppoe.ether.sa);
- fprintf(f, " %u ", a->encap.pppoe.pppoe.session_id);
- break;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- fprintf(f, "vxlan ether ");
- ether_addr_show(f, &a->encap.vxlan.ether.da);
- fprintf(f, " ");
- ether_addr_show(f, &a->encap.vxlan.ether.sa);
- if (table->ap->params.encap.vxlan.vlan)
- fprintf(f, " vlan pcp %u dei %u vid %u ",
- a->encap.vxlan.vlan.pcp,
- a->encap.vxlan.vlan.dei,
- a->encap.vxlan.vlan.vid);
- if (table->ap->params.encap.vxlan.ip_version) {
- fprintf(f, " ipv4 ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.sa);
- fprintf(f, " ");
- ipv4_addr_show(f, a->encap.vxlan.ipv4.da);
- fprintf(f, " %u %u ",
- (uint32_t)a->encap.vxlan.ipv4.dscp,
- (uint32_t)a->encap.vxlan.ipv4.ttl);
- } else {
- fprintf(f, " ipv6 ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.sa);
- fprintf(f, " ");
- ipv6_addr_show(f, &a->encap.vxlan.ipv6.da);
- fprintf(f, " %u %u %u ",
- a->encap.vxlan.ipv6.flow_label,
- (uint32_t)a->encap.vxlan.ipv6.dscp,
- (uint32_t)a->encap.vxlan.ipv6.hop_limit);
- fprintf(f, " udp %u %u vxlan %u ",
- a->encap.vxlan.udp.sp,
- a->encap.vxlan.udp.dp,
- a->encap.vxlan.vxlan.vni);
- }
- break;
-
- default:
- fprintf(f, "unknown ");
- }
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- fprintf(f, "nat %s ", (a->nat.ip_version) ? "ipv4 " : "ipv6 ");
- if (a->nat.ip_version)
- ipv4_addr_show(f, a->nat.addr.ipv4);
- else
- ipv6_addr_show(f, &a->nat.addr.ipv6);
- fprintf(f, " %u ", (uint32_t)(a->nat.port));
- }
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TTL))
- fprintf(f, "ttl %s ", (a->ttl.decrement) ? "dec" : "keep");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_STATS))
- fprintf(f, "stats ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TIME))
- fprintf(f, "time ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO))
- fprintf(f, "sym_crypto ");
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_TAG))
- fprintf(f, "tag %u ", a->tag.tag);
-
- if (a->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP))
- fprintf(f, "decap %u ", a->decap.n);
-
- /* end */
- fprintf(f, "\n");
- }
-
- /* Write table default rule to file. */
- if (table->rule_default) {
- struct table_rule_action *a = &table->rule_default->action;
-
- fprintf(f, "# match default action fwd ");
-
- switch (a->fwd.action) {
- case RTE_PIPELINE_ACTION_DROP:
- fprintf(f, "drop ");
- break;
-
- case RTE_PIPELINE_ACTION_PORT:
- fprintf(f, "port %u ", a->fwd.id);
- break;
-
- case RTE_PIPELINE_ACTION_PORT_META:
- fprintf(f, "meta ");
- break;
-
- case RTE_PIPELINE_ACTION_TABLE:
- default:
- fprintf(f, "table %u ", a->fwd.id);
- }
- } else
- fprintf(f, "# match default action fwd drop ");
-
- fprintf(f, "\n");
-
- /* Close file. */
- fclose(f);
-
- return 0;
-}
-
-static const char cmd_pipeline_table_rule_show_help[] =
-"pipeline <pipeline_name> table <table_id> rule show\n"
-" file <file_name>\n";
-
-static void
-cmd_pipeline_table_rule_show(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *file_name = NULL, *pipeline_name;
- uint32_t table_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "show") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "show");
- return;
- }
-
- if (strcmp(tokens[6], "file") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "file");
- return;
- }
-
- file_name = tokens[7];
-
- status = table_rule_show(pipeline_name, table_id, file_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-static const char cmd_pipeline_table_rule_stats_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_stats_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_stats_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "stats") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "stats");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule stats. */
- status = pipeline_table_rule_stats_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- if (stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: %" PRIu64 "\n",
- stats.n_packets,
- stats.n_bytes);
-
- if (stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: %" PRIu64 "; Bytes: N/A\n",
- stats.n_packets);
-
- if (!stats.n_packets_valid && stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A; Bytes: %" PRIu64 "\n",
- stats.n_bytes);
-
- if (!stats.n_packets_valid && !stats.n_bytes_valid)
- snprintf(out, out_size, "Packets: N/A ; Bytes: N/A\n");
-}
-
-static const char cmd_pipeline_table_meter_profile_add_help[] =
-"pipeline <pipeline_name> table <table_id> meter profile <meter_profile_id>\n"
-" add srtcm cir <cir> cbs <cbs> ebs <ebs>\n"
-" | trtcm cir <cir> pir <pir> cbs <cbs> pbs <pbs>\n";
-
-static void
-cmd_pipeline_table_meter_profile_add(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_meter_profile p;
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens < 9) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "add") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "add");
- return;
- }
-
- if (strcmp(tokens[8], "srtcm") == 0) {
- if (n_tokens != 15) {
- snprintf(out, out_size, MSG_ARG_MISMATCH,
- tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_SRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.cbs, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[13], "ebs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ebs");
- return;
- }
-
- if (parser_read_uint64(&p.srtcm.ebs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "ebs");
- return;
- }
- } else if (strcmp(tokens[8], "trtcm") == 0) {
- if (n_tokens != 17) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- p.alg = RTE_TABLE_ACTION_METER_TRTCM;
-
- if (strcmp(tokens[9], "cir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cir, tokens[10]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cir");
- return;
- }
-
- if (strcmp(tokens[11], "pir") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pir");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pir, tokens[12]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pir");
- return;
- }
- if (strcmp(tokens[13], "cbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.cbs, tokens[14]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "cbs");
- return;
- }
-
- if (strcmp(tokens[15], "pbs") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pbs");
- return;
- }
-
- if (parser_read_uint64(&p.trtcm.pbs, tokens[16]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "pbs");
- return;
- }
- } else {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- status = pipeline_table_mtr_profile_add(pipeline_name,
- table_id,
- meter_profile_id,
- &p);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_meter_profile_delete_help[] =
-"pipeline <pipeline_name> table <table_id>\n"
-" meter profile <meter_profile_id> delete\n";
-
-static void
-cmd_pipeline_table_meter_profile_delete(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t table_id, meter_profile_id;
- int status;
-
- if (n_tokens != 8) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- if (strcmp(tokens[5], "profile") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "profile");
- return;
- }
-
- if (parser_read_uint32(&meter_profile_id, tokens[6]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "meter_profile_id");
- return;
- }
-
- if (strcmp(tokens[7], "delete") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "delete");
- return;
- }
-
- status = pipeline_table_mtr_profile_delete(pipeline_name,
- table_id,
- meter_profile_id);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_meter_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read meter [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_meter_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_mtr_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "meter") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meter");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule meter stats. */
- status = pipeline_table_rule_mtr_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
-}
-
-
-static const char cmd_pipeline_table_dscp_help[] =
-"pipeline <pipeline_name> table <table_id> dscp <file_name>\n"
-"\n"
-" File <file_name>:\n"
-" - exactly 64 lines\n"
-" - line format: <tc_id> <tc_queue_id> <color>, with <color> as: g | y | r\n";
-
-static int
-load_dscp_table(struct rte_table_action_dscp_table *dscp_table,
- const char *file_name,
- uint32_t *line_number)
-{
- FILE *f = NULL;
- uint32_t dscp, l;
-
- /* Check input arguments */
- if ((dscp_table == NULL) ||
- (file_name == NULL) ||
- (line_number == NULL)) {
- if (line_number)
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- *line_number = 0;
- return -EINVAL;
- }
-
- /* Read file */
- for (dscp = 0, l = 1; ; l++) {
- char line[64];
- char *tokens[3];
- enum rte_color color;
- uint32_t tc_id, tc_queue_id, n_tokens = RTE_DIM(tokens);
-
- if (fgets(line, sizeof(line), f) == NULL)
- break;
-
- if (is_comment(line))
- continue;
-
- if (parse_tokenize_string(line, tokens, &n_tokens)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- if (n_tokens == 0)
- continue;
-
- if ((dscp >= RTE_DIM(dscp_table->entry)) ||
- (n_tokens != RTE_DIM(tokens)) ||
- parser_read_uint32(&tc_id, tokens[0]) ||
- (tc_id >= RTE_TABLE_ACTION_TC_MAX) ||
- parser_read_uint32(&tc_queue_id, tokens[1]) ||
- (tc_queue_id >= RTE_TABLE_ACTION_TC_QUEUE_MAX) ||
- (strlen(tokens[2]) != 1)) {
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- switch (tokens[2][0]) {
- case 'g':
- case 'G':
- color = RTE_COLOR_GREEN;
- break;
-
- case 'y':
- case 'Y':
- color = RTE_COLOR_YELLOW;
- break;
-
- case 'r':
- case 'R':
- color = RTE_COLOR_RED;
- break;
-
- default:
- *line_number = l;
- fclose(f);
- return -EINVAL;
- }
-
- dscp_table->entry[dscp].tc_id = tc_id;
- dscp_table->entry[dscp].tc_queue_id = tc_queue_id;
- dscp_table->entry[dscp].color = color;
- dscp++;
- }
-
- /* Close file */
- fclose(f);
- return 0;
-}
-
-static void
-cmd_pipeline_table_dscp(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct rte_table_action_dscp_table dscp_table;
- char *pipeline_name, *file_name;
- uint32_t table_id, line_number;
- int status;
-
- if (n_tokens != 6) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "dscp") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "dscp");
- return;
- }
-
- file_name = tokens[5];
-
- status = load_dscp_table(&dscp_table, file_name, &line_number);
- if (status) {
- snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
- return;
- }
-
- status = pipeline_table_dscp_table_update(pipeline_name,
- table_id,
- UINT64_MAX,
- &dscp_table);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-}
-
-
-static const char cmd_pipeline_table_rule_ttl_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read ttl [clear]\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_ttl_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- struct rte_table_action_ttl_counters stats;
- char *pipeline_name;
- uint32_t table_id, n_tokens_parsed;
- int clear = 0, status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "ttl") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "ttl");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* clear */
- if (n_tokens && (strcmp(tokens[0], "clear") == 0)) {
- clear = 1;
-
- n_tokens--;
- tokens++;
- }
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule TTL stats. */
- status = pipeline_table_rule_ttl_read(pipeline_name,
- table_id,
- &m,
- &stats,
- clear);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n",
- stats.n_packets);
-}
-
-static const char cmd_pipeline_table_rule_time_read_help[] =
-"pipeline <pipeline_name> table <table_id> rule read time\n"
-" match <match>\n";
-
-static void
-cmd_pipeline_table_rule_time_read(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- struct table_rule_match m;
- char *pipeline_name;
- uint64_t timestamp;
- uint32_t table_id, n_tokens_parsed;
- int status;
-
- if (n_tokens < 7) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- pipeline_name = tokens[1];
-
- if (strcmp(tokens[2], "table") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "table");
- return;
- }
-
- if (parser_read_uint32(&table_id, tokens[3]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "table_id");
- return;
- }
-
- if (strcmp(tokens[4], "rule") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "rule");
- return;
- }
-
- if (strcmp(tokens[5], "read") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "read");
- return;
- }
-
- if (strcmp(tokens[6], "time") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "time");
- return;
- }
-
- n_tokens -= 7;
- tokens += 7;
-
- /* match */
- if ((n_tokens == 0) || strcmp(tokens[0], "match")) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "match");
- return;
- }
-
- n_tokens_parsed = parse_match(tokens,
- n_tokens,
- out,
- out_size,
- &m);
- if (n_tokens_parsed == 0)
- return;
- n_tokens -= n_tokens_parsed;
- tokens += n_tokens_parsed;
-
- /* end */
- if (n_tokens) {
- snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
- return;
- }
-
- /* Read table rule timestamp. */
- status = pipeline_table_rule_time_read(pipeline_name,
- table_id,
- &m,
- ×tamp);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
- return;
- }
-
- /* Print stats. */
- snprintf(out, out_size, "Packets: %" PRIu64 "\n", timestamp);
-}
-
-static const char cmd_thread_pipeline_enable_help[] =
-"thread <thread_id> pipeline <pipeline_name> enable\n";
-
-static void
-cmd_thread_pipeline_enable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "enable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
- return;
- }
-
- status = thread_pipeline_enable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
- return;
- }
-}
-
-
-static const char cmd_thread_pipeline_disable_help[] =
-"thread <thread_id> pipeline <pipeline_name> disable\n";
-
-static void
-cmd_thread_pipeline_disable(char **tokens,
- uint32_t n_tokens,
- char *out,
- size_t out_size)
-{
- char *pipeline_name;
- uint32_t thread_id;
- int status;
-
- if (n_tokens != 5) {
- snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
- return;
- }
-
- if (parser_read_uint32(&thread_id, tokens[1]) != 0) {
- snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
- return;
- }
-
- if (strcmp(tokens[2], "pipeline") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline");
- return;
- }
-
- pipeline_name = tokens[3];
-
- if (strcmp(tokens[4], "disable") != 0) {
- snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
- return;
- }
-
- status = thread_pipeline_disable(thread_id, pipeline_name);
- if (status) {
- snprintf(out, out_size, MSG_CMD_FAIL,
- "thread pipeline disable");
- return;
- }
-}
-
-static void
-cmd_help(char **tokens, uint32_t n_tokens, char *out, size_t out_size)
-{
- tokens++;
- n_tokens--;
-
- if (n_tokens == 0) {
- snprintf(out, out_size,
- "Type 'help <command>' for details on each command.\n\n"
- "List of commands:\n"
- "\tmempool\n"
- "\tlink\n"
- "\tswq\n"
- "\ttmgr subport profile\n"
- "\ttmgr pipe profile\n"
- "\ttmgr\n"
- "\ttmgr subport\n"
- "\ttmgr subport pipe\n"
- "\ttap\n"
- "\tport in action profile\n"
- "\ttable action profile\n"
- "\tpipeline\n"
- "\tpipeline port in\n"
- "\tpipeline port out\n"
- "\tpipeline table\n"
- "\tpipeline port in table\n"
- "\tpipeline port in stats\n"
- "\tpipeline port in enable\n"
- "\tpipeline port in disable\n"
- "\tpipeline port out stats\n"
- "\tpipeline table stats\n"
- "\tpipeline table rule add\n"
- "\tpipeline table rule add default\n"
- "\tpipeline table rule add bulk\n"
- "\tpipeline table rule delete\n"
- "\tpipeline table rule delete default\n"
- "\tpipeline table rule show\n"
- "\tpipeline table rule stats read\n"
- "\tpipeline table meter profile add\n"
- "\tpipeline table meter profile delete\n"
- "\tpipeline table rule meter read\n"
- "\tpipeline table dscp\n"
- "\tpipeline table rule ttl read\n"
- "\tpipeline table rule time read\n"
- "\tthread pipeline enable\n"
- "\tthread pipeline disable\n\n");
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_mempool_help);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_link_help);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_swq_help);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if (n_tokens == 1) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_help);
- return;
- }
-
- if ((n_tokens == 2) &&
- (strcmp(tokens[1], "subport")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_tmgr_subport_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "pipe") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_subport_pipe_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_tmgr_pipe_profile_help);
- return;
- }
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_tap_help);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[0], "port") == 0) &&
- (strcmp(tokens[1], "in") == 0) &&
- (strcmp(tokens[2], "action") == 0) &&
- (strcmp(tokens[3], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_port_in_action_profile_help);
- return;
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "table") == 0) &&
- (strcmp(tokens[1], "action") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- snprintf(out, out_size, "\n%s\n", cmd_table_action_profile_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 1)) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_help);
- return;
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "port") == 0)) {
- if ((n_tokens == 3) && (strcmp(tokens[2], "in")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_in_help);
- return;
- }
-
- if ((n_tokens == 3) && (strcmp(tokens[2], "out")) == 0) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_port_out_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "table") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_table_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_stats_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "enable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_enable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "in") == 0) &&
- (strcmp(tokens[3], "disable") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_in_disable_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "out") == 0) &&
- (strcmp(tokens[3], "stats") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_port_out_stats_help);
- return;
- }
- }
-
- if ((strcmp(tokens[0], "pipeline") == 0) &&
- (strcmp(tokens[1], "table") == 0)) {
- if (n_tokens == 2) {
- snprintf(out, out_size, "\n%s\n", cmd_pipeline_table_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "stats") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_stats_help);
- return;
- }
-
- if ((n_tokens == 3) && strcmp(tokens[2], "dscp") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_dscp_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_default_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "add") == 0) &&
- (strcmp(tokens[4], "bulk") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_add_bulk_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "delete") == 0) &&
- (strcmp(tokens[4], "default") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_delete_default_help);
- return;
- }
-
- if ((n_tokens == 4) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "show") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_show_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "stats") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_stats_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "add") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_add_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "meter") == 0) &&
- (strcmp(tokens[3], "profile") == 0) &&
- (strcmp(tokens[4], "delete") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_meter_profile_delete_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "meter") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_meter_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "ttl") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_ttl_read_help);
- return;
- }
-
- if ((n_tokens == 5) &&
- (strcmp(tokens[2], "rule") == 0) &&
- (strcmp(tokens[3], "time") == 0) &&
- (strcmp(tokens[4], "read") == 0)) {
- snprintf(out, out_size, "\n%s\n",
- cmd_pipeline_table_rule_time_read_help);
- return;
- }
- }
-
- if ((n_tokens == 3) &&
- (strcmp(tokens[0], "thread") == 0) &&
- (strcmp(tokens[1], "pipeline") == 0)) {
- if (strcmp(tokens[2], "enable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_enable_help);
- return;
- }
-
- if (strcmp(tokens[2], "disable") == 0) {
- snprintf(out, out_size, "\n%s\n",
- cmd_thread_pipeline_disable_help);
- return;
- }
- }
-
- snprintf(out, out_size, "Invalid command\n");
-}
-
-void
-cli_process(char *in, char *out, size_t out_size)
-{
- char *tokens[CMD_MAX_TOKENS];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- if (is_comment(in))
- return;
-
- status = parse_tokenize_string(in, tokens, &n_tokens);
- if (status) {
- snprintf(out, out_size, MSG_ARG_TOO_MANY, "");
- return;
- }
-
- if (n_tokens == 0)
- return;
-
- if (strcmp(tokens[0], "help") == 0) {
- cmd_help(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "mempool") == 0) {
- cmd_mempool(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "link") == 0) {
- if (strcmp(tokens[1], "show") == 0) {
- cmd_link_show(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_link(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "swq") == 0) {
- cmd_swq(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tmgr") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "subport") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_subport_profile(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 3) &&
- (strcmp(tokens[1], "pipe") == 0) &&
- (strcmp(tokens[2], "profile") == 0)) {
- cmd_tmgr_pipe_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "profile") == 0)) {
- cmd_tmgr_subport(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "subport") == 0) &&
- (strcmp(tokens[4], "pipe") == 0)) {
- cmd_tmgr_subport_pipe(tokens, n_tokens, out, out_size);
- return;
- }
-
- cmd_tmgr(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "tap") == 0) {
- cmd_tap(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "cryptodev") == 0) {
- cmd_cryptodev(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "port") == 0) {
- cmd_port_in_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "table") == 0) {
- cmd_table_action_profile(tokens, n_tokens, out, out_size);
- return;
- }
-
- if (strcmp(tokens[0], "pipeline") == 0) {
- if ((n_tokens >= 3) &&
- (strcmp(tokens[2], "period") == 0)) {
- cmd_pipeline(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_in(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[4], "bsz") == 0)) {
- cmd_pipeline_port_out(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 4) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[3], "match") == 0)) {
- cmd_pipeline_table(tokens, n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "table") == 0)) {
- cmd_pipeline_port_in_table(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_in_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "enable") == 0)) {
- cmd_pipeline_port_in_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "in") == 0) &&
- (strcmp(tokens[5], "disable") == 0)) {
- cmd_pipeline_port_in_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "port") == 0) &&
- (strcmp(tokens[3], "out") == 0) &&
- (strcmp(tokens[5], "stats") == 0)) {
- cmd_pipeline_port_out_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "stats") == 0)) {
- cmd_pipeline_table_stats(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_add_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "add") == 0) &&
- (strcmp(tokens[6], "bulk") == 0)) {
- cmd_pipeline_table_rule_add_bulk(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "delete") == 0) &&
- (strcmp(tokens[6], "match") == 0)) {
- if ((n_tokens >= 8) &&
- (strcmp(tokens[7], "default") == 0)) {
- cmd_pipeline_table_rule_delete_default(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- cmd_pipeline_table_rule_delete(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 6) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "show") == 0)) {
- cmd_pipeline_table_rule_show(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "stats") == 0)) {
- cmd_pipeline_table_rule_stats_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "add") == 0)) {
- cmd_pipeline_table_meter_profile_add(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 8) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "meter") == 0) &&
- (strcmp(tokens[5], "profile") == 0) &&
- (strcmp(tokens[7], "delete") == 0)) {
- cmd_pipeline_table_meter_profile_delete(tokens,
- n_tokens, out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "meter") == 0)) {
- cmd_pipeline_table_rule_meter_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "dscp") == 0)) {
- cmd_pipeline_table_dscp(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "ttl") == 0)) {
- cmd_pipeline_table_rule_ttl_read(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 7) &&
- (strcmp(tokens[2], "table") == 0) &&
- (strcmp(tokens[4], "rule") == 0) &&
- (strcmp(tokens[5], "read") == 0) &&
- (strcmp(tokens[6], "time") == 0)) {
- cmd_pipeline_table_rule_time_read(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- if (strcmp(tokens[0], "thread") == 0) {
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "enable") == 0)) {
- cmd_thread_pipeline_enable(tokens, n_tokens,
- out, out_size);
- return;
- }
-
- if ((n_tokens >= 5) &&
- (strcmp(tokens[4], "disable") == 0)) {
- cmd_thread_pipeline_disable(tokens, n_tokens,
- out, out_size);
- return;
- }
- }
-
- snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
-}
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max)
-{
- char *msg_in = NULL, *msg_out = NULL;
- FILE *f = NULL;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (msg_in_len_max == 0) ||
- (msg_out_len_max == 0))
- return -EINVAL;
-
- msg_in = malloc(msg_in_len_max + 1);
- msg_out = malloc(msg_out_len_max + 1);
- if ((msg_in == NULL) ||
- (msg_out == NULL)) {
- free(msg_out);
- free(msg_in);
- return -ENOMEM;
- }
-
- /* Open input file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- free(msg_out);
- free(msg_in);
- return -EIO;
- }
-
- /* Read file */
- for ( ; ; ) {
- if (fgets(msg_in, msg_in_len_max + 1, f) == NULL)
- break;
-
- printf("%s", msg_in);
- msg_out[0] = 0;
-
- cli_process(msg_in,
- msg_out,
- msg_out_len_max);
-
- if (strlen(msg_out))
- printf("%s", msg_out);
- }
-
- /* Close file */
- fclose(f);
- free(msg_out);
- free(msg_in);
- return 0;
-}
-
-static int
-cli_rule_file_process(const char *file_name,
- size_t line_len_max,
- struct table_rule_list **rule_list,
- uint32_t *n_rules,
- uint32_t *line_number,
- char *out,
- size_t out_size)
-{
- struct table_rule_list *list = NULL;
- char *line = NULL;
- FILE *f = NULL;
- uint32_t rule_id = 0, line_id = 0;
- int status = 0;
-
- /* Check input arguments */
- if ((file_name == NULL) ||
- (strlen(file_name) == 0) ||
- (line_len_max == 0) ||
- (rule_list == NULL) ||
- (n_rules == NULL) ||
- (line_number == NULL) ||
- (out == NULL)) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Memory allocation */
- list = malloc(sizeof(struct table_rule_list));
- if (list == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INIT(list);
-
- line = malloc(line_len_max + 1);
- if (line == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- /* Open file */
- f = fopen(file_name, "r");
- if (f == NULL) {
- status = -EIO;
- goto cli_rule_file_process_free;
- }
-
- /* Read file */
- for (line_id = 1, rule_id = 0; ; line_id++) {
- char *tokens[CMD_MAX_TOKENS];
- struct table_rule *rule = NULL;
- uint32_t n_tokens, n_tokens_parsed, t0;
-
- /* Read next line from file. */
- if (fgets(line, line_len_max + 1, f) == NULL)
- break;
-
- /* Comment. */
- if (is_comment(line))
- continue;
-
- /* Parse line. */
- n_tokens = RTE_DIM(tokens);
- status = parse_tokenize_string(line, tokens, &n_tokens);
- if (status) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Empty line. */
- if (n_tokens == 0)
- continue;
- t0 = 0;
-
- /* Rule alloc and insert. */
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL) {
- status = -ENOMEM;
- goto cli_rule_file_process_free;
- }
-
- TAILQ_INSERT_TAIL(list, rule, node);
-
- /* Rule match. */
- n_tokens_parsed = parse_match(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->match);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Rule action. */
- n_tokens_parsed = parse_table_action(tokens + t0,
- n_tokens - t0,
- out,
- out_size,
- &rule->action);
- if (n_tokens_parsed == 0) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
- t0 += n_tokens_parsed;
-
- /* Line completed. */
- if (t0 < n_tokens) {
- status = -EINVAL;
- goto cli_rule_file_process_free;
- }
-
- /* Increment rule count */
- rule_id++;
- }
-
- /* Close file */
- fclose(f);
-
- /* Memory free */
- free(line);
-
- *rule_list = list;
- *n_rules = rule_id;
- *line_number = line_id;
- return 0;
-
-cli_rule_file_process_free:
- if (rule_list != NULL)
- *rule_list = NULL;
-
- if (n_rules != NULL)
- *n_rules = rule_id;
-
- if (line_number != NULL)
- *line_number = line_id;
-
- if (list != NULL)
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- }
-
- if (f)
- fclose(f);
- free(line);
- free(list);
-
- return status;
-}
diff --git a/examples/ip_pipeline/cli.h b/examples/ip_pipeline/cli.h
deleted file mode 100644
index 992e4c3a4a4a2a667ec03a7997430421b82be273..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/cli.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CLI_H__
-#define __INCLUDE_CLI_H__
-
-#include <stddef.h>
-
-void
-cli_process(char *in, char *out, size_t out_size);
-
-int
-cli_script_process(const char *file_name,
- size_t msg_in_len_max,
- size_t msg_out_len_max);
-
-#endif
diff --git a/examples/ip_pipeline/common.h b/examples/ip_pipeline/common.h
deleted file mode 100644
index 0886dfbe95976257569593012cbf4d9d61eed957..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/common.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_COMMON_H_
-#define _INCLUDE_COMMON_H_
-
-#ifndef NAME_SIZE
-#define NAME_SIZE 64
-#endif
-
-#endif /* _INCLUDE_COMMON_H_ */
diff --git a/examples/ip_pipeline/conn.c b/examples/ip_pipeline/conn.c
deleted file mode 100644
index b2406b7af1ba371f97787de8d4bedd86af464070..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/conn.c
+++ /dev/null
@@ -1,330 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-
-#include <sys/socket.h>
-
-#include <sys/epoll.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#include <rte_string_fns.h>
-
-#include "conn.h"
-
-#define MSG_CMD_TOO_LONG "Command too long."
-
-struct conn {
- char *welcome;
- char *prompt;
- char *buf;
- char *msg_in;
- char *msg_out;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- size_t msg_in_len;
- int fd_server;
- int fd_client_group;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p)
-{
- struct sockaddr_in server_address;
- struct conn *conn;
- int fd_server, fd_client_group, status;
-
- memset(&server_address, 0, sizeof(server_address));
-
- /* Check input arguments */
- if ((p == NULL) ||
- (p->welcome == NULL) ||
- (p->prompt == NULL) ||
- (p->addr == NULL) ||
- (p->buf_size == 0) ||
- (p->msg_in_len_max == 0) ||
- (p->msg_out_len_max == 0) ||
- (p->msg_handle == NULL))
- return NULL;
-
- status = inet_aton(p->addr, &server_address.sin_addr);
- if (status == 0)
- return NULL;
-
- /* Memory allocation */
- conn = calloc(1, sizeof(struct conn));
- if (conn == NULL)
- return NULL;
-
- conn->welcome = calloc(1, CONN_WELCOME_LEN_MAX + 1);
- conn->prompt = calloc(1, CONN_PROMPT_LEN_MAX + 1);
- conn->buf = calloc(1, p->buf_size);
- conn->msg_in = calloc(1, p->msg_in_len_max + 1);
- conn->msg_out = calloc(1, p->msg_out_len_max + 1);
-
- if ((conn->welcome == NULL) ||
- (conn->prompt == NULL) ||
- (conn->buf == NULL) ||
- (conn->msg_in == NULL) ||
- (conn->msg_out == NULL)) {
- conn_free(conn);
- return NULL;
- }
-
- /* Server socket */
- server_address.sin_family = AF_INET;
- server_address.sin_port = htons(p->port);
-
- fd_server = socket(AF_INET,
- SOCK_STREAM | SOCK_NONBLOCK,
- 0);
- if (fd_server == -1) {
- conn_free(conn);
- return NULL;
- }
-
- status = bind(fd_server,
- (struct sockaddr *) &server_address,
- sizeof(server_address));
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- status = listen(fd_server, 16);
- if (status == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Client group */
- fd_client_group = epoll_create(1);
- if (fd_client_group == -1) {
- conn_free(conn);
- close(fd_server);
- return NULL;
- }
-
- /* Fill in */
- strlcpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX + 1);
- strlcpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX + 1);
- conn->buf_size = p->buf_size;
- conn->msg_in_len_max = p->msg_in_len_max;
- conn->msg_out_len_max = p->msg_out_len_max;
- conn->msg_in_len = 0;
- conn->fd_server = fd_server;
- conn->fd_client_group = fd_client_group;
- conn->msg_handle = p->msg_handle;
-
- return conn;
-}
-
-void
-conn_free(struct conn *conn)
-{
- if (conn == NULL)
- return;
-
- if (conn->fd_client_group)
- close(conn->fd_client_group);
-
- if (conn->fd_server)
- close(conn->fd_server);
-
- free(conn->msg_out);
- free(conn->msg_in);
- free(conn->prompt);
- free(conn->welcome);
- free(conn);
-}
-
-int
-conn_poll_for_conn(struct conn *conn)
-{
- struct sockaddr_in client_address;
- struct epoll_event event;
- socklen_t client_address_length;
- int fd_client, status;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Server socket */
- client_address_length = sizeof(client_address);
- fd_client = accept4(conn->fd_server,
- (struct sockaddr *) &client_address,
- &client_address_length,
- SOCK_NONBLOCK);
- if (fd_client == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
-
- /* Client group */
- event.events = EPOLLIN | EPOLLRDHUP | EPOLLHUP;
- event.data.fd = fd_client;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_ADD,
- fd_client,
- &event);
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- /* Client */
- status = write(fd_client,
- conn->welcome,
- strlen(conn->welcome));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1) {
- close(fd_client);
- return -1;
- }
-
- return 0;
-}
-
-static int
-data_event_handle(struct conn *conn,
- int fd_client)
-{
- ssize_t len, i, status;
-
- /* Read input message */
-
- len = read(fd_client,
- conn->buf,
- conn->buf_size);
- if (len == -1) {
- if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
- return 0;
-
- return -1;
- }
- if (len == 0)
- return 0;
-
- /* Handle input messages */
- for (i = 0; i < len; i++) {
- if (conn->buf[i] == '\n') {
- size_t n;
-
- conn->msg_in[conn->msg_in_len] = 0;
- conn->msg_out[0] = 0;
-
- conn->msg_handle(conn->msg_in,
- conn->msg_out,
- conn->msg_out_len_max);
-
- n = strlen(conn->msg_out);
- if (n) {
- status = write(fd_client,
- conn->msg_out,
- n);
- if (status == -1)
- return status;
- }
-
- conn->msg_in_len = 0;
- } else if (conn->msg_in_len < conn->msg_in_len_max) {
- conn->msg_in[conn->msg_in_len] = conn->buf[i];
- conn->msg_in_len++;
- } else {
- status = write(fd_client,
- MSG_CMD_TOO_LONG,
- strlen(MSG_CMD_TOO_LONG));
- if (status == -1)
- return status;
-
- conn->msg_in_len = 0;
- }
- }
-
- /* Write prompt */
- status = write(fd_client,
- conn->prompt,
- strlen(conn->prompt));
- if (status == -1)
- return status;
-
- return 0;
-}
-
-static int
-control_event_handle(struct conn *conn,
- int fd_client)
-{
- int status;
-
- status = epoll_ctl(conn->fd_client_group,
- EPOLL_CTL_DEL,
- fd_client,
- NULL);
- if (status == -1)
- return -1;
-
- status = close(fd_client);
- if (status == -1)
- return -1;
-
- return 0;
-}
-
-int
-conn_poll_for_msg(struct conn *conn)
-{
- struct epoll_event event;
- int fd_client, status, status_data = 0, status_control = 0;
-
- /* Check input arguments */
- if (conn == NULL)
- return -1;
-
- /* Client group */
- status = epoll_wait(conn->fd_client_group,
- &event,
- 1,
- 0);
- if (status == -1)
- return -1;
- if (status == 0)
- return 0;
-
- fd_client = event.data.fd;
-
- /* Data available */
- if (event.events & EPOLLIN)
- status_data = data_event_handle(conn, fd_client);
-
- /* Control events */
- if (event.events & (EPOLLRDHUP | EPOLLERR | EPOLLHUP))
- status_control = control_event_handle(conn, fd_client);
-
- if (status_data || status_control)
- return -1;
-
- return 0;
-}
diff --git a/examples/ip_pipeline/conn.h b/examples/ip_pipeline/conn.h
deleted file mode 100644
index 46f9f95e9cfcd40aa38a5f31f24f63217bc8f706..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/conn.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_CONN_H__
-#define __INCLUDE_CONN_H__
-
-#include <stdint.h>
-
-struct conn;
-
-#ifndef CONN_WELCOME_LEN_MAX
-#define CONN_WELCOME_LEN_MAX 1024
-#endif
-
-#ifndef CONN_PROMPT_LEN_MAX
-#define CONN_PROMPT_LEN_MAX 16
-#endif
-
-typedef void (*conn_msg_handle_t)(char *msg_in,
- char *msg_out,
- size_t msg_out_len_max);
-
-struct conn_params {
- const char *welcome;
- const char *prompt;
- const char *addr;
- uint16_t port;
- size_t buf_size;
- size_t msg_in_len_max;
- size_t msg_out_len_max;
- conn_msg_handle_t msg_handle;
-};
-
-struct conn *
-conn_init(struct conn_params *p);
-
-void
-conn_free(struct conn *conn);
-
-int
-conn_poll_for_conn(struct conn *conn);
-
-int
-conn_poll_for_msg(struct conn *conn);
-
-#endif
diff --git a/examples/ip_pipeline/cryptodev.c b/examples/ip_pipeline/cryptodev.c
deleted file mode 100644
index cd0f9c3d4eac633d3b5f05dfbb58e5057ae7b29c..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/cryptodev.c
+++ /dev/null
@@ -1,160 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <rte_cryptodev.h>
-#include <rte_string_fns.h>
-
-#include "cryptodev.h"
-
-#define PIPELINE_CRYPTO_SESSION_CACHE_SIZE 128
-
-static struct cryptodev_list cryptodev_list;
-
-int
-cryptodev_init(void)
-{
- TAILQ_INIT(&cryptodev_list);
-
- return 0;
-}
-
-struct cryptodev *
-cryptodev_find(const char *name)
-{
- struct cryptodev *cryptodev;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(cryptodev, &cryptodev_list, node)
- if (strcmp(cryptodev->name, name) == 0)
- return cryptodev;
-
- return NULL;
-}
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev)
-{
- return (cryptodev == NULL) ?
- TAILQ_FIRST(&cryptodev_list) :
- TAILQ_NEXT(cryptodev, node);
-}
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params)
-{
- struct rte_cryptodev_info dev_info;
- struct rte_cryptodev_config dev_conf;
- struct rte_cryptodev_qp_conf queue_conf;
- struct cryptodev *cryptodev;
- uint32_t dev_id, i;
- uint32_t socket_id;
- uint32_t cache_size;
- char mp_name[NAME_SIZE];
- int status;
-
- /* Check input params */
- if ((name == NULL) ||
- cryptodev_find(name) ||
- (params->n_queues == 0) ||
- (params->queue_size == 0) ||
- (params->session_pool_size == 0))
- return NULL;
-
- if (params->dev_name) {
- status = rte_cryptodev_get_dev_id(params->dev_name);
- if (status == -1)
- return NULL;
-
- dev_id = (uint32_t)status;
- } else {
- if (rte_cryptodev_is_valid_dev(params->dev_id) == 0)
- return NULL;
-
- dev_id = params->dev_id;
- }
-
- cache_size = (params->session_pool_size / 2 <
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE) ?
- (params->session_pool_size / 2) :
- PIPELINE_CRYPTO_SESSION_CACHE_SIZE;
-
- socket_id = rte_cryptodev_socket_id(dev_id);
- rte_cryptodev_info_get(dev_id, &dev_info);
-
- if (dev_info.max_nb_queue_pairs < params->n_queues)
- return NULL;
-
- dev_conf.socket_id = socket_id;
- dev_conf.nb_queue_pairs = params->n_queues;
- dev_conf.ff_disable = 0;
-
- status = rte_cryptodev_configure(dev_id, &dev_conf);
- if (status < 0)
- return NULL;
-
- queue_conf.nb_descriptors = params->queue_size;
- for (i = 0; i < params->n_queues; i++) {
- status = rte_cryptodev_queue_pair_setup(dev_id, i,
- &queue_conf, socket_id);
- if (status < 0)
- return NULL;
- }
-
- if (rte_cryptodev_start(dev_id) < 0)
- return NULL;
-
- cryptodev = calloc(1, sizeof(struct cryptodev));
- if (cryptodev == NULL) {
- rte_cryptodev_stop(dev_id);
- return NULL;
- }
-
- strlcpy(cryptodev->name, name, sizeof(cryptodev->name));
- cryptodev->dev_id = dev_id;
- cryptodev->n_queues = params->n_queues;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp%u", name, dev_id);
- cryptodev->mp_create = rte_cryptodev_sym_session_pool_create(
- mp_name,
- params->session_pool_size,
- 0,
- cache_size,
- 0,
- socket_id);
- if (!cryptodev->mp_create)
- goto error_exit;
-
- snprintf(mp_name, NAME_SIZE, "%s_mp_priv%u", name, dev_id);
- cryptodev->mp_init = rte_mempool_create(
- NULL,
- params->session_pool_size,
- rte_cryptodev_sym_get_private_session_size(dev_id),
- cache_size,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- socket_id,
- 0);
- if (!cryptodev->mp_init)
- goto error_exit;
-
- TAILQ_INSERT_TAIL(&cryptodev_list, cryptodev, node);
-
- return cryptodev;
-
-error_exit:
- rte_mempool_free(cryptodev->mp_create);
- rte_mempool_free(cryptodev->mp_init);
-
- free(cryptodev);
-
- return NULL;
-}
diff --git a/examples/ip_pipeline/cryptodev.h b/examples/ip_pipeline/cryptodev.h
deleted file mode 100644
index d00434379edb6f12745ebc0ce13ea97e9c0074a4..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/cryptodev.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SYM_C_H_
-#define _INCLUDE_SYM_C_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_cryptodev.h>
-
-#include "common.h"
-
-struct cryptodev {
- TAILQ_ENTRY(cryptodev) node;
- char name[NAME_SIZE];
- uint16_t dev_id;
- uint32_t n_queues;
- struct rte_mempool *mp_create;
- struct rte_mempool *mp_init;
-};
-
-TAILQ_HEAD(cryptodev_list, cryptodev);
-
-int
-cryptodev_init(void);
-
-struct cryptodev *
-cryptodev_find(const char *name);
-
-struct cryptodev *
-cryptodev_next(struct cryptodev *cryptodev);
-
-struct cryptodev_params {
- const char *dev_name;
- uint32_t dev_id; /**< Valid only when *dev_name* is NULL. */
- uint32_t n_queues;
- uint32_t queue_size;
- uint32_t session_pool_size;
-};
-
-struct cryptodev *
-cryptodev_create(const char *name, struct cryptodev_params *params);
-
-#endif
diff --git a/examples/ip_pipeline/examples/firewall.cli b/examples/ip_pipeline/examples/firewall.cli
deleted file mode 100644
index 269256c16175cf3483d1902564e1140b2e27935b..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/firewall.cli
+++ /dev/null
@@ -1,59 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Firewall |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; -+-
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match acl ipv4 offset 270 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd drop
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match acl priority 0 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow.cli b/examples/ip_pipeline/examples/flow.cli
deleted file mode 100644
index 426ff9025528e7c6179f024e6ed9c093e0a8c611..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/flow.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Flow |
-; LINK2 RXQ0 --->| Classification |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 16 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF offset 278 buckets 16K size 65K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.10 200.0.0.10 100 200 6 action fwd port 0
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.11 200.0.0.11 101 201 6 action fwd port 1
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.12 200.0.0.12 102 202 6 action fwd port 2
-pipeline PIPELINE0 table 0 rule add match hash ipv4_5tuple 100.0.0.13 200.0.0.13 103 203 6 action fwd port 3
diff --git a/examples/ip_pipeline/examples/flow_crypto.cli b/examples/ip_pipeline/examples/flow_crypto.cli
deleted file mode 100644
index 849f9d5feca57004a57828646a467546984bebea..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/flow_crypto.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2018 Intel Corporation
-
-; ________________
-; LINK0 RXQ0 --->| |---> CRYPTO0 TXQ0
-; | Flow |
-; CRYPTO0 RXQ0-->| Classification |---> LINK0 TXQ0
-; |________________|
-; |
-; +-----------> SINK0 (flow lookup miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 280 20
-; 4 Packet 256 1536
-; 5 Crypto Operation 1792 160
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 1
-
-link LINK0 dev 81:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-#Cryptodev
-cryptodev CRYPTO0 dev crypto_aesni_gcm0 queue 1 1024 max_sessions 512
-
-table action profile AP0 ipv4 offset 270 fwd sym_crypto dev CRYPTO0 offset 1792
-table action profile AP1 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 1
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 cryptodev CRYPTO0 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 cryptodev CRYPTO0 txq 0 offset 1792
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match hash ext key 8 mask FFFFFFFF00000000 offset 282 buckets 1K size 4K action AP0
-pipeline PIPELINE0 table match stub action AP1
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-
-thread 2 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 2
-
-#AES-GCM encrypt
-pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto encrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-#AES-GCM decrypt
-#pipeline PIPELINE0 table 0 rule add match hash ipv4_addr 100.0.0.10 action fwd port 0 sym_crypto decrypt type aead aead_algo aes-gcm aead_key 000102030405060708090a0b0c0d0e0f aead_iv 000102030405060708090a0b aead_aad 000102030405060708090a0b0c0d0e0f digest_size 8 data_offset 290
-
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
diff --git a/examples/ip_pipeline/examples/l2fwd.cli b/examples/ip_pipeline/examples/l2fwd.cli
deleted file mode 100644
index 35e77cc968f5972902c0f6aab714c5aa4e1c72b5..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/l2fwd.cli
+++ /dev/null
@@ -1,51 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; The pipeline below implements a simple pass-through connection between the
-; input ports to the output ports, as in this diagram:
-; ________________
-; LINK0 RXQ0 --->|................|---> LINK1 TXQ0
-; | |
-; LINK1 RXQ0 --->|................|---> LINK0 TXQ0
-; | PIPELINE0 |
-; LINK2 RXQ0 --->|................|---> LINK3 TXQ0
-; | |
-; LINK3 RXQ0 --->|................|---> LINK2 TXQ0
-; |________________|
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 table match stub
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 1
-pipeline PIPELINE0 table 1 rule add match default action fwd port 0
-pipeline PIPELINE0 table 2 rule add match default action fwd port 3
-pipeline PIPELINE0 table 3 rule add match default action fwd port 2
diff --git a/examples/ip_pipeline/examples/route.cli b/examples/ip_pipeline/examples/route.cli
deleted file mode 100644
index 579b36a659262624b6347aa9b8bd7b9d854be978..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/route.cli
+++ /dev/null
@@ -1,60 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________
-; LINK0 RXQ0 --->| |---> LINK0 TXQ0
-; | |
-; LINK1 RXQ0 --->| |---> LINK1 TXQ0
-; | Routing |
-; LINK2 RXQ0 --->| |---> LINK2 TXQ0
-; | |
-; LINK3 RXQ0 --->| |---> LINK3 TXQ0
-; |_______________|
-; |
-; +-----------> SINK0 (route miss)
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile AP0 ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/route_ecmp.cli b/examples/ip_pipeline/examples/route_ecmp.cli
deleted file mode 100644
index 06434a2560ed3d4ade86ec980aaecaa4070d1e79..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/route_ecmp.cli
+++ /dev/null
@@ -1,57 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; Equal Cost Multi-Path (ECMP) Routing
-;
-; Input packet: Ethernet/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK2 dev 0000:06:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK3 dev 0000:06:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-table action profile APRT ipv4 offset 270 fwd balance offset 278 mask 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF outoffset 256
-table action profile APNH ipv4 offset 270 fwd encap ether
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE0 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE0 port out bsz 32 sink
-
-pipeline PIPELINE0 table match lpm ipv4 offset 286 size 4K action APRT
-pipeline PIPELINE0 table match array offset 256 size 64K action APNH
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 4
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.0.0.0 10 action fwd table 1 balance 0 0 0 0 1 1 2 2
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.64.0.0 10 action fwd table 1 balance 1 1 1 1 2 2 3 3
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.128.0.0 10 action fwd table 1 balance 2 2 2 2 3 3 0 0
-pipeline PIPELINE0 table 0 rule add match lpm ipv4 100.192.0.0 10 action fwd table 1 balance 3 3 3 3 0 0 1 1
-
-pipeline PIPELINE0 table 1 rule add match array 0 action fwd port 0 encap ether a0:a1:a2:a3:a4:a5 00:01:02:03:04:05
-pipeline PIPELINE0 table 1 rule add match array 1 action fwd port 1 encap ether b0:b1:b2:b3:b4:b5 10:11:12:13:14:15
-pipeline PIPELINE0 table 1 rule add match array 2 action fwd port 2 encap ether c0:c1:c2:c3:c4:c5 20:21:22:23:24:25
-pipeline PIPELINE0 table 1 rule add match array 3 action fwd port 3 encap ether d0:d1:d2:d3:d4:d5 30:31:32:33:34:35
diff --git a/examples/ip_pipeline/examples/rss.cli b/examples/ip_pipeline/examples/rss.cli
deleted file mode 100644
index 29c0a913924bad176a64ebb8bb6628f701382241..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/rss.cli
+++ /dev/null
@@ -1,112 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; This setup demonstrates the usage of NIC Receive Side Scaling (RSS) feature.
-; Each NIC splits the input traffic into 4 RX queues, with each of its RX queues
-; being handled by a different pipeline:
-;
-; +-----------+ +----------+
-; +--------------------------->| | | |
-; | +------------------->| PIPELINE0 +--->| LINK 0 |--->
-; | | +------------->| (CORE A) | | TX |
-; | | | +------->| | | |
-; | | | | +-----------+ +----------+
-; +----------+ | | | |
-; | |-------+ | | |
-;--->| LINK 0 |-----------+ | | |
-; | RX |---------+ | | | |
-; | |-------+ | | | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | | +---|-----|-----|------->| | | |
-; +----------+ | | | +---|-----|------->| PIPELINE1 +--->| LINK 1 |--->
-; | |-------|-|-----+ | | +---|------->| (CORE B) | | TX |
-;--->| LINK 1 |-------|-|-------+ | | | +----->| | | |
-; | RX |-------|-|-------+ | | | | +-----------+ +----------+
-; | |-------|-|-----+ | | | | |
-; +----------+ | | | | | | | |
-; | | | | | | | |
-; +----------+ | | | | | | | |
-; | |-------|-|-----|-|---+ | | |
-;--->| LINK 2 |-------|-|-----|-|-----+ | | +-----------+ +----------+
-; | RX |-----+ | +-----|-|---------|-|----->| | | |
-; | |---+ | | | +---------|-|----->| PIPELINE2 +--->| LINK 2 |--->
-; +----------+ | +-|-------|-----------|-|----->| (CORE C) | | TX |
-; | | | | | +--->| | | |
-; +----------+ | | | | | | +-----------+ +----------+
-; | |---|---|-------|-----------+ | |
-;--->| LINK 3 |---|---|-------|-------------+ |
-; | RX |---|---|-------|---------------+
-; | |---|---|-------|-----------+
-; +----------+ | | | |
-; | | | | +-----------+ +----------+
-; | +-------|-----------|------->| | | |
-; | +-----------|------->| PIPELINE3 +--->| LINK 3 |--->
-; +-----------------------|------->| (CORE D) | | TX |
-; +------->| | | |
-; +-----------+ +----------+
-;
-;
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK1 dev 0000:02:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK2 dev 0000:06:00.0 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-link LINK3 dev 0000:06:00.1 rxq 4 128 MEMPOOL0 txq 1 512 promiscuous on rss 0 1 2 3
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK2 rxq 0
-pipeline PIPELINE0 port in bsz 32 link LINK3 rxq 0
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-pipeline PIPELINE0 table match stub
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 0
-pipeline PIPELINE0 port in 2 table 0
-pipeline PIPELINE0 port in 3 table 0
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE1 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE1 port in bsz 32 link LINK0 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK1 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK2 rxq 1
-pipeline PIPELINE1 port in bsz 32 link LINK3 rxq 1
-pipeline PIPELINE1 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE1 table match stub
-pipeline PIPELINE1 port in 0 table 0
-pipeline PIPELINE1 port in 1 table 0
-pipeline PIPELINE1 port in 2 table 0
-pipeline PIPELINE1 port in 3 table 0
-pipeline PIPELINE1 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE2 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE2 port in bsz 32 link LINK0 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK1 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK2 rxq 2
-pipeline PIPELINE2 port in bsz 32 link LINK3 rxq 2
-pipeline PIPELINE2 port out bsz 32 link LINK2 txq 0
-pipeline PIPELINE2 table match stub
-pipeline PIPELINE2 port in 0 table 0
-pipeline PIPELINE2 port in 1 table 0
-pipeline PIPELINE2 port in 2 table 0
-pipeline PIPELINE2 port in 3 table 0
-pipeline PIPELINE2 table 0 rule add match default action fwd port 0
-
-pipeline PIPELINE3 period 10 offset_port_id 0 cpu 0
-pipeline PIPELINE3 port in bsz 32 link LINK0 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK1 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK2 rxq 3
-pipeline PIPELINE3 port in bsz 32 link LINK3 rxq 3
-pipeline PIPELINE3 port out bsz 32 link LINK3 txq 0
-pipeline PIPELINE3 table match stub
-pipeline PIPELINE3 port in 0 table 0
-pipeline PIPELINE3 port in 1 table 0
-pipeline PIPELINE3 port in 2 table 0
-pipeline PIPELINE3 port in 3 table 0
-pipeline PIPELINE3 table 0 rule add match default action fwd port 0
-
-thread 1 pipeline PIPELINE0 enable
-thread 2 pipeline PIPELINE1 enable
-thread 3 pipeline PIPELINE2 enable
-thread 4 pipeline PIPELINE3 enable
diff --git a/examples/ip_pipeline/examples/tap.cli b/examples/ip_pipeline/examples/tap.cli
deleted file mode 100644
index 600cea264350352510b1eefa176563015435e59a..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/examples/tap.cli
+++ /dev/null
@@ -1,66 +0,0 @@
-; SPDX-License-Identifier: BSD-3-Clause
-; Copyright(c) 2010-2018 Intel Corporation
-
-; _______________ ______________________
-; | | TAP0 | |
-; LINK0 RXQ0 --->|...............|------->|--+ |
-; | | TAP1 | | br0 |
-; LINK1 TXQ0 <---|...............|<-------|<-+ |
-; | | | Linux Kernel |
-; | PIPELINE0 | | Network Stack |
-; | | TAP1 | |
-; LINK1 RXQ0 --->|...............|------->|--+ |
-; | | TAP0 | | br0 |
-; LINK0 TXQ0 <---|...............|<-------|<-+ |
-; |_______________| |______________________|
-;
-; Configure Linux kernel bridge between TAP0 and TAP1 interfaces:
-; [Linux]$ brctl addbr br0
-; [Linux]$ brctl addif br0 TAP0
-; [Linux]$ brctl addif br0 TAP1
-; [Linux]$ ifconfig TAP0 up
-; [Linux]$ ifconfig TAP1 up
-; [Linux]$ ifconfig br0 up
-;
-; Monitor packet forwarding performed by Linux kernel between TAP0 and TAP1:
-; [Linux]$ tcpdump -i TAP0
-; [Linux]$ tcpdump -i TAP1
-
-mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
-
-link LINK0 dev 0000:02:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-link LINK1 dev 0000:02:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
-
-tap TAP0
-tap TAP1
-
-table action profile AP0 ipv4 offset 270 fwd
-
-pipeline PIPELINE0 period 10 offset_port_id 0 cpu 0
-
-pipeline PIPELINE0 port in bsz 32 link LINK0 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP1 mempool MEMPOOL0 mtu 1500
-pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
-pipeline PIPELINE0 port in bsz 32 tap TAP0 mempool MEMPOOL0 mtu 1500
-
-pipeline PIPELINE0 port out bsz 32 tap TAP0
-pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
-pipeline PIPELINE0 port out bsz 32 tap TAP1
-pipeline PIPELINE0 port out bsz 32 link LINK0 txq 0
-
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-pipeline PIPELINE0 table match stub action AP0
-
-pipeline PIPELINE0 port in 0 table 0
-pipeline PIPELINE0 port in 1 table 1
-pipeline PIPELINE0 port in 2 table 2
-pipeline PIPELINE0 port in 3 table 3
-
-thread 1 pipeline PIPELINE0 enable
-
-pipeline PIPELINE0 table 0 rule add match default action fwd port 0
-pipeline PIPELINE0 table 1 rule add match default action fwd port 1
-pipeline PIPELINE0 table 2 rule add match default action fwd port 2
-pipeline PIPELINE0 table 3 rule add match default action fwd port 3
diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
deleted file mode 100644
index 4d69ebebfbc0eea2cd6cf93bf9b3b0d9480fc428..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/link.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_ethdev.h>
-#include <rte_string_fns.h>
-
-#include "link.h"
-#include "mempool.h"
-
-static struct link_list link_list;
-
-int
-link_init(void)
-{
- TAILQ_INIT(&link_list);
-
- return 0;
-}
-
-struct link *
-link_find(const char *name)
-{
- struct link *link;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(link, &link_list, node)
- if (strcmp(link->name, name) == 0)
- return link;
-
- return NULL;
-}
-
-struct link *
-link_next(struct link *link)
-{
- return (link == NULL) ? TAILQ_FIRST(&link_list) : TAILQ_NEXT(link, node);
-}
-
-static struct rte_eth_conf port_conf_default = {
- .link_speeds = 0,
- .rxmode = {
- .mq_mode = RTE_ETH_MQ_RX_NONE,
- .mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_key_len = 40,
- .rss_hf = 0,
- },
- },
- .txmode = {
- .mq_mode = RTE_ETH_MQ_TX_NONE,
- },
- .lpbk_mode = 0,
-};
-
-#define RETA_CONF_SIZE (RTE_ETH_RSS_RETA_SIZE_512 / RTE_ETH_RETA_GROUP_SIZE)
-
-static int
-rss_setup(uint16_t port_id,
- uint16_t reta_size,
- struct link_params_rss *rss)
-{
- struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE];
- uint32_t i;
- int status;
-
- /* RETA setting */
- memset(reta_conf, 0, sizeof(reta_conf));
-
- for (i = 0; i < reta_size; i++)
- reta_conf[i / RTE_ETH_RETA_GROUP_SIZE].mask = UINT64_MAX;
-
- for (i = 0; i < reta_size; i++) {
- uint32_t reta_id = i / RTE_ETH_RETA_GROUP_SIZE;
- uint32_t reta_pos = i % RTE_ETH_RETA_GROUP_SIZE;
- uint32_t rss_qs_pos = i % rss->n_queues;
-
- reta_conf[reta_id].reta[reta_pos] =
- (uint16_t) rss->queue_id[rss_qs_pos];
- }
-
- /* RETA update */
- status = rte_eth_dev_rss_reta_update(port_id,
- reta_conf,
- reta_size);
-
- return status;
-}
-
-struct link *
-link_create(const char *name, struct link_params *params)
-{
- struct rte_eth_dev_info port_info;
- struct rte_eth_conf port_conf;
- struct link *link;
- struct link_params_rss *rss;
- struct mempool *mempool;
- uint32_t cpu_id, i;
- int status;
- uint16_t port_id;
-
- /* Check input params */
- if ((name == NULL) ||
- link_find(name) ||
- (params == NULL) ||
- (params->rx.n_queues == 0) ||
- (params->rx.queue_size == 0) ||
- (params->tx.n_queues == 0) ||
- (params->tx.queue_size == 0))
- return NULL;
-
- port_id = params->port_id;
- if (params->dev_name) {
- status = rte_eth_dev_get_port_by_name(params->dev_name,
- &port_id);
-
- if (status)
- return NULL;
- } else
- if (!rte_eth_dev_is_valid_port(port_id))
- return NULL;
-
- if (rte_eth_dev_info_get(port_id, &port_info) != 0)
- return NULL;
-
- mempool = mempool_find(params->rx.mempool_name);
- if (mempool == NULL)
- return NULL;
-
- rss = params->rx.rss;
- if (rss) {
- if ((port_info.reta_size == 0) ||
- (port_info.reta_size > RTE_ETH_RSS_RETA_SIZE_512))
- return NULL;
-
- if ((rss->n_queues == 0) ||
- (rss->n_queues >= LINK_RXQ_RSS_MAX))
- return NULL;
-
- for (i = 0; i < rss->n_queues; i++)
- if (rss->queue_id[i] >= port_info.max_rx_queues)
- return NULL;
- }
-
- /**
- * Resource create
- */
- /* Port */
- memcpy(&port_conf, &port_conf_default, sizeof(port_conf));
- if (rss) {
- port_conf.rxmode.mq_mode = RTE_ETH_MQ_RX_RSS;
- port_conf.rx_adv_conf.rss_conf.rss_hf =
- (RTE_ETH_RSS_IP | RTE_ETH_RSS_TCP | RTE_ETH_RSS_UDP) &
- port_info.flow_type_rss_offloads;
- }
-
- cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id);
- if (cpu_id == (uint32_t) SOCKET_ID_ANY)
- cpu_id = 0;
-
- status = rte_eth_dev_configure(
- port_id,
- params->rx.n_queues,
- params->tx.n_queues,
- &port_conf);
-
- if (status < 0)
- return NULL;
-
- if (params->promiscuous) {
- status = rte_eth_promiscuous_enable(port_id);
- if (status != 0)
- return NULL;
- }
-
- /* Port RX */
- for (i = 0; i < params->rx.n_queues; i++) {
- status = rte_eth_rx_queue_setup(
- port_id,
- i,
- params->rx.queue_size,
- cpu_id,
- NULL,
- mempool->m);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port TX */
- for (i = 0; i < params->tx.n_queues; i++) {
- status = rte_eth_tx_queue_setup(
- port_id,
- i,
- params->tx.queue_size,
- cpu_id,
- NULL);
-
- if (status < 0)
- return NULL;
- }
-
- /* Port start */
- status = rte_eth_dev_start(port_id);
- if (status < 0)
- return NULL;
-
- if (rss) {
- status = rss_setup(port_id, port_info.reta_size, rss);
-
- if (status) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
- }
-
- /* Port link up */
- status = rte_eth_dev_set_link_up(port_id);
- if ((status < 0) && (status != -ENOTSUP)) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node allocation */
- link = calloc(1, sizeof(struct link));
- if (link == NULL) {
- rte_eth_dev_stop(port_id);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(link->name, name, sizeof(link->name));
- link->port_id = port_id;
- link->n_rxq = params->rx.n_queues;
- link->n_txq = params->tx.n_queues;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&link_list, link, node);
-
- return link;
-}
-
-int
-link_is_up(const char *name)
-{
- struct rte_eth_link link_params;
- struct link *link;
-
- /* Check input params */
- if (name == NULL)
- return 0;
-
- link = link_find(name);
- if (link == NULL)
- return 0;
-
- /* Resource */
- if (rte_eth_link_get(link->port_id, &link_params) < 0)
- return 0;
-
- return (link_params.link_status == RTE_ETH_LINK_DOWN) ? 0 : 1;
-}
diff --git a/examples/ip_pipeline/link.h b/examples/ip_pipeline/link.h
deleted file mode 100644
index 34ff1149e0f7e52e4564f700c56045b11abd0565..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/link.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_LINK_H_
-#define _INCLUDE_LINK_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include "common.h"
-
-#ifndef LINK_RXQ_RSS_MAX
-#define LINK_RXQ_RSS_MAX 16
-#endif
-
-struct link {
- TAILQ_ENTRY(link) node;
- char name[NAME_SIZE];
- uint16_t port_id;
- uint32_t n_rxq;
- uint32_t n_txq;
-};
-
-TAILQ_HEAD(link_list, link);
-
-int
-link_init(void);
-
-struct link *
-link_find(const char *name);
-
-struct link *
-link_next(struct link *link);
-
-struct link_params_rss {
- uint32_t queue_id[LINK_RXQ_RSS_MAX];
- uint32_t n_queues;
-};
-
-struct link_params {
- const char *dev_name;
- uint16_t port_id; /**< Valid only when *dev_name* is NULL. */
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- const char *mempool_name;
- struct link_params_rss *rss;
- } rx;
-
- struct {
- uint32_t n_queues;
- uint32_t queue_size;
- } tx;
-
- int promiscuous;
-};
-
-struct link *
-link_create(const char *name, struct link_params *params);
-
-int
-link_is_up(const char *name);
-
-#endif /* _INCLUDE_LINK_H_ */
diff --git a/examples/ip_pipeline/main.c b/examples/ip_pipeline/main.c
deleted file mode 100644
index 663f538f024a2957bd0e3acaa806e65e89ecb09c..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/main.c
+++ /dev/null
@@ -1,260 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <getopt.h>
-
-#include <rte_launch.h>
-#include <rte_eal.h>
-
-#include "cli.h"
-#include "conn.h"
-#include "cryptodev.h"
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "swq.h"
-#include "tap.h"
-#include "thread.h"
-#include "tmgr.h"
-
-static const char usage[] =
- "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n";
-
-static const char welcome[] =
- "\n"
- "Welcome to IP Pipeline!\n"
- "\n";
-
-static const char prompt[] = "pipeline> ";
-
-static struct app_params {
- struct conn_params conn;
- char *script_name;
-} app = {
- .conn = {
- .welcome = welcome,
- .prompt = prompt,
- .addr = "0.0.0.0",
- .port = 8086,
- .buf_size = 1024 * 1024,
- .msg_in_len_max = 1024,
- .msg_out_len_max = 1024 * 1024,
- .msg_handle = cli_process,
- },
- .script_name = NULL,
-};
-
-static int
-parse_args(int argc, char **argv)
-{
- char *app_name = argv[0];
- struct option lgopts[] = {
- { NULL, 0, 0, 0 }
- };
- int opt, option_index;
- int h_present, p_present, s_present, n_args, i;
-
- /* Skip EAL input args */
- n_args = argc;
- for (i = 0; i < n_args; i++)
- if (strcmp(argv[i], "--") == 0) {
- argc -= i;
- argv += i;
- break;
- }
-
- if (i == n_args)
- return 0;
-
- /* Parse args */
- h_present = 0;
- p_present = 0;
- s_present = 0;
-
- while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index))
- != EOF)
- switch (opt) {
- case 'h':
- if (h_present) {
- printf("Error: Multiple -h arguments\n");
- return -1;
- }
- h_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -h not provided\n");
- return -1;
- }
-
- app.conn.addr = strdup(optarg);
- if (app.conn.addr == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- case 'p':
- if (p_present) {
- printf("Error: Multiple -p arguments\n");
- return -1;
- }
- p_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -p not provided\n");
- return -1;
- }
-
- app.conn.port = (uint16_t) atoi(optarg);
- break;
-
- case 's':
- if (s_present) {
- printf("Error: Multiple -s arguments\n");
- return -1;
- }
- s_present = 1;
-
- if (!strlen(optarg)) {
- printf("Error: Argument for -s not provided\n");
- return -1;
- }
-
- app.script_name = strdup(optarg);
- if (app.script_name == NULL) {
- printf("Error: Not enough memory\n");
- return -1;
- }
- break;
-
- default:
- printf(usage, app_name);
- return -1;
- }
-
- optind = 1; /* reset getopt lib */
-
- return 0;
-}
-
-int
-main(int argc, char **argv)
-{
- struct conn *conn;
- int status;
-
- /* Parse application arguments */
- status = parse_args(argc, argv);
- if (status < 0)
- return status;
-
- /* EAL */
- status = rte_eal_init(argc, argv);
- if (status < 0) {
- printf("Error: EAL initialization failed (%d)\n", status);
- return status;
- };
-
- /* Connectivity */
- conn = conn_init(&app.conn);
- if (conn == NULL) {
- printf("Error: Connectivity initialization failed (%d)\n",
- status);
- return status;
- };
-
- /* Mempool */
- status = mempool_init();
- if (status) {
- printf("Error: Mempool initialization failed (%d)\n", status);
- return status;
- }
-
- /* Link */
- status = link_init();
- if (status) {
- printf("Error: Link initialization failed (%d)\n", status);
- return status;
- }
-
- /* SWQ */
- status = swq_init();
- if (status) {
- printf("Error: SWQ initialization failed (%d)\n", status);
- return status;
- }
-
- /* Traffic Manager */
- status = tmgr_init();
- if (status) {
- printf("Error: TMGR initialization failed (%d)\n", status);
- return status;
- }
-
- /* TAP */
- status = tap_init();
- if (status) {
- printf("Error: TAP initialization failed (%d)\n", status);
- return status;
- }
-
- /* Sym Crypto */
- status = cryptodev_init();
- if (status) {
- printf("Error: Cryptodev initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Action */
- status = port_in_action_profile_init();
- if (status) {
- printf("Error: Input port action profile initialization failed (%d)\n", status);
- return status;
- }
-
- status = table_action_profile_init();
- if (status) {
- printf("Error: Action profile initialization failed (%d)\n",
- status);
- return status;
- }
-
- /* Pipeline */
- status = pipeline_init();
- if (status) {
- printf("Error: Pipeline initialization failed (%d)\n", status);
- return status;
- }
-
- /* Thread */
- status = thread_init();
- if (status) {
- printf("Error: Thread initialization failed (%d)\n", status);
- return status;
- }
-
- rte_eal_mp_remote_launch(
- thread_main,
- NULL,
- SKIP_MAIN);
-
- /* Script */
- if (app.script_name)
- cli_script_process(app.script_name,
- app.conn.msg_in_len_max,
- app.conn.msg_out_len_max);
-
- /* Dispatch loop */
- for ( ; ; ) {
- conn_poll_for_conn(conn);
-
- conn_poll_for_msg(conn);
- }
-}
diff --git a/examples/ip_pipeline/mempool.c b/examples/ip_pipeline/mempool.c
deleted file mode 100644
index f5d2a7d108daa96cc7b9514dc5df682d22cf672a..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/mempool.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_mbuf.h>
-#include <rte_string_fns.h>
-
-#include "mempool.h"
-
-#define BUFFER_SIZE_MIN (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
-
-static struct mempool_list mempool_list;
-
-int
-mempool_init(void)
-{
- TAILQ_INIT(&mempool_list);
-
- return 0;
-}
-
-struct mempool *
-mempool_find(const char *name)
-{
- struct mempool *mempool;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(mempool, &mempool_list, node)
- if (strcmp(mempool->name, name) == 0)
- return mempool;
-
- return NULL;
-}
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params)
-{
- struct mempool *mempool;
- struct rte_mempool *m;
-
- /* Check input params */
- if ((name == NULL) ||
- mempool_find(name) ||
- (params == NULL) ||
- (params->buffer_size < BUFFER_SIZE_MIN) ||
- (params->pool_size == 0))
- return NULL;
-
- /* Resource create */
- m = rte_pktmbuf_pool_create(
- name,
- params->pool_size,
- params->cache_size,
- 0,
- params->buffer_size - sizeof(struct rte_mbuf),
- params->cpu_id);
-
- if (m == NULL)
- return NULL;
-
- /* Node allocation */
- mempool = calloc(1, sizeof(struct mempool));
- if (mempool == NULL) {
- rte_mempool_free(m);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(mempool->name, name, sizeof(mempool->name));
- mempool->m = m;
- mempool->buffer_size = params->buffer_size;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&mempool_list, mempool, node);
-
- return mempool;
-}
diff --git a/examples/ip_pipeline/mempool.h b/examples/ip_pipeline/mempool.h
deleted file mode 100644
index bd46a11ca09f35bca1a52996af92a3c7b9026d0b..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/mempool.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_MEMPOOL_H_
-#define _INCLUDE_MEMPOOL_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_mempool.h>
-
-#include "common.h"
-
-struct mempool {
- TAILQ_ENTRY(mempool) node;
- char name[NAME_SIZE];
- struct rte_mempool *m;
- uint32_t buffer_size;
-};
-
-TAILQ_HEAD(mempool_list, mempool);
-
-int
-mempool_init(void);
-
-struct mempool *
-mempool_find(const char *name);
-
-struct mempool_params {
- uint32_t buffer_size;
- uint32_t pool_size;
- uint32_t cache_size;
- uint32_t cpu_id;
-};
-
-struct mempool *
-mempool_create(const char *name, struct mempool_params *params);
-
-#endif /* _INCLUDE_MEMPOOL_H_ */
diff --git a/examples/ip_pipeline/meson.build b/examples/ip_pipeline/meson.build
deleted file mode 100644
index 68049157e42978a2192fcf86769f5bdfc36465fc..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/meson.build
+++ /dev/null
@@ -1,30 +0,0 @@
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017-2018 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'
-
-build = cc.has_header('sys/epoll.h')
-if not build
- subdir_done()
-endif
-
-deps += ['pipeline', 'bus_pci']
-allow_experimental_apis = true
-sources = files(
- 'action.c',
- 'cli.c',
- 'conn.c',
- 'cryptodev.c',
- 'link.c',
- 'main.c',
- 'mempool.c',
- 'parser.c',
- 'pipeline.c',
- 'swq.c',
- 'tap.c',
- 'thread.c',
- 'tmgr.c',
-)
diff --git a/examples/ip_pipeline/parser.c b/examples/ip_pipeline/parser.c
deleted file mode 100644
index 8baa70e1f41053fad34fdee1f7f0b1bda6817b6b..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/parser.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation.
- * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
- * All rights reserved.
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <getopt.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <string.h>
-#include <libgen.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <arpa/inet.h>
-#include <sys/socket.h>
-
-#include <rte_errno.h>
-#include <rte_string_fns.h>
-
-#include "parser.h"
-
-static uint32_t
-get_hex_val(char c)
-{
- switch (c) {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9':
- return c - '0';
- case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
- return c - 'A' + 10;
- case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
- return c - 'a' + 10;
- default:
- return 0;
- }
-}
-
-int
-parser_read_arg_bool(const char *p)
-{
- p = rte_str_skip_leading_spaces(p);
- int result = -EINVAL;
-
- if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
- ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
- p += 3;
- result = 1;
- }
-
- if (((p[0] == 'o') && (p[1] == 'n')) ||
- ((p[0] == 'O') && (p[1] == 'N'))) {
- p += 2;
- result = 1;
- }
-
- if (((p[0] == 'n') && (p[1] == 'o')) ||
- ((p[0] == 'N') && (p[1] == 'O'))) {
- p += 2;
- result = 0;
- }
-
- if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
- ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
- p += 3;
- result = 0;
- }
-
- p = rte_str_skip_leading_spaces(p);
-
- if (p[0] != '\0')
- return -EINVAL;
-
- return result;
-}
-
-int
-parser_read_uint64(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
- if (!isdigit(*p))
- return -EINVAL;
-
- val = strtoul(p, &next, 10);
- if (p == next)
- return -EINVAL;
-
- p = next;
- switch (*p) {
- case 'T':
- val *= 1024ULL;
- /* fall through */
- case 'G':
- val *= 1024ULL;
- /* fall through */
- case 'M':
- val *= 1024ULL;
- /* fall through */
- case 'k':
- case 'K':
- val *= 1024ULL;
- p++;
- break;
- }
-
- p = rte_str_skip_leading_spaces(p);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint64_hex(uint64_t *value, const char *p)
-{
- char *next;
- uint64_t val;
-
- p = rte_str_skip_leading_spaces(p);
-
- val = strtoul(p, &next, 16);
- if (p == next)
- return -EINVAL;
-
- p = rte_str_skip_leading_spaces(next);
- if (*p != '\0')
- return -EINVAL;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint32_hex(uint32_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT32_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint16_hex(uint16_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT16_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parser_read_uint8_hex(uint8_t *value, const char *p)
-{
- uint64_t val = 0;
- int ret = parser_read_uint64_hex(&val, p);
-
- if (ret < 0)
- return ret;
-
- if (val > UINT8_MAX)
- return -ERANGE;
-
- *value = val;
- return 0;
-}
-
-int
-parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
-{
- uint32_t i;
-
- if ((string == NULL) ||
- (tokens == NULL) ||
- (*n_tokens < 1))
- return -EINVAL;
-
- for (i = 0; i < *n_tokens; i++) {
- tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
- if (tokens[i] == NULL)
- break;
- }
-
- if ((i == *n_tokens) &&
- (NULL != strtok_r(string, PARSE_DELIMITER, &string)))
- return -E2BIG;
-
- *n_tokens = i;
- return 0;
-}
-
-int
-parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
-{
- char *c;
- uint32_t len, i;
-
- /* Check input parameters */
- if ((src == NULL) ||
- (dst == NULL) ||
- (size == NULL) ||
- (*size == 0))
- return -1;
-
- len = strlen(src);
- if (((len & 3) != 0) ||
- (len > (*size) * 2))
- return -1;
- *size = len / 2;
-
- for (c = src; *c != 0; c++) {
- if ((((*c) >= '0') && ((*c) <= '9')) ||
- (((*c) >= 'A') && ((*c) <= 'F')) ||
- (((*c) >= 'a') && ((*c) <= 'f')))
- continue;
-
- return -1;
- }
-
- /* Convert chars to bytes */
- for (i = 0; i < *size; i++)
- dst[i] = get_hex_val(src[2 * i]) * 16 +
- get_hex_val(src[2 * i + 1]);
-
- return 0;
-}
-
-int
-parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels)
-{
- uint32_t n_max_labels = *n_labels, count = 0;
-
- /* Check for void list of labels */
- if (strcmp(string, "<void>") == 0) {
- *n_labels = 0;
- return 0;
- }
-
- /* At least one label should be present */
- for ( ; (*string != '\0'); ) {
- char *next;
- int value;
-
- if (count >= n_max_labels)
- return -1;
-
- if (count > 0) {
- if (string[0] != ':')
- return -1;
-
- string++;
- }
-
- value = strtol(string, &next, 10);
- if (next == string)
- return -1;
- string = next;
-
- labels[count++] = (uint32_t) value;
- }
-
- *n_labels = count;
- return 0;
-}
-
-static struct rte_ether_addr *
-my_ether_aton(const char *a)
-{
- int i;
- char *end;
- unsigned long o[RTE_ETHER_ADDR_LEN];
- static struct rte_ether_addr ether_addr;
-
- i = 0;
- do {
- errno = 0;
- o[i] = strtoul(a, &end, 16);
- if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
- return NULL;
- a = end + 1;
- } while (++i != RTE_DIM(o) && end[0] != 0);
-
- /* Junk at the end of line */
- if (end[0] != 0)
- return NULL;
-
- /* Support the format XX:XX:XX:XX:XX:XX */
- if (i == RTE_ETHER_ADDR_LEN) {
- while (i-- != 0) {
- if (o[i] > UINT8_MAX)
- return NULL;
- ether_addr.addr_bytes[i] = (uint8_t)o[i];
- }
- /* Support the format XXXX:XXXX:XXXX */
- } else if (i == RTE_ETHER_ADDR_LEN / 2) {
- while (i-- != 0) {
- if (o[i] > UINT16_MAX)
- return NULL;
- ether_addr.addr_bytes[i * 2] = (uint8_t)(o[i] >> 8);
- ether_addr.addr_bytes[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
- }
- /* unknown format */
- } else
- return NULL;
-
- return (struct rte_ether_addr *)ðer_addr;
-}
-
-int
-parse_ipv4_addr(const char *token, struct in_addr *ipv4)
-{
- if (strlen(token) >= INET_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET, token, ipv4) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6)
-{
- if (strlen(token) >= INET6_ADDRSTRLEN)
- return -EINVAL;
-
- if (inet_pton(AF_INET6, token, ipv6) != 1)
- return -EINVAL;
-
- return 0;
-}
-
-int
-parse_mac_addr(const char *token, struct rte_ether_addr *addr)
-{
- struct rte_ether_addr *tmp;
-
- tmp = my_ether_aton(token);
- if (tmp == NULL)
- return -1;
-
- *addr = *tmp;
- return 0;
-}
-
-int
-parse_cpu_core(const char *entry,
- struct cpu_core_params *p)
-{
- size_t num_len;
- char num[8];
-
- uint32_t s = 0, c = 0, h = 0, val;
- uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
- const char *next = rte_str_skip_leading_spaces(entry);
- char type;
-
- if (p == NULL)
- return -EINVAL;
-
- /* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
- while (*next != '\0') {
- /* If everything parsed nothing should left */
- if (s_parsed && c_parsed && h_parsed)
- return -EINVAL;
-
- type = *next;
- switch (type) {
- case 's':
- case 'S':
- if (s_parsed || c_parsed || h_parsed)
- return -EINVAL;
- s_parsed = 1;
- next++;
- break;
- case 'c':
- case 'C':
- if (c_parsed || h_parsed)
- return -EINVAL;
- c_parsed = 1;
- next++;
- break;
- case 'h':
- case 'H':
- if (h_parsed)
- return -EINVAL;
- h_parsed = 1;
- next++;
- break;
- default:
- /* If it start from digit it must be only core id. */
- if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
- return -EINVAL;
-
- type = 'C';
- }
-
- for (num_len = 0; *next != '\0'; next++, num_len++) {
- if (num_len == RTE_DIM(num))
- return -EINVAL;
-
- if (!isdigit(*next))
- break;
-
- num[num_len] = *next;
- }
-
- if (num_len == 0 && type != 'h' && type != 'H')
- return -EINVAL;
-
- if (num_len != 0 && (type == 'h' || type == 'H'))
- return -EINVAL;
-
- num[num_len] = '\0';
- val = strtol(num, NULL, 10);
-
- h = 0;
- switch (type) {
- case 's':
- case 'S':
- s = val;
- break;
- case 'c':
- case 'C':
- c = val;
- break;
- case 'h':
- case 'H':
- h = 1;
- break;
- }
- }
-
- p->socket_id = s;
- p->core_id = c;
- p->thread_id = h;
- return 0;
-}
diff --git a/examples/ip_pipeline/parser.h b/examples/ip_pipeline/parser.h
deleted file mode 100644
index c8f0187d71a2edcc9db97e81c2263d33cce0973f..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/parser.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_PARSER_H__
-#define __INCLUDE_PARSER_H__
-
-#include <ctype.h>
-#include <stdint.h>
-
-#include <rte_ip.h>
-#include <rte_ether.h>
-
-#define PARSE_DELIMITER " \f\n\r\t\v"
-
-static inline size_t
-skip_digits(const char *src)
-{
- size_t i;
-
- for (i = 0; isdigit(src[i]); i++)
- ;
-
- return i;
-}
-
-int parser_read_arg_bool(const char *p);
-
-int parser_read_uint64(uint64_t *value, const char *p);
-int parser_read_uint32(uint32_t *value, const char *p);
-int parser_read_uint16(uint16_t *value, const char *p);
-int parser_read_uint8(uint8_t *value, const char *p);
-
-int parser_read_uint64_hex(uint64_t *value, const char *p);
-int parser_read_uint32_hex(uint32_t *value, const char *p);
-int parser_read_uint16_hex(uint16_t *value, const char *p);
-int parser_read_uint8_hex(uint8_t *value, const char *p);
-
-int parse_hex_string(char *src, uint8_t *dst, uint32_t *size);
-
-int parse_ipv4_addr(const char *token, struct in_addr *ipv4);
-int parse_ipv6_addr(const char *token, struct rte_ipv6_addr *ipv6);
-int parse_mac_addr(const char *token, struct rte_ether_addr *addr);
-int parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels);
-
-struct cpu_core_params {
- uint32_t socket_id;
- uint32_t core_id;
- uint32_t thread_id;
-};
-
-int parse_cpu_core(const char *entry, struct cpu_core_params *p);
-
-int parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens);
-
-#endif
diff --git a/examples/ip_pipeline/pipeline.c b/examples/ip_pipeline/pipeline.c
deleted file mode 100644
index 792aab0059e9b154987cdc343643c3e77959dad5..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/pipeline.c
+++ /dev/null
@@ -1,1078 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-
-#include <rte_string_fns.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_ring.h>
-#include <rte_port_source_sink.h>
-#include <rte_port_fd.h>
-#include <rte_port_sched.h>
-#include <rte_port_sym_crypto.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_func.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_stub.h>
-
-#include "link.h"
-#include "mempool.h"
-#include "pipeline.h"
-#include "tap.h"
-#include "tmgr.h"
-#include "swq.h"
-#include "cryptodev.h"
-
-#ifndef PIPELINE_MSGQ_SIZE
-#define PIPELINE_MSGQ_SIZE 64
-#endif
-
-#ifndef TABLE_LPM_NUMBER_TBL8
-#define TABLE_LPM_NUMBER_TBL8 256
-#endif
-
-static struct pipeline_list pipeline_list;
-
-int
-pipeline_init(void)
-{
- TAILQ_INIT(&pipeline_list);
-
- return 0;
-}
-
-struct pipeline *
-pipeline_find(const char *name)
-{
- struct pipeline *pipeline;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(pipeline, &pipeline_list, node)
- if (strcmp(name, pipeline->name) == 0)
- return pipeline;
-
- return NULL;
-}
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params)
-{
- char msgq_name[NAME_MAX];
- struct rte_pipeline_params pp;
- struct pipeline *pipeline;
- struct rte_pipeline *p;
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- /* Check input params */
- if ((name == NULL) ||
- pipeline_find(name) ||
- (params == NULL) ||
- (params->timer_period_ms == 0))
- return NULL;
-
- /* Resource create */
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-REQ", name);
-
- msgq_req = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_req == NULL)
- return NULL;
-
- snprintf(msgq_name, sizeof(msgq_name), "%s-MSGQ-RSP", name);
-
- msgq_rsp = rte_ring_create(msgq_name,
- PIPELINE_MSGQ_SIZE,
- params->cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_rsp == NULL) {
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- pp.name = name;
- pp.socket_id = (int) params->cpu_id;
- pp.offset_port_id = params->offset_port_id;
-
- p = rte_pipeline_create(&pp);
- if (p == NULL) {
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node allocation */
- pipeline = calloc(1, sizeof(struct pipeline));
- if (pipeline == NULL) {
- rte_pipeline_free(p);
- rte_ring_free(msgq_rsp);
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(pipeline->name, name, sizeof(pipeline->name));
- pipeline->p = p;
- pipeline->n_ports_in = 0;
- pipeline->n_ports_out = 0;
- pipeline->n_tables = 0;
- pipeline->msgq_req = msgq_req;
- pipeline->msgq_rsp = msgq_rsp;
- pipeline->timer_period_ms = params->timer_period_ms;
- pipeline->enabled = 0;
- pipeline->cpu_id = params->cpu_id;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&pipeline_list, pipeline, node);
-
- return pipeline;
-}
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled)
-{
- struct rte_pipeline_port_in_params p;
-
- union {
- struct rte_port_ethdev_reader_params ethdev;
- struct rte_port_ring_reader_params ring;
- struct rte_port_sched_reader_params sched;
- struct rte_port_fd_reader_params fd;
- struct rte_port_source_params source;
- struct rte_port_sym_crypto_reader_params sym_crypto;
- } pp;
-
- struct pipeline *pipeline;
- struct port_in *port_in;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *action;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = port_in_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- switch (params->type) {
- case PORT_IN_RXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->rxq.queue_id >= link->n_rxq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->rxq.queue_id;
-
- p.ops = &rte_port_ethdev_reader_ops;
- p.arg_create = &pp.ethdev;
- break;
- }
-
- case PORT_IN_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
-
- p.ops = &rte_port_ring_reader_ops;
- p.arg_create = &pp.ring;
- break;
- }
-
- case PORT_IN_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
-
- p.ops = &rte_port_sched_reader_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_IN_TAP:
- {
- struct tap *tap;
- struct mempool *mempool;
-
- tap = tap_find(params->dev_name);
- mempool = mempool_find(params->tap.mempool_name);
- if ((tap == NULL) || (mempool == NULL))
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.mempool = mempool->m;
- pp.fd.mtu = params->tap.mtu;
-
- p.ops = &rte_port_fd_reader_ops;
- p.arg_create = &pp.fd;
- break;
- }
-
-
- case PORT_IN_SOURCE:
- {
- struct mempool *mempool;
-
- mempool = mempool_find(params->source.mempool_name);
- if (mempool == NULL)
- return -1;
-
- pp.source.mempool = mempool->m;
- pp.source.file_name = params->source.file_name;
- pp.source.n_bytes_per_pkt = params->source.n_bytes_per_pkt;
-
- p.ops = &rte_port_source_ops;
- p.arg_create = &pp.source;
- break;
- }
-
- case PORT_IN_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->rxq.queue_id > cryptodev->n_queues - 1)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.f_callback = params->cryptodev.f_callback;
- pp.sym_crypto.arg_callback = params->cryptodev.arg_callback;
- p.ops = &rte_port_sym_crypto_reader_ops;
- p.arg_create = &pp.sym_crypto;
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.burst_size = params->burst_size;
-
- /* Resource create */
- action = NULL;
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_port_in_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_port_in_action_params_get(
- action,
- &p);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
- }
-
- status = rte_pipeline_port_in_create(pipeline->p,
- &p,
- &port_id);
- if (status) {
- rte_port_in_action_free(action);
- return -1;
- }
-
- if (enabled)
- rte_pipeline_port_in_enable(pipeline->p, port_id);
-
- /* Pipeline */
- port_in = &pipeline->port_in[pipeline->n_ports_in];
- memcpy(&port_in->params, params, sizeof(*params));
- port_in->ap = ap;
- port_in->a = action;
- pipeline->n_ports_in++;
-
- return 0;
-}
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct pipeline *pipeline;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (port_id >= pipeline->n_ports_in) ||
- (table_id >= pipeline->n_tables))
- return -1;
-
- /* Resource */
- status = rte_pipeline_port_in_connect_to_table(pipeline->p,
- port_id,
- table_id);
-
- return status;
-
-}
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params)
-{
- struct rte_pipeline_port_out_params p;
-
- union {
- struct rte_port_ethdev_writer_params ethdev;
- struct rte_port_ring_writer_params ring;
- struct rte_port_sched_writer_params sched;
- struct rte_port_fd_writer_params fd;
- struct rte_port_sink_params sink;
- struct rte_port_sym_crypto_writer_params sym_crypto;
- } pp;
-
- union {
- struct rte_port_ethdev_writer_nodrop_params ethdev;
- struct rte_port_ring_writer_nodrop_params ring;
- struct rte_port_fd_writer_nodrop_params fd;
- struct rte_port_sym_crypto_writer_nodrop_params sym_crypto;
- } pp_nodrop;
-
- struct pipeline *pipeline;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
- memset(&pp_nodrop, 0, sizeof(pp_nodrop));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL) ||
- (params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- switch (params->type) {
- case PORT_OUT_TXQ:
- {
- struct link *link;
-
- link = link_find(params->dev_name);
- if (link == NULL)
- return -1;
-
- if (params->txq.queue_id >= link->n_txq)
- return -1;
-
- pp.ethdev.port_id = link->port_id;
- pp.ethdev.queue_id = params->txq.queue_id;
- pp.ethdev.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ethdev.port_id = link->port_id;
- pp_nodrop.ethdev.queue_id = params->txq.queue_id;
- pp_nodrop.ethdev.tx_burst_sz = params->burst_size;
- pp_nodrop.ethdev.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ethdev_writer_ops;
- p.arg_create = &pp.ethdev;
- } else {
- p.ops = &rte_port_ethdev_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ethdev;
- }
- break;
- }
-
- case PORT_OUT_SWQ:
- {
- struct swq *swq;
-
- swq = swq_find(params->dev_name);
- if (swq == NULL)
- return -1;
-
- pp.ring.ring = swq->r;
- pp.ring.tx_burst_sz = params->burst_size;
-
- pp_nodrop.ring.ring = swq->r;
- pp_nodrop.ring.tx_burst_sz = params->burst_size;
- pp_nodrop.ring.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_ring_writer_ops;
- p.arg_create = &pp.ring;
- } else {
- p.ops = &rte_port_ring_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.ring;
- }
- break;
- }
-
- case PORT_OUT_TMGR:
- {
- struct tmgr_port *tmgr_port;
-
- tmgr_port = tmgr_port_find(params->dev_name);
- if (tmgr_port == NULL)
- return -1;
-
- pp.sched.sched = tmgr_port->s;
- pp.sched.tx_burst_sz = params->burst_size;
-
- p.ops = &rte_port_sched_writer_ops;
- p.arg_create = &pp.sched;
- break;
- }
-
- case PORT_OUT_TAP:
- {
- struct tap *tap;
-
- tap = tap_find(params->dev_name);
- if (tap == NULL)
- return -1;
-
- pp.fd.fd = tap->fd;
- pp.fd.tx_burst_sz = params->burst_size;
-
- pp_nodrop.fd.fd = tap->fd;
- pp_nodrop.fd.tx_burst_sz = params->burst_size;
- pp_nodrop.fd.n_retries = params->n_retries;
-
- if (params->retry == 0) {
- p.ops = &rte_port_fd_writer_ops;
- p.arg_create = &pp.fd;
- } else {
- p.ops = &rte_port_fd_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.fd;
- }
- break;
- }
-
-
- case PORT_OUT_SINK:
- {
- pp.sink.file_name = params->sink.file_name;
- pp.sink.max_n_pkts = params->sink.max_n_pkts;
-
- p.ops = &rte_port_sink_ops;
- p.arg_create = &pp.sink;
- break;
- }
-
- case PORT_OUT_CRYPTODEV:
- {
- struct cryptodev *cryptodev;
-
- cryptodev = cryptodev_find(params->dev_name);
- if (cryptodev == NULL)
- return -1;
-
- if (params->cryptodev.queue_id >= cryptodev->n_queues)
- return -1;
-
- pp.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp.sym_crypto.tx_burst_sz = params->burst_size;
- pp.sym_crypto.crypto_op_offset = params->cryptodev.op_offset;
-
- pp_nodrop.sym_crypto.cryptodev_id = cryptodev->dev_id;
- pp_nodrop.sym_crypto.queue_id = params->cryptodev.queue_id;
- pp_nodrop.sym_crypto.tx_burst_sz = params->burst_size;
- pp_nodrop.sym_crypto.n_retries = params->retry;
- pp_nodrop.sym_crypto.crypto_op_offset =
- params->cryptodev.op_offset;
-
- if (params->retry == 0) {
- p.ops = &rte_port_sym_crypto_writer_ops;
- p.arg_create = &pp.sym_crypto;
- } else {
- p.ops = &rte_port_sym_crypto_writer_nodrop_ops;
- p.arg_create = &pp_nodrop.sym_crypto;
- }
-
- break;
- }
-
- default:
- return -1;
- }
-
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- /* Resource create */
- status = rte_pipeline_port_out_create(pipeline->p,
- &p,
- &port_id);
-
- if (status)
- return -1;
-
- /* Pipeline */
- pipeline->n_ports_out++;
-
- return 0;
-}
-
-static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
-
- /* Source IP address (IPv4) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv4_hdr, src_addr),
- },
-
- /* Destination IP address (IPv4) */
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv4_hdr, dst_addr),
- },
-
- /* Source Port */
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 3,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 4,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv6_hdr, proto),
- },
-
- /* Source IP address (IPv6) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[0]),
- },
-
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[4]),
- },
-
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 3,
- .input_index = 3,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[8]),
- },
-
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 4,
- .input_index = 4,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr.a[12]),
- },
-
- /* Destination IP address (IPv6) */
- [5] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 5,
- .input_index = 5,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[0]),
- },
-
- [6] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 6,
- .input_index = 6,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[4]),
- },
-
- [7] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 7,
- .input_index = 7,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[8]),
- },
-
- [8] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 8,
- .input_index = 8,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr.a[12]),
- },
-
- /* Source Port */
- [9] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 9,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [10] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 10,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params)
-{
- char name[NAME_MAX];
- struct rte_pipeline_table_params p;
-
- union {
- struct rte_table_acl_params acl;
- struct rte_table_array_params array;
- struct rte_table_hash_params hash;
- struct rte_table_lpm_params lpm;
- struct rte_table_lpm_ipv6_params lpm_ipv6;
- } pp;
-
- struct pipeline *pipeline;
- struct table *table;
- struct table_action_profile *ap;
- struct rte_table_action *action;
- uint32_t table_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (params == NULL))
- return -1;
-
- pipeline = pipeline_find(pipeline_name);
- if ((pipeline == NULL) ||
- (pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX))
- return -1;
-
- ap = NULL;
- if (params->action_profile_name) {
- ap = table_action_profile_find(params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- snprintf(name, NAME_MAX, "%s_table%u",
- pipeline_name, pipeline->n_tables);
-
- switch (params->match_type) {
- case TABLE_ACL:
- {
- uint32_t ip_header_offset = params->match.acl.ip_header_offset -
- (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
- uint32_t i;
-
- if (params->match.acl.n_rules == 0)
- return -1;
-
- pp.acl.name = name;
- pp.acl.n_rules = params->match.acl.n_rules;
- if (params->match.acl.ip_version) {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv4,
- sizeof(table_acl_field_format_ipv4));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv4);
- } else {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv6,
- sizeof(table_acl_field_format_ipv6));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv6);
- }
-
- for (i = 0; i < pp.acl.n_rule_fields; i++)
- pp.acl.field_format[i].offset += ip_header_offset;
-
- p.ops = &rte_table_acl_ops;
- p.arg_create = &pp.acl;
- break;
- }
-
- case TABLE_ARRAY:
- {
- if (params->match.array.n_keys == 0)
- return -1;
-
- pp.array.n_entries = params->match.array.n_keys;
- pp.array.offset = params->match.array.key_offset;
-
- p.ops = &rte_table_array_ops;
- p.arg_create = &pp.array;
- break;
- }
-
- case TABLE_HASH:
- {
- struct rte_table_ops *ops;
- rte_table_hash_op_hash f_hash;
-
- if (params->match.hash.n_keys == 0)
- return -1;
-
- switch (params->match.hash.key_size) {
- case 8:
- f_hash = rte_table_hash_crc_key8;
- break;
- case 16:
- f_hash = rte_table_hash_crc_key16;
- break;
- case 24:
- f_hash = rte_table_hash_crc_key24;
- break;
- case 32:
- f_hash = rte_table_hash_crc_key32;
- break;
- case 40:
- f_hash = rte_table_hash_crc_key40;
- break;
- case 48:
- f_hash = rte_table_hash_crc_key48;
- break;
- case 56:
- f_hash = rte_table_hash_crc_key56;
- break;
- case 64:
- f_hash = rte_table_hash_crc_key64;
- break;
- default:
- return -1;
- }
-
- pp.hash.name = name;
- pp.hash.key_size = params->match.hash.key_size;
- pp.hash.key_offset = params->match.hash.key_offset;
- pp.hash.key_mask = params->match.hash.key_mask;
- pp.hash.n_keys = params->match.hash.n_keys;
- pp.hash.n_buckets = params->match.hash.n_buckets;
- pp.hash.f_hash = f_hash;
- pp.hash.seed = 0;
-
- if (params->match.hash.extendable_bucket)
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_ext_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_ext_ops;
- break;
- default:
- ops = &rte_table_hash_ext_ops;
- }
- else
- switch (params->match.hash.key_size) {
- case 8:
- ops = &rte_table_hash_key8_lru_ops;
- break;
- case 16:
- ops = &rte_table_hash_key16_lru_ops;
- break;
- default:
- ops = &rte_table_hash_lru_ops;
- }
-
- p.ops = ops;
- p.arg_create = &pp.hash;
- break;
- }
-
- case TABLE_LPM:
- {
- if (params->match.lpm.n_rules == 0)
- return -1;
-
- switch (params->match.lpm.key_size) {
- case 4:
- {
- pp.lpm.name = name;
- pp.lpm.n_rules = params->match.lpm.n_rules;
- pp.lpm.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm.flags = 0;
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ops;
- p.arg_create = &pp.lpm;
- break;
- }
-
- case 16:
- {
- pp.lpm_ipv6.name = name;
- pp.lpm_ipv6.n_rules = params->match.lpm.n_rules;
- pp.lpm_ipv6.number_tbl8s = TABLE_LPM_NUMBER_TBL8;
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- pp.lpm_ipv6.offset = params->match.lpm.key_offset;
-
- p.ops = &rte_table_lpm_ipv6_ops;
- p.arg_create = &pp.lpm_ipv6;
- break;
- }
-
- default:
- return -1;
- }
-
- break;
- }
-
- case TABLE_STUB:
- {
- p.ops = &rte_table_stub_ops;
- p.arg_create = NULL;
- break;
- }
-
- default:
- return -1;
- }
-
- /* Resource create */
- action = NULL;
- p.f_action_hit = NULL;
- p.f_action_miss = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_table_action_create(ap->ap,
- pipeline->cpu_id);
- if (action == NULL)
- return -1;
-
- status = rte_table_action_table_params_get(
- action,
- &p);
- if (status ||
- ((p.action_data_size +
- sizeof(struct rte_pipeline_table_entry)) >
- TABLE_RULE_ACTION_SIZE_MAX)) {
- rte_table_action_free(action);
- return -1;
- }
- }
-
- if (params->match_type == TABLE_LPM) {
- if (params->match.lpm.key_size == 4)
- pp.lpm.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
-
- if (params->match.lpm.key_size == 16)
- pp.lpm_ipv6.entry_unique_size = p.action_data_size +
- sizeof(struct rte_pipeline_table_entry);
- }
-
- status = rte_pipeline_table_create(pipeline->p,
- &p,
- &table_id);
- if (status) {
- rte_table_action_free(action);
- return -1;
- }
-
- /* Pipeline */
- table = &pipeline->table[pipeline->n_tables];
- memcpy(&table->params, params, sizeof(*params));
- table->ap = ap;
- table->a = action;
- TAILQ_INIT(&table->rules);
- table->rule_default = NULL;
-
- pipeline->n_tables++;
-
- return 0;
-}
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- TAILQ_FOREACH(rule, &table->rules, node)
- if (memcmp(&rule->match, match, sizeof(*match)) == 0)
- return rule;
-
- return NULL;
-}
-
-void
-table_rule_add(struct table *table,
- struct table_rule *new_rule)
-{
- struct table_rule *existing_rule;
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
-}
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules)
-{
- uint32_t i;
-
- for (i = 0; i < n_rules; i++) {
- struct table_rule *existing_rule, *new_rule;
-
- new_rule = TAILQ_FIRST(list);
- if (new_rule == NULL)
- break;
-
- TAILQ_REMOVE(list, new_rule, node);
-
- existing_rule = table_rule_find(table, &new_rule->match);
- if (existing_rule == NULL)
- TAILQ_INSERT_TAIL(&table->rules, new_rule, node);
- else {
- TAILQ_INSERT_AFTER(&table->rules, existing_rule, new_rule, node);
- TAILQ_REMOVE(&table->rules, existing_rule, node);
- free(existing_rule);
- }
- }
-}
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match)
-{
- struct table_rule *rule;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return;
-
- TAILQ_REMOVE(&table->rules, rule, node);
- free(rule);
-}
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule)
-{
- free(table->rule_default);
- table->rule_default = rule;
-}
-
-void
-table_rule_default_delete(struct table *table)
-{
- free(table->rule_default);
- table->rule_default = NULL;
-}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
deleted file mode 100644
index 89696480fc01b91da389db29790d44d518a37a18..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/pipeline.h
+++ /dev/null
@@ -1,425 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_PIPELINE_H_
-#define _INCLUDE_PIPELINE_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_pipeline.h>
-#include <rte_table_action.h>
-
-#include "common.h"
-#include "action.h"
-
-struct pipeline_params {
- uint32_t timer_period_ms;
- uint32_t offset_port_id;
- uint32_t cpu_id;
-};
-
-enum port_in_type {
- PORT_IN_RXQ,
- PORT_IN_SWQ,
- PORT_IN_TMGR,
- PORT_IN_TAP,
- PORT_IN_SOURCE,
- PORT_IN_CRYPTODEV,
-};
-
-struct port_in_params {
- /* Read */
- enum port_in_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } rxq;
-
- struct {
- const char *mempool_name;
- uint32_t mtu;
- } tap;
-
- struct {
- const char *mempool_name;
- const char *file_name;
- uint32_t n_bytes_per_pkt;
- } source;
-
- struct {
- uint16_t queue_id;
- void *f_callback;
- void *arg_callback;
- } cryptodev;
- };
- uint32_t burst_size;
-
- /* Action */
- const char *action_profile_name;
-};
-
-enum port_out_type {
- PORT_OUT_TXQ,
- PORT_OUT_SWQ,
- PORT_OUT_TMGR,
- PORT_OUT_TAP,
- PORT_OUT_SINK,
- PORT_OUT_CRYPTODEV,
-};
-
-struct port_out_params {
- enum port_out_type type;
- const char *dev_name;
- union {
- struct {
- uint16_t queue_id;
- } txq;
-
- struct {
- const char *file_name;
- uint32_t max_n_pkts;
- } sink;
-
- struct {
- uint16_t queue_id;
- uint32_t op_offset;
- } cryptodev;
- };
- uint32_t burst_size;
- int retry;
- uint32_t n_retries;
-};
-
-enum table_type {
- TABLE_ACL,
- TABLE_ARRAY,
- TABLE_HASH,
- TABLE_LPM,
- TABLE_STUB,
-};
-
-struct table_acl_params {
- uint32_t n_rules;
- uint32_t ip_header_offset;
- int ip_version;
-};
-
-struct table_array_params {
- uint32_t n_keys;
- uint32_t key_offset;
-};
-
-struct table_hash_params {
- uint32_t n_keys;
- uint32_t key_offset;
- uint32_t key_size;
- uint8_t *key_mask;
- uint32_t n_buckets;
- int extendable_bucket;
-};
-
-struct table_lpm_params {
- uint32_t n_rules;
- uint32_t key_offset;
- uint32_t key_size;
-};
-
-struct table_params {
- /* Match */
- enum table_type match_type;
- union {
- struct table_acl_params acl;
- struct table_array_params array;
- struct table_hash_params hash;
- struct table_lpm_params lpm;
- } match;
-
- /* Action */
- const char *action_profile_name;
-};
-
-struct table_rule;
-
-TAILQ_HEAD(table_rule_list, table_rule);
-
-struct port_in {
- struct port_in_params params;
- struct port_in_action_profile *ap;
- struct rte_port_in_action *a;
-};
-
-struct table {
- struct table_params params;
- struct table_action_profile *ap;
- struct rte_table_action *a;
- struct table_rule_list rules;
- struct table_rule *rule_default;
-};
-
-struct pipeline {
- TAILQ_ENTRY(pipeline) node;
- char name[NAME_SIZE];
-
- struct rte_pipeline *p;
- struct port_in port_in[RTE_PIPELINE_PORT_IN_MAX];
- struct table table[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
-
- int enabled;
- uint32_t thread_id;
- uint32_t cpu_id;
-};
-
-TAILQ_HEAD(pipeline_list, pipeline);
-
-int
-pipeline_init(void);
-
-struct pipeline *
-pipeline_find(const char *name);
-
-struct pipeline *
-pipeline_create(const char *name, struct pipeline_params *params);
-
-int
-pipeline_port_in_create(const char *pipeline_name,
- struct port_in_params *params,
- int enabled);
-
-int
-pipeline_port_in_connect_to_table(const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id);
-
-int
-pipeline_port_out_create(const char *pipeline_name,
- struct port_out_params *params);
-
-int
-pipeline_table_create(const char *pipeline_name,
- struct table_params *params);
-
-struct table_rule_match_acl {
- int ip_version;
-
- union {
- struct {
- uint32_t sa;
- uint32_t da;
- } ipv4;
-
- struct {
- struct rte_ipv6_addr sa;
- struct rte_ipv6_addr da;
- } ipv6;
- };
-
- uint32_t sa_depth;
- uint32_t da_depth;
- uint16_t sp0;
- uint16_t sp1;
- uint16_t dp0;
- uint16_t dp1;
- uint8_t proto;
- uint8_t proto_mask;
- uint32_t priority;
-};
-
-struct table_rule_match_array {
- uint32_t pos;
-};
-
-#ifndef TABLE_RULE_MATCH_SIZE_MAX
-#define TABLE_RULE_MATCH_SIZE_MAX 256
-#endif
-
-#ifndef TABLE_RULE_ACTION_SIZE_MAX
-#define TABLE_RULE_ACTION_SIZE_MAX 2048
-#endif
-
-struct table_rule_match_hash {
- uint8_t key[TABLE_RULE_MATCH_SIZE_MAX];
-};
-
-struct table_rule_match_lpm {
- int ip_version;
-
- union {
- uint32_t ipv4;
- struct rte_ipv6_addr ipv6;
- };
-
- uint8_t depth;
-};
-
-struct table_rule_match {
- enum table_type match_type;
-
- union {
- struct table_rule_match_acl acl;
- struct table_rule_match_array array;
- struct table_rule_match_hash hash;
- struct table_rule_match_lpm lpm;
- } match;
-};
-
-#ifndef SYM_CRYPTO_MAX_KEY_SIZE
-#define SYM_CRYPTO_MAX_KEY_SIZE (256)
-#endif
-
-struct table_rule_action {
- uint64_t action_mask;
- struct rte_table_action_fwd_params fwd;
- struct rte_table_action_lb_params lb;
- struct rte_table_action_mtr_params mtr;
- struct rte_table_action_tm_params tm;
- struct rte_table_action_encap_params encap;
- struct rte_table_action_nat_params nat;
- struct rte_table_action_ttl_params ttl;
- struct rte_table_action_stats_params stats;
- struct rte_table_action_time_params time;
- struct rte_table_action_sym_crypto_params sym_crypto;
- uint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];
- struct rte_table_action_tag_params tag;
- struct rte_table_action_decap_params decap;
-
-};
-
-struct table_rule {
- TAILQ_ENTRY(table_rule) node;
- struct table_rule_match match;
- struct table_rule_action action;
- void *data;
-};
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear);
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id);
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear);
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear);
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added);
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action);
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match);
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id);
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id);
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table);
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp);
-
-struct table_rule *
-table_rule_find(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_add_bulk(struct table *table,
- struct table_rule_list *list,
- uint32_t n_rules);
-
-void
-table_rule_delete(struct table *table,
- struct table_rule_match *match);
-
-void
-table_rule_default_add(struct table *table,
- struct table_rule *rule);
-
-void
-table_rule_default_delete(struct table *table);
-
-#endif /* _INCLUDE_PIPELINE_H_ */
diff --git a/examples/ip_pipeline/swq.c b/examples/ip_pipeline/swq.c
deleted file mode 100644
index 7e54a1dbfe0428e26a5ba77a40f469a465c2f75b..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/swq.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-
-#include "swq.h"
-
-static struct swq_list swq_list;
-
-int
-swq_init(void)
-{
- TAILQ_INIT(&swq_list);
-
- return 0;
-}
-
-struct swq *
-swq_find(const char *name)
-{
- struct swq *swq;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(swq, &swq_list, node)
- if (strcmp(swq->name, name) == 0)
- return swq;
-
- return NULL;
-}
-
-struct swq *
-swq_create(const char *name, struct swq_params *params)
-{
- struct swq *swq;
- struct rte_ring *r;
- unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ;
-
- /* Check input params */
- if ((name == NULL) ||
- swq_find(name) ||
- (params == NULL) ||
- (params->size == 0))
- return NULL;
-
- /* Resource create */
- r = rte_ring_create(
- name,
- params->size,
- params->cpu_id,
- flags);
-
- if (r == NULL)
- return NULL;
-
- /* Node allocation */
- swq = calloc(1, sizeof(struct swq));
- if (swq == NULL) {
- rte_ring_free(r);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(swq->name, name, sizeof(swq->name));
- swq->r = r;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&swq_list, swq, node);
-
- return swq;
-}
diff --git a/examples/ip_pipeline/swq.h b/examples/ip_pipeline/swq.h
deleted file mode 100644
index c8440ee3cd89590cb157f29f3586a69220765cbf..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/swq.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_SWQ_H_
-#define _INCLUDE_SWQ_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_ring.h>
-
-#include "common.h"
-
-struct swq {
- TAILQ_ENTRY(swq) node;
- char name[NAME_SIZE];
- struct rte_ring *r;
-};
-
-TAILQ_HEAD(swq_list, swq);
-
-int
-swq_init(void);
-
-struct swq *
-swq_find(const char *name);
-
-struct swq_params {
- uint32_t size;
- uint32_t cpu_id;
-};
-
-struct swq *
-swq_create(const char *name, struct swq_params *params);
-
-#endif /* _INCLUDE_SWQ_H_ */
diff --git a/examples/ip_pipeline/tap.c b/examples/ip_pipeline/tap.c
deleted file mode 100644
index adae640c1e6b4a3d11d2cbdd962cf54384bb1c2f..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/tap.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <netinet/in.h>
-#ifdef RTE_EXEC_ENV_LINUX
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <rte_string_fns.h>
-
-#include "tap.h"
-
-#define TAP_DEV "/dev/net/tun"
-
-static struct tap_list tap_list;
-
-int
-tap_init(void)
-{
- TAILQ_INIT(&tap_list);
-
- return 0;
-}
-
-struct tap *
-tap_find(const char *name)
-{
- struct tap *tap;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tap, &tap_list, node)
- if (strcmp(tap->name, name) == 0)
- return tap;
-
- return NULL;
-}
-
-#ifndef RTE_EXEC_ENV_LINUX
-
-struct tap *
-tap_create(const char *name __rte_unused)
-{
- return NULL;
-}
-
-#else
-
-struct tap *
-tap_create(const char *name)
-{
- struct tap *tap;
- struct ifreq ifr;
- int fd, status;
-
- /* Check input params */
- if ((name == NULL) ||
- tap_find(name))
- return NULL;
-
- /* Resource create */
- fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
- if (fd < 0)
- return NULL;
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
- strlcpy(ifr.ifr_name, name, IFNAMSIZ);
-
- status = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (status < 0) {
- close(fd);
- return NULL;
- }
-
- /* Node allocation */
- tap = calloc(1, sizeof(struct tap));
- if (tap == NULL) {
- close(fd);
- return NULL;
- }
- /* Node fill in */
- strlcpy(tap->name, name, sizeof(tap->name));
- tap->fd = fd;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tap_list, tap, node);
-
- return tap;
-}
-
-#endif
diff --git a/examples/ip_pipeline/tap.h b/examples/ip_pipeline/tap.h
deleted file mode 100644
index 0dce72fe3c989ac5443c8037fe2bb929b27a5bb7..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/tap.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TAP_H_
-#define _INCLUDE_TAP_H_
-
-#include <sys/queue.h>
-
-#include "common.h"
-
-struct tap {
- TAILQ_ENTRY(tap) node;
- char name[NAME_SIZE];
- int fd;
-};
-
-TAILQ_HEAD(tap_list, tap);
-
-int
-tap_init(void);
-
-struct tap *
-tap_find(const char *name);
-
-struct tap *
-tap_create(const char *name);
-
-#endif /* _INCLUDE_TAP_H_ */
diff --git a/examples/ip_pipeline/thread.c b/examples/ip_pipeline/thread.c
deleted file mode 100644
index 0a44bddd90fcd190bd8c7a93fba3c02c74fc3e89..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/thread.c
+++ /dev/null
@@ -1,3137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_lcore.h>
-#include <rte_ring.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-
-#include "common.h"
-#include "thread.h"
-#include "pipeline.h"
-
-#ifndef THREAD_PIPELINES_MAX
-#define THREAD_PIPELINES_MAX 256
-#endif
-
-#ifndef THREAD_MSGQ_SIZE
-#define THREAD_MSGQ_SIZE 64
-#endif
-
-#ifndef THREAD_TIMER_PERIOD_MS
-#define THREAD_TIMER_PERIOD_MS 100
-#endif
-
-/**
- * Main thread: data plane thread context
- */
-struct thread {
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
-
- uint32_t enabled;
-};
-
-static struct thread thread[RTE_MAX_LCORE];
-
-/**
- * Data plane threads: context
- */
-struct table_data {
- struct rte_table_action *a;
-};
-
-struct pipeline_data {
- struct rte_pipeline *p;
- struct table_data table_data[RTE_PIPELINE_TABLE_MAX];
- uint32_t n_tables;
-
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
-
- uint8_t buffer[TABLE_RULE_ACTION_SIZE_MAX];
-};
-
-struct __rte_cache_aligned thread_data {
- struct rte_pipeline *p[THREAD_PIPELINES_MAX];
- uint32_t n_pipelines;
-
- struct pipeline_data pipeline_data[THREAD_PIPELINES_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint64_t timer_period; /* Measured in CPU cycles. */
- uint64_t time_next;
- uint64_t time_next_min;
-};
-
-static struct thread_data thread_data[RTE_MAX_LCORE];
-
-/**
- * Main thread: data plane thread init
- */
-static void
-thread_free(void)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_MAX_LCORE; i++) {
- struct thread *t = &thread[i];
-
- if (!rte_lcore_is_enabled(i))
- continue;
-
- /* MSGQs */
- rte_ring_free(t->msgq_req);
-
- rte_ring_free(t->msgq_rsp);
- }
-}
-
-int
-thread_init(void)
-{
- uint32_t i;
-
- RTE_LCORE_FOREACH_WORKER(i) {
- char name[NAME_MAX];
- struct rte_ring *msgq_req, *msgq_rsp;
- struct thread *t = &thread[i];
- struct thread_data *t_data = &thread_data[i];
- uint32_t cpu_id = rte_lcore_to_socket_id(i);
-
- /* MSGQs */
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-REQ", i);
-
- msgq_req = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_req == NULL) {
- thread_free();
- return -1;
- }
-
- snprintf(name, sizeof(name), "THREAD-%04x-MSGQ-RSP", i);
-
- msgq_rsp = rte_ring_create(name,
- THREAD_MSGQ_SIZE,
- cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (msgq_rsp == NULL) {
- thread_free();
- return -1;
- }
-
- /* Main thread records */
- t->msgq_req = msgq_req;
- t->msgq_rsp = msgq_rsp;
- t->enabled = 1;
-
- /* Data plane thread records */
- t_data->n_pipelines = 0;
- t_data->msgq_req = msgq_req;
- t_data->msgq_rsp = msgq_rsp;
- t_data->timer_period =
- (rte_get_tsc_hz() * THREAD_TIMER_PERIOD_MS) / 1000;
- t_data->time_next = rte_get_tsc_cycles() + t_data->timer_period;
- t_data->time_next_min = t_data->time_next;
- }
-
- return 0;
-}
-
-static inline int
-thread_is_running(uint32_t thread_id)
-{
- enum rte_lcore_state_t thread_state;
-
- thread_state = rte_eal_get_lcore_state(thread_id);
- return (thread_state == RUNNING) ? 1 : 0;
-}
-
-/**
- * Pipeline is running when:
- * (A) Pipeline is mapped to a data plane thread AND
- * (B) Its data plane thread is in RUNNING state.
- */
-static inline int
-pipeline_is_running(struct pipeline *p)
-{
- if (p->enabled == 0)
- return 0;
-
- return thread_is_running(p->thread_id);
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum thread_req_type {
- THREAD_REQ_PIPELINE_ENABLE = 0,
- THREAD_REQ_PIPELINE_DISABLE,
- THREAD_REQ_MAX
-};
-
-struct thread_msg_req {
- enum thread_req_type type;
-
- union {
- struct {
- struct rte_pipeline *p;
- struct {
- struct rte_table_action *a;
- } table[RTE_PIPELINE_TABLE_MAX];
- struct rte_ring *msgq_req;
- struct rte_ring *msgq_rsp;
- uint32_t timer_period_ms;
- uint32_t n_tables;
- } pipeline_enable;
-
- struct {
- struct rte_pipeline *p;
- } pipeline_disable;
- };
-};
-
-struct thread_msg_rsp {
- int status;
-};
-
-/**
- * Main thread
- */
-static struct thread_msg_req *
-thread_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct thread_msg_req),
- sizeof(struct thread_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-thread_msg_free(struct thread_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct thread_msg_rsp *
-thread_msg_send_recv(uint32_t thread_id,
- struct thread_msg_req *req)
-{
- struct thread *t = &thread[thread_id];
- struct rte_ring *msgq_req = t->msgq_req;
- struct rte_ring *msgq_rsp = t->msgq_rsp;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- uint32_t i;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL) ||
- (p->n_ports_in == 0) ||
- (p->n_ports_out == 0) ||
- (p->n_tables == 0))
- return -1;
-
- t = &thread[thread_id];
- if ((t->enabled == 0) ||
- p->enabled)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- struct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];
-
- if (td->n_pipelines >= THREAD_PIPELINES_MAX)
- return -1;
-
- /* Data plane thread */
- td->p[td->n_pipelines] = p->p;
-
- tdp->p = p->p;
- for (i = 0; i < p->n_tables; i++)
- tdp->table_data[i].a = p->table[i].a;
-
- tdp->n_tables = p->n_tables;
-
- tdp->msgq_req = p->msgq_req;
- tdp->msgq_rsp = p->msgq_rsp;
- tdp->timer_period = (rte_get_tsc_hz() * p->timer_period_ms) / 1000;
- tdp->time_next = rte_get_tsc_cycles() + tdp->timer_period;
-
- td->n_pipelines++;
-
- /* Pipeline */
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_ENABLE;
- req->pipeline_enable.p = p->p;
- for (i = 0; i < p->n_tables; i++)
- req->pipeline_enable.table[i].a =
- p->table[i].a;
- req->pipeline_enable.msgq_req = p->msgq_req;
- req->pipeline_enable.msgq_rsp = p->msgq_rsp;
- req->pipeline_enable.timer_period_ms = p->timer_period_ms;
- req->pipeline_enable.n_tables = p->n_tables;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->thread_id = thread_id;
- p->enabled = 1;
-
- return 0;
-}
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name)
-{
- struct pipeline *p = pipeline_find(pipeline_name);
- struct thread *t;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((thread_id >= RTE_MAX_LCORE) ||
- (p == NULL))
- return -1;
-
- t = &thread[thread_id];
- if (t->enabled == 0)
- return -1;
-
- if (p->enabled == 0)
- return 0;
-
- if (p->thread_id != thread_id)
- return -1;
-
- if (!thread_is_running(thread_id)) {
- struct thread_data *td = &thread_data[thread_id];
- uint32_t i;
-
- for (i = 0; i < td->n_pipelines; i++) {
- struct pipeline_data *tdp = &td->pipeline_data[i];
-
- if (tdp->p != p->p)
- continue;
-
- /* Data plane thread */
- if (i < td->n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- td->p[td->n_pipelines - 1];
- struct pipeline_data *tdp_last =
- &td->pipeline_data[td->n_pipelines - 1];
-
- td->p[i] = pipeline_last;
- memcpy(tdp, tdp_last, sizeof(*tdp));
- }
-
- td->n_pipelines--;
-
- /* Pipeline */
- p->enabled = 0;
-
- break;
- }
-
- return 0;
- }
-
- /* Allocate request */
- req = thread_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = THREAD_REQ_PIPELINE_DISABLE;
- req->pipeline_disable.p = p->p;
-
- /* Send request and wait for response */
- rsp = thread_msg_send_recv(thread_id, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- thread_msg_free(rsp);
-
- /* Request completion */
- if (status)
- return status;
-
- p->enabled = 0;
-
- return 0;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct thread_msg_req *
-thread_msg_recv(struct rte_ring *msgq_req)
-{
- struct thread_msg_req *req = NULL;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-thread_msg_send(struct rte_ring *msgq_rsp,
- struct thread_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_enable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- struct pipeline_data *p = &t->pipeline_data[t->n_pipelines];
- uint32_t i;
-
- /* Request */
- if (t->n_pipelines >= THREAD_PIPELINES_MAX) {
- rsp->status = -1;
- return rsp;
- }
-
- t->p[t->n_pipelines] = req->pipeline_enable.p;
-
- p->p = req->pipeline_enable.p;
- for (i = 0; i < req->pipeline_enable.n_tables; i++)
- p->table_data[i].a =
- req->pipeline_enable.table[i].a;
-
- p->n_tables = req->pipeline_enable.n_tables;
-
- p->msgq_req = req->pipeline_enable.msgq_req;
- p->msgq_rsp = req->pipeline_enable.msgq_rsp;
- p->timer_period =
- (rte_get_tsc_hz() * req->pipeline_enable.timer_period_ms) / 1000;
- p->time_next = rte_get_tsc_cycles() + p->timer_period;
-
- t->n_pipelines++;
-
- /* Response */
- rsp->status = 0;
- return rsp;
-}
-
-static struct thread_msg_rsp *
-thread_msg_handle_pipeline_disable(struct thread_data *t,
- struct thread_msg_req *req)
-{
- struct thread_msg_rsp *rsp = (struct thread_msg_rsp *) req;
- uint32_t n_pipelines = t->n_pipelines;
- struct rte_pipeline *pipeline = req->pipeline_disable.p;
- uint32_t i;
-
- /* find pipeline */
- for (i = 0; i < n_pipelines; i++) {
- struct pipeline_data *p = &t->pipeline_data[i];
-
- if (p->p != pipeline)
- continue;
-
- if (i < n_pipelines - 1) {
- struct rte_pipeline *pipeline_last =
- t->p[n_pipelines - 1];
- struct pipeline_data *p_last =
- &t->pipeline_data[n_pipelines - 1];
-
- t->p[i] = pipeline_last;
- memcpy(p, p_last, sizeof(*p));
- }
-
- t->n_pipelines--;
-
- rsp->status = 0;
- return rsp;
- }
-
- /* should not get here */
- rsp->status = 0;
- return rsp;
-}
-
-static void
-thread_msg_handle(struct thread_data *t)
-{
- for ( ; ; ) {
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
-
- req = thread_msg_recv(t->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case THREAD_REQ_PIPELINE_ENABLE:
- rsp = thread_msg_handle_pipeline_enable(t, req);
- break;
-
- case THREAD_REQ_PIPELINE_DISABLE:
- rsp = thread_msg_handle_pipeline_disable(t, req);
- break;
-
- default:
- rsp = (struct thread_msg_rsp *) req;
- rsp->status = -1;
- }
-
- thread_msg_send(t->msgq_rsp, rsp);
- }
-}
-
-/**
- * Main thread & data plane threads: message passing
- */
-enum pipeline_req_type {
- /* Port IN */
- PIPELINE_REQ_PORT_IN_STATS_READ,
- PIPELINE_REQ_PORT_IN_ENABLE,
- PIPELINE_REQ_PORT_IN_DISABLE,
-
- /* Port OUT */
- PIPELINE_REQ_PORT_OUT_STATS_READ,
-
- /* Table */
- PIPELINE_REQ_TABLE_STATS_READ,
- PIPELINE_REQ_TABLE_RULE_ADD,
- PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_ADD_BULK,
- PIPELINE_REQ_TABLE_RULE_DELETE,
- PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_STATS_READ,
- PIPELINE_REQ_TABLE_MTR_PROFILE_ADD,
- PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE,
- PIPELINE_REQ_TABLE_RULE_MTR_READ,
- PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,
- PIPELINE_REQ_TABLE_RULE_TTL_READ,
- PIPELINE_REQ_TABLE_RULE_TIME_READ,
- PIPELINE_REQ_MAX
-};
-
-struct pipeline_msg_req_port_in_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_port_out_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_stats_read {
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_add {
- struct table_rule_match match;
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_default {
- struct table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_bulk {
- struct table_rule_list *list;
- int bulk;
-};
-
-struct pipeline_msg_req_table_rule_delete {
- struct table_rule_match match;
-};
-
-struct pipeline_msg_req_table_rule_stats_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_mtr_profile_add {
- uint32_t meter_profile_id;
- struct rte_table_action_meter_profile profile;
-};
-
-struct pipeline_msg_req_table_mtr_profile_delete {
- uint32_t meter_profile_id;
-};
-
-struct pipeline_msg_req_table_rule_mtr_read {
- void *data;
- uint32_t tc_mask;
- int clear;
-};
-
-struct pipeline_msg_req_table_dscp_table_update {
- uint64_t dscp_mask;
- struct rte_table_action_dscp_table dscp_table;
-};
-
-struct pipeline_msg_req_table_rule_ttl_read {
- void *data;
- int clear;
-};
-
-struct pipeline_msg_req_table_rule_time_read {
- void *data;
-};
-
-struct pipeline_msg_req {
- enum pipeline_req_type type;
- uint32_t id; /* Port IN, port OUT or table ID */
-
- union {
- struct pipeline_msg_req_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_req_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_req_table_stats_read table_stats_read;
- struct pipeline_msg_req_table_rule_add table_rule_add;
- struct pipeline_msg_req_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_req_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_req_table_rule_delete table_rule_delete;
- struct pipeline_msg_req_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_req_table_mtr_profile_add table_mtr_profile_add;
- struct pipeline_msg_req_table_mtr_profile_delete table_mtr_profile_delete;
- struct pipeline_msg_req_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_req_table_dscp_table_update table_dscp_table_update;
- struct pipeline_msg_req_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_req_table_rule_time_read table_rule_time_read;
- };
-};
-
-struct pipeline_msg_rsp_port_in_stats_read {
- struct rte_pipeline_port_in_stats stats;
-};
-
-struct pipeline_msg_rsp_port_out_stats_read {
- struct rte_pipeline_port_out_stats stats;
-};
-
-struct pipeline_msg_rsp_table_stats_read {
- struct rte_pipeline_table_stats stats;
-};
-
-struct pipeline_msg_rsp_table_rule_add {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_default {
- void *data;
-};
-
-struct pipeline_msg_rsp_table_rule_add_bulk {
- uint32_t n_rules;
-};
-
-struct pipeline_msg_rsp_table_rule_stats_read {
- struct rte_table_action_stats_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_mtr_read {
- struct rte_table_action_mtr_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_ttl_read {
- struct rte_table_action_ttl_counters stats;
-};
-
-struct pipeline_msg_rsp_table_rule_time_read {
- uint64_t timestamp;
-};
-
-struct pipeline_msg_rsp {
- int status;
-
- union {
- struct pipeline_msg_rsp_port_in_stats_read port_in_stats_read;
- struct pipeline_msg_rsp_port_out_stats_read port_out_stats_read;
- struct pipeline_msg_rsp_table_stats_read table_stats_read;
- struct pipeline_msg_rsp_table_rule_add table_rule_add;
- struct pipeline_msg_rsp_table_rule_add_default table_rule_add_default;
- struct pipeline_msg_rsp_table_rule_add_bulk table_rule_add_bulk;
- struct pipeline_msg_rsp_table_rule_stats_read table_rule_stats_read;
- struct pipeline_msg_rsp_table_rule_mtr_read table_rule_mtr_read;
- struct pipeline_msg_rsp_table_rule_ttl_read table_rule_ttl_read;
- struct pipeline_msg_rsp_table_rule_time_read table_rule_time_read;
- };
-};
-
-/**
- * Main thread
- */
-static struct pipeline_msg_req *
-pipeline_msg_alloc(void)
-{
- size_t size = RTE_MAX(sizeof(struct pipeline_msg_req),
- sizeof(struct pipeline_msg_rsp));
-
- return calloc(1, size);
-}
-
-static void
-pipeline_msg_free(struct pipeline_msg_rsp *rsp)
-{
- free(rsp);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_send_recv(struct pipeline *p,
- struct pipeline_msg_req *req)
-{
- struct rte_ring *msgq_req = p->msgq_req;
- struct rte_ring *msgq_rsp = p->msgq_rsp;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(msgq_req, req);
- } while (status == -ENOBUFS);
-
- /* recv */
- do {
- status = rte_ring_sc_dequeue(msgq_rsp, (void **) &rsp);
- } while (status != 0);
-
- return rsp;
-}
-
-int
-pipeline_port_in_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_STATS_READ;
- req->id = port_id;
- req->port_in_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_enable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_enable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_ENABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_in_disable(const char *pipeline_name,
- uint32_t port_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_in))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_disable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_DISABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_port_out_stats_read(const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (port_id >= p->n_ports_out))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_OUT_STATS_READ;
- req->id = port_id;
- req->port_out_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_stats_read(p->p,
- table_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_STATS_READ;
- req->id = table_id;
- req->table_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static int
-match_check(struct table_rule_match *match,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table *table;
-
- if ((match == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
- if (match->match_type != table->params.match_type)
- return -1;
-
- switch (match->match_type) {
- case TABLE_ACL:
- {
- struct table_acl_params *t = &table->params.match.acl;
- struct table_rule_match_acl *r = &match->match.acl;
-
- if ((r->ip_version && (t->ip_version == 0)) ||
- ((r->ip_version == 0) && t->ip_version))
- return -1;
-
- if (r->ip_version) {
- if ((r->sa_depth > 32) ||
- (r->da_depth > 32))
- return -1;
- } else {
- if ((r->sa_depth > 128) ||
- (r->da_depth > 128))
- return -1;
- }
- return 0;
- }
-
- case TABLE_ARRAY:
- return 0;
-
- case TABLE_HASH:
- return 0;
-
- case TABLE_LPM:
- {
- struct table_lpm_params *t = &table->params.match.lpm;
- struct table_rule_match_lpm *r = &match->match.lpm;
-
- if ((r->ip_version && (t->key_size != 4)) ||
- ((r->ip_version == 0) && (t->key_size != 16)))
- return -1;
-
- if (r->ip_version) {
- if (r->depth > 32)
- return -1;
- } else {
- if (r->depth > 128)
- return -1;
- }
- return 0;
- }
-
- case TABLE_STUB:
- return -1;
-
- default:
- return -1;
- }
-}
-
-static int
-action_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct table_action_profile *ap;
-
- if ((action == NULL) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- ap = p->table[table_id].ap;
- if (action->action_mask != ap->params.action_mask)
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- uint32_t tc_mask0 = (1 << ap->params.mtr.n_tc) - 1;
- uint32_t tc_mask1 = action->mtr.tc_mask;
-
- if (tc_mask1 != tc_mask0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- uint32_t n_subports_per_port =
- ap->params.tm.n_subports_per_port;
- uint32_t n_pipes_per_subport =
- ap->params.tm.n_pipes_per_subport;
- uint32_t subport_id = action->tm.subport_id;
- uint32_t pipe_id = action->tm.pipe_id;
-
- if ((subport_id >= n_subports_per_port) ||
- (pipe_id >= n_pipes_per_subport))
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- uint64_t encap_mask = ap->params.encap.encap_mask;
- enum rte_table_action_encap_type type = action->encap.type;
-
- if ((encap_mask & (1LLU << type)) == 0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- int ip_version0 = ap->params.common.ip_version;
- int ip_version1 = action->nat.ip_version;
-
- if ((ip_version1 && (ip_version0 == 0)) ||
- ((ip_version1 == 0) && ip_version0))
- return -1;
- }
-
- return 0;
-}
-
-static int
-action_default_check(struct table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- if ((action == NULL) ||
- (action->action_mask != (1LLU << RTE_TABLE_ACTION_FWD)) ||
- (p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if ((action->fwd.action == RTE_PIPELINE_ACTION_PORT) &&
- (action->fwd.id >= p->n_ports_out))
- return -1;
-
- if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
- (action->fwd.id >= p->n_tables))
- return -1;
- }
-
- return 0;
-}
-
-union table_rule_match_low_level {
- struct rte_table_acl_rule_add_params acl_add;
- struct rte_table_acl_rule_delete_params acl_delete;
- struct rte_table_array_key array;
- uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
- struct rte_table_lpm_key lpm_ipv4;
- struct rte_table_lpm_ipv6_key lpm_ipv6;
-};
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add);
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data);
-
-struct table_ll {
- struct rte_pipeline *p;
- int table_id;
- struct rte_table_action *a;
- int bulk_supported;
-};
-
-static int
-table_rule_add_bulk_ll(struct table_ll *table,
- struct table_rule_list *list,
- uint32_t *n_rules)
-{
- union table_rule_match_low_level *match_ll = NULL;
- uint8_t *action_ll = NULL;
- void **match_ll_ptr = NULL;
- struct rte_pipeline_table_entry **action_ll_ptr = NULL;
- struct rte_pipeline_table_entry **entries_ptr = NULL;
- int *found = NULL;
- struct table_rule *rule;
- uint32_t n, i;
- int status = 0;
-
- n = 0;
- TAILQ_FOREACH(rule, list, node)
- n++;
-
- /* Memory allocation */
- match_ll = calloc(n, sizeof(union table_rule_match_low_level));
- action_ll = calloc(n, TABLE_RULE_ACTION_SIZE_MAX);
-
- match_ll_ptr = calloc(n, sizeof(void *));
- action_ll_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
-
- entries_ptr = calloc(n, sizeof(struct rte_pipeline_table_entry *));
- found = calloc(n, sizeof(int));
-
- if (match_ll == NULL ||
- action_ll == NULL ||
- match_ll_ptr == NULL ||
- action_ll_ptr == NULL ||
- entries_ptr == NULL ||
- found == NULL) {
- status = -ENOMEM;
- goto table_rule_add_bulk_ll_free;
- }
-
- /* Init */
- for (i = 0; i < n; i++) {
- match_ll_ptr[i] = (void *)&match_ll[i];
- action_ll_ptr[i] = (struct rte_pipeline_table_entry *)
- &action_ll[i * TABLE_RULE_ACTION_SIZE_MAX];
- }
-
- /* Rule (match, action) conversion */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- status = match_convert(&rule->match, match_ll_ptr[i], 1);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- status = action_convert(table->a, &rule->action, action_ll_ptr[i]);
- if (status)
- goto table_rule_add_bulk_ll_free;
-
- i++;
- }
-
- /* Add rule (match, action) to table */
- if (table->bulk_supported) {
- status = rte_pipeline_table_entry_add_bulk(table->p,
- table->table_id,
- match_ll_ptr,
- action_ll_ptr,
- n,
- found,
- entries_ptr);
- if (status)
- goto table_rule_add_bulk_ll_free;
- } else
- for (i = 0; i < n; i++) {
- status = rte_pipeline_table_entry_add(table->p,
- table->table_id,
- match_ll_ptr[i],
- action_ll_ptr[i],
- &found[i],
- &entries_ptr[i]);
- if (status) {
- if (i == 0)
- goto table_rule_add_bulk_ll_free;
-
- /* No roll-back. */
- status = 0;
- n = i;
- break;
- }
- }
-
- /* Write back to the rule list. */
- i = 0;
- TAILQ_FOREACH(rule, list, node) {
- if (i >= n)
- break;
-
- rule->data = entries_ptr[i];
-
- i++;
- }
-
- *n_rules = n;
-
- /* Free */
-table_rule_add_bulk_ll_free:
- free(found);
- free(entries_ptr);
- free(action_ll_ptr);
- free(match_ll_ptr);
- free(action_ll);
- free(match_ll);
-
- return status;
-}
-
-int
-pipeline_table_rule_add(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id) ||
- action_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->match, match, sizeof(*match));
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- struct rte_pipeline_table_entry *data_in, *data_out;
- int key_found;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Table match-action rule conversion */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- status = action_convert(table->a, action, data_in);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Add rule (match, action) to table */
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD;
- req->id = table_id;
- memcpy(&req->table_rule_add.match, match, sizeof(*match));
- memcpy(&req->table_rule_add.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add.data;
- table_rule_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_add_default(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_action *action)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (action == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- action_default_check(action, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = calloc(1, sizeof(struct table_rule));
- if (rule == NULL)
- return -1;
-
- memcpy(&rule->action, action, sizeof(*action));
-
- if (!pipeline_is_running(p)) {
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint8_t *buffer;
-
- buffer = calloc(TABLE_RULE_ACTION_SIZE_MAX, sizeof(uint8_t));
- if (buffer == NULL) {
- free(rule);
- return -1;
- }
-
- /* Apply actions */
- data_in = (struct rte_pipeline_table_entry *)buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- free(buffer);
- free(rule);
- return -1;
- }
-
- /* Write Response */
- rule->data = data_out;
- table_rule_default_add(table, rule);
-
- free(buffer);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(rule);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT;
- req->id = table_id;
- memcpy(&req->table_rule_add_default.action, action, sizeof(*action));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- rule->data = rsp->table_rule_add_default.data;
- table_rule_default_add(table, rule);
- } else
- free(rule);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static uint32_t
-table_rule_list_free(struct table_rule_list *list)
-{
- uint32_t n = 0;
-
- if (!list)
- return 0;
-
- for ( ; ; ) {
- struct table_rule *rule;
-
- rule = TAILQ_FIRST(list);
- if (rule == NULL)
- break;
-
- TAILQ_REMOVE(list, rule, node);
- free(rule);
- n++;
- }
-
- free(list);
- return n;
-}
-
-int
-pipeline_table_rule_add_bulk(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_list *list,
- uint32_t *n_rules_added,
- uint32_t *n_rules_not_added)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status = 0;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (list == NULL) ||
- TAILQ_EMPTY(list) ||
- (n_rules_added == NULL) ||
- (n_rules_not_added == NULL)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- table = &p->table[table_id];
-
- TAILQ_FOREACH(rule, list, node)
- if (match_check(&rule->match, p, table_id) ||
- action_check(&rule->action, p, table_id)) {
- table_rule_list_free(list);
- return -EINVAL;
- }
-
- if (!pipeline_is_running(p)) {
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = table->a,
- .bulk_supported = table->params.match_type == TABLE_ACL,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, n_rules_added);
- if (status) {
- table_rule_list_free(list);
- return status;
- }
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- return 0;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- table_rule_list_free(list);
- return -ENOMEM;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;
- req->id = table_id;
- req->table_rule_add_bulk.list = list;
- req->table_rule_add_bulk.bulk = table->params.match_type == TABLE_ACL;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0) {
- *n_rules_added = rsp->table_rule_add_bulk.n_rules;
-
- table_rule_add_bulk(table, list, *n_rules_added);
- *n_rules_not_added = table_rule_list_free(list);
- } else
- table_rule_list_free(list);
-
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- union table_rule_match_low_level match_ll;
- int key_found;
-
- status = match_convert(match, &match_ll, 0);
- if (status)
- return -1;
-
- status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- if (status == 0)
- table_rule_delete(table, match);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE;
- req->id = table_id;
- memcpy(&req->table_rule_delete.match, match, sizeof(*match));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_delete(table, match);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_delete_default(const char *pipeline_name,
- uint32_t table_id)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- table = &p->table[table_id];
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- if (status == 0)
- table_rule_default_delete(table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT;
- req->id = table_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- table_rule_default_delete(table);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_stats_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_stats_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_STATS_READ;
- req->id = table_id;
- req->table_rule_stats_read.data = rule->data;
- req->table_rule_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_add(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (profile == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
- req->id = table_id;
- req->table_mtr_profile_add.meter_profile_id = meter_profile_id;
- memcpy(&req->table_mtr_profile_add.profile, profile, sizeof(*profile));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_mtr_profile_delete(const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL)
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE;
- req->id = table_id;
- req->table_mtr_profile_delete.meter_profile_id = meter_profile_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_mtr_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- uint32_t tc_mask;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- tc_mask = (1 << table->ap->params.mtr.n_tc) - 1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_meter_read(table->a,
- rule->data,
- tc_mask,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_MTR_READ;
- req->id = table_id;
- req->table_rule_mtr_read.data = rule->data;
- req->table_rule_mtr_read.tc_mask = tc_mask;
- req->table_rule_mtr_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_mtr_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_dscp_table_update(const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (dscp_table == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables))
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE;
- req->id = table_id;
- req->table_dscp_table_update.dscp_mask = dscp_mask;
- memcpy(&req->table_dscp_table_update.dscp_table,
- dscp_table, sizeof(*dscp_table));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_ttl_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (stats == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
- if (!table->ap->params.ttl.n_packets_enabled)
- return -1;
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_ttl_read(table->a,
- rule->data,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TTL_READ;
- req->id = table_id;
- req->table_rule_ttl_read.data = rule->data;
- req->table_rule_ttl_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-pipeline_table_rule_time_read(const char *pipeline_name,
- uint32_t table_id,
- struct table_rule_match *match,
- uint64_t *timestamp)
-{
- struct pipeline *p;
- struct table *table;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- struct table_rule *rule;
- int status;
-
- /* Check input params */
- if ((pipeline_name == NULL) ||
- (match == NULL) ||
- (timestamp == NULL))
- return -1;
-
- p = pipeline_find(pipeline_name);
- if ((p == NULL) ||
- (table_id >= p->n_tables) ||
- match_check(match, p, table_id))
- return -1;
-
- table = &p->table[table_id];
-
- rule = table_rule_find(table, match);
- if (rule == NULL)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_time_read(table->a,
- rule->data,
- timestamp);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_RULE_TIME_READ;
- req->id = table_id;
- req->table_rule_time_read.data = rule->data;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- *timestamp = rsp->table_rule_time_read.timestamp;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-/**
- * Data plane threads: message handling
- */
-static inline struct pipeline_msg_req *
-pipeline_msg_recv(struct rte_ring *msgq_req)
-{
- struct pipeline_msg_req *req;
-
- int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
-
- if (status != 0)
- return NULL;
-
- return req;
-}
-
-static inline void
-pipeline_msg_send(struct rte_ring *msgq_rsp,
- struct pipeline_msg_rsp *rsp)
-{
- int status;
-
- do {
- status = rte_ring_sp_enqueue(msgq_rsp, rsp);
- } while (status == -ENOBUFS);
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_in_stats_read.clear;
-
- rsp->status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- &rsp->port_in_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_enable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_enable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_in_disable(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
-
- rsp->status = rte_pipeline_port_in_disable(p->p,
- port_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_port_out_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->port_out_stats_read.clear;
-
- rsp->status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- &rsp->port_out_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t port_id = req->id;
- int clear = req->table_stats_read.clear;
-
- rsp->status = rte_pipeline_table_stats_read(p->p,
- port_id,
- &rsp->table_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static int
-match_convert_ipv6_depth(uint32_t depth, uint32_t *depth32)
-{
- if (depth > 128)
- return -1;
-
- switch (depth / 32) {
- case 0:
- depth32[0] = depth;
- depth32[1] = 0;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 1:
- depth32[0] = 32;
- depth32[1] = depth - 32;
- depth32[2] = 0;
- depth32[3] = 0;
- return 0;
-
- case 2:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = depth - 64;
- depth32[3] = 0;
- return 0;
-
- case 3:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = depth - 96;
- return 0;
-
- case 4:
- depth32[0] = 32;
- depth32[1] = 32;
- depth32[2] = 32;
- depth32[3] = 32;
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-match_convert(struct table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add)
-{
- memset(ml, 0, sizeof(*ml));
-
- switch (mh->match_type) {
- case TABLE_ACL:
- if (mh->match.acl.ip_version)
- if (add) {
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_add.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_add.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_add.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_add.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_delete.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_delete.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_delete.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_delete.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
- }
- else
- if (add) {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_add.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_add.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_add.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_add.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_add.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_add.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_add.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_add.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_add.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_add.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_add.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_add.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_add.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_add.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_add.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_add.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t) mh->match.acl.priority;
- } else {
- uint32_t *sa32 = (uint32_t *)&mh->match.acl.ipv6.sa;
- uint32_t *da32 = (uint32_t *)&mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_delete.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_delete.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_delete.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_delete.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_delete.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_delete.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_delete.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_delete.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_delete.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_delete.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_delete.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_delete.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_delete.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_delete.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_delete.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_delete.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
- }
- return 0;
-
- case TABLE_ARRAY:
- ml->array.pos = mh->match.array.pos;
- return 0;
-
- case TABLE_HASH:
- memcpy(ml->hash, mh->match.hash.key, sizeof(ml->hash));
- return 0;
-
- case TABLE_LPM:
- if (mh->match.lpm.ip_version) {
- ml->lpm_ipv4.ip = mh->match.lpm.ipv4;
- ml->lpm_ipv4.depth = mh->match.lpm.depth;
- } else {
- ml->lpm_ipv6.ip = mh->match.lpm.ipv6;
- ml->lpm_ipv6.depth = mh->match.lpm.depth;
- }
-
- return 0;
-
- default:
- return -1;
- }
-}
-
-static int
-action_convert(struct rte_table_action *a,
- struct table_rule_action *action,
- struct rte_pipeline_table_entry *data)
-{
- int status;
-
- /* Apply actions */
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_FWD,
- &action->fwd);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_LB,
- &action->lb);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_MTR,
- &action->mtr);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TM,
- &action->tm);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_ENCAP,
- &action->encap);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_NAT,
- &action->nat);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TTL,
- &action->ttl);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_STATS,
- &action->stats);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TIME,
- &action->time);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- &action->sym_crypto);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TAG,
- &action->tag);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_DECAP,
- &action->decap);
-
- if (status)
- return status;
- }
-
- return 0;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_add.match;
- struct table_rule_action *action = &req->table_rule_add.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int key_found, status;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = action_convert(a, action, data_in);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_action *action = &req->table_rule_add_default.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int status;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *) p->buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_default.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
-
- uint32_t table_id = req->id;
- struct table_rule_list *list = req->table_rule_add_bulk.list;
- uint32_t bulk = req->table_rule_add_bulk.bulk;
-
- uint32_t n_rules_added;
- int status;
-
- struct table_ll table_ll = {
- .p = p->p,
- .table_id = table_id,
- .a = p->table_data[table_id].a,
- .bulk_supported = bulk,
- };
-
- status = table_rule_add_bulk_ll(&table_ll, list, &n_rules_added);
- if (status) {
- rsp->status = -1;
- rsp->table_rule_add_bulk.n_rules = 0;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_bulk.n_rules = n_rules_added;
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- struct table_rule_match *match = &req->table_rule_delete.match;
- uint32_t table_id = req->id;
- int key_found, status;
-
- status = match_convert(match, &match_ll, 0);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- table_id,
- &match_ll,
- &key_found,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_delete_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- table_id,
- NULL);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_stats_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_stats_read.data;
- int clear = req->table_rule_stats_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_stats_read(a,
- data,
- &rsp->table_rule_stats_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id = req->table_mtr_profile_add.meter_profile_id;
- struct rte_table_action_meter_profile *profile =
- &req->table_mtr_profile_add.profile;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_add(a,
- meter_profile_id,
- profile);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_mtr_profile_delete(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint32_t meter_profile_id =
- req->table_mtr_profile_delete.meter_profile_id;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_mtr_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_mtr_read.data;
- uint32_t tc_mask = req->table_rule_mtr_read.tc_mask;
- int clear = req->table_rule_mtr_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_meter_read(a,
- data,
- tc_mask,
- &rsp->table_rule_mtr_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_dscp_table_update(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- uint64_t dscp_mask = req->table_dscp_table_update.dscp_mask;
- struct rte_table_action_dscp_table *dscp_table =
- &req->table_dscp_table_update.dscp_table;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_dscp_table_update(a,
- dscp_mask,
- dscp_table);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_ttl_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_ttl_read.data;
- int clear = req->table_rule_ttl_read.clear;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_ttl_read(a,
- data,
- &rsp->table_rule_ttl_read.stats,
- clear);
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_time_read(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *) req;
- uint32_t table_id = req->id;
- void *data = req->table_rule_time_read.data;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- rsp->status = rte_table_action_time_read(a,
- data,
- &rsp->table_rule_time_read.timestamp);
-
- return rsp;
-}
-
-static void
-pipeline_msg_handle(struct pipeline_data *p)
-{
- for ( ; ; ) {
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
-
- req = pipeline_msg_recv(p->msgq_req);
- if (req == NULL)
- break;
-
- switch (req->type) {
- case PIPELINE_REQ_PORT_IN_STATS_READ:
- rsp = pipeline_msg_handle_port_in_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_ENABLE:
- rsp = pipeline_msg_handle_port_in_enable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_IN_DISABLE:
- rsp = pipeline_msg_handle_port_in_disable(p, req);
- break;
-
- case PIPELINE_REQ_PORT_OUT_STATS_READ:
- rsp = pipeline_msg_handle_port_out_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_STATS_READ:
- rsp = pipeline_msg_handle_table_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD:
- rsp = pipeline_msg_handle_table_rule_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_add_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_ADD_BULK:
- rsp = pipeline_msg_handle_table_rule_add_bulk(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE:
- rsp = pipeline_msg_handle_table_rule_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT:
- rsp = pipeline_msg_handle_table_rule_delete_default(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_STATS_READ:
- rsp = pipeline_msg_handle_table_rule_stats_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_ADD:
- rsp = pipeline_msg_handle_table_mtr_profile_add(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE:
- rsp = pipeline_msg_handle_table_mtr_profile_delete(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_MTR_READ:
- rsp = pipeline_msg_handle_table_rule_mtr_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE:
- rsp = pipeline_msg_handle_table_dscp_table_update(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TTL_READ:
- rsp = pipeline_msg_handle_table_rule_ttl_read(p, req);
- break;
-
- case PIPELINE_REQ_TABLE_RULE_TIME_READ:
- rsp = pipeline_msg_handle_table_rule_time_read(p, req);
- break;
-
- default:
- rsp = (struct pipeline_msg_rsp *) req;
- rsp->status = -1;
- }
-
- pipeline_msg_send(p->msgq_rsp, rsp);
- }
-}
-
-/**
- * Data plane threads: main
- */
-int
-thread_main(void *arg __rte_unused)
-{
- struct thread_data *t;
- uint32_t thread_id, i;
-
- thread_id = rte_lcore_id();
- t = &thread_data[thread_id];
-
- /* Dispatch loop */
- for (i = 0; ; i++) {
- uint32_t j;
-
- /* Data Plane */
- for (j = 0; j < t->n_pipelines; j++)
- rte_pipeline_run(t->p[j]);
-
- /* Control Plane */
- if ((i & 0xF) == 0) {
- uint64_t time = rte_get_tsc_cycles();
- uint64_t time_next_min = UINT64_MAX;
-
- if (time < t->time_next_min)
- continue;
-
- /* Pipeline message queues */
- for (j = 0; j < t->n_pipelines; j++) {
- struct pipeline_data *p =
- &t->pipeline_data[j];
- uint64_t time_next = p->time_next;
-
- if (time_next <= time) {
- pipeline_msg_handle(p);
- rte_pipeline_flush(p->p);
- time_next = time + p->timer_period;
- p->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- /* Thread message queues */
- {
- uint64_t time_next = t->time_next;
-
- if (time_next <= time) {
- thread_msg_handle(t);
- time_next = time + t->timer_period;
- t->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
-
- t->time_next_min = time_next_min;
- }
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h
deleted file mode 100644
index facdf004eb6e1dba9dfa388620e8807b235d7dd5..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/thread.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_THREAD_H_
-#define _INCLUDE_THREAD_H_
-
-#include <stdint.h>
-
-int
-thread_pipeline_enable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_pipeline_disable(uint32_t thread_id,
- const char *pipeline_name);
-
-int
-thread_init(void);
-
-int
-thread_main(void *arg);
-
-#endif /* _INCLUDE_THREAD_H_ */
diff --git a/examples/ip_pipeline/tmgr.c b/examples/ip_pipeline/tmgr.c
deleted file mode 100644
index 2432b56aeec6ce66b0feb636ee86f38da7712343..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/tmgr.c
+++ /dev/null
@@ -1,248 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdlib.h>
-
-#include <rte_common.h>
-#include <rte_string_fns.h>
-
-#include "tmgr.h"
-
-static struct rte_sched_subport_profile_params
- subport_profile[TMGR_SUBPORT_PROFILE_MAX];
-
-static uint32_t n_subport_profiles;
-
-static struct rte_sched_pipe_params
- pipe_profile[TMGR_PIPE_PROFILE_MAX];
-
-static uint32_t n_pipe_profiles;
-
-static const struct rte_sched_subport_params subport_params_default = {
- .n_pipes_per_subport_enabled = 0, /* filled at runtime */
- .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},
- .pipe_profiles = pipe_profile,
- .n_pipe_profiles = 0, /* filled at run time */
- .n_max_pipe_profiles = RTE_DIM(pipe_profile),
- .cman_params = NULL,
-};
-
-static struct tmgr_port_list tmgr_port_list;
-
-int
-tmgr_init(void)
-{
- TAILQ_INIT(&tmgr_port_list);
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_find(const char *name)
-{
- struct tmgr_port *tmgr_port;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(tmgr_port, &tmgr_port_list, node)
- if (strcmp(tmgr_port->name, name) == 0)
- return tmgr_port;
-
- return NULL;
-}
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *params)
-{
- /* Check input params */
- if (params == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&subport_profile[n_subport_profiles],
- params,
- sizeof(*params));
-
- n_subport_profiles++;
-
- return 0;
-}
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p)
-{
- /* Check input params */
- if (p == NULL)
- return -1;
-
- /* Save profile */
- memcpy(&pipe_profile[n_pipe_profiles],
- p,
- sizeof(*p));
-
- n_pipe_profiles++;
-
- return 0;
-}
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params)
-{
- struct rte_sched_subport_params subport_params;
- struct rte_sched_port_params p;
- struct tmgr_port *tmgr_port;
- struct rte_sched_port *s;
- uint32_t i, j;
-
- /* Check input params */
- if ((name == NULL) ||
- tmgr_port_find(name) ||
- (params == NULL) ||
- (params->n_subports_per_port == 0) ||
- (params->n_pipes_per_subport == 0) ||
- (params->cpu_id >= RTE_MAX_NUMA_NODES) ||
- (n_subport_profiles == 0) ||
- (n_pipe_profiles == 0))
- return NULL;
-
- /* Resource create */
- p.name = name;
- p.socket = (int) params->cpu_id;
- p.rate = params->rate;
- p.mtu = params->mtu;
- p.frame_overhead = params->frame_overhead;
- p.n_subports_per_port = params->n_subports_per_port;
- p.n_subport_profiles = n_subport_profiles;
- p.subport_profiles = subport_profile;
- p.n_max_subport_profiles = TMGR_SUBPORT_PROFILE_MAX;
- p.n_pipes_per_subport = params->n_pipes_per_subport;
-
-
- s = rte_sched_port_config(&p);
- if (s == NULL)
- return NULL;
-
- memcpy(&subport_params, &subport_params_default,
- sizeof(subport_params_default));
-
- subport_params.n_pipe_profiles = n_pipe_profiles;
- subport_params.n_pipes_per_subport_enabled =
- params->n_pipes_per_subport;
-
- for (i = 0; i < params->n_subports_per_port; i++) {
- int status;
-
- status = rte_sched_subport_config(
- s,
- i,
- &subport_params,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- for (j = 0; j < params->n_pipes_per_subport; j++) {
-
- status = rte_sched_pipe_config(
- s,
- i,
- j,
- 0);
-
- if (status) {
- rte_sched_port_free(s);
- return NULL;
- }
- }
- }
-
- /* Node allocation */
- tmgr_port = calloc(1, sizeof(struct tmgr_port));
- if (tmgr_port == NULL) {
- rte_sched_port_free(s);
- return NULL;
- }
-
- /* Node fill in */
- strlcpy(tmgr_port->name, name, sizeof(tmgr_port->name));
- tmgr_port->s = s;
- tmgr_port->n_subports_per_port = params->n_subports_per_port;
- tmgr_port->n_pipes_per_subport = params->n_pipes_per_subport;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&tmgr_port_list, tmgr_port, node);
-
- return tmgr_port;
-}
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id)
-{
- struct tmgr_port *port;
- int status;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (subport_profile_id >= n_subport_profiles))
- return -1;
-
- /* Resource config */
- status = rte_sched_subport_config(
- port->s,
- subport_id,
- NULL,
- subport_profile_id);
-
- return status;
-}
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id)
-{
- struct tmgr_port *port;
- uint32_t i;
-
- /* Check input params */
- if (port_name == NULL)
- return -1;
-
- port = tmgr_port_find(port_name);
- if ((port == NULL) ||
- (subport_id >= port->n_subports_per_port) ||
- (pipe_id_first >= port->n_pipes_per_subport) ||
- (pipe_id_last >= port->n_pipes_per_subport) ||
- (pipe_id_first > pipe_id_last) ||
- (pipe_profile_id >= n_pipe_profiles))
- return -1;
-
- /* Resource config */
- for (i = pipe_id_first; i <= pipe_id_last; i++) {
- int status;
-
- status = rte_sched_pipe_config(
- port->s,
- subport_id,
- i,
- (int) pipe_profile_id);
-
- if (status)
- return status;
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/tmgr.h b/examples/ip_pipeline/tmgr.h
deleted file mode 100644
index 1994c55bcc536562204b220f1f0344d9424f5544..0000000000000000000000000000000000000000
--- a/examples/ip_pipeline/tmgr.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef _INCLUDE_TMGR_H_
-#define _INCLUDE_TMGR_H_
-
-#include <stdint.h>
-#include <sys/queue.h>
-
-#include <rte_sched.h>
-#include <rte_red.h>
-
-#include "common.h"
-
-#ifndef TMGR_PIPE_SUBPORT_MAX
-#define TMGR_PIPE_SUBPORT_MAX 4096
-#endif
-
-#ifndef TMGR_SUBPORT_PROFILE_MAX
-#define TMGR_SUBPORT_PROFILE_MAX 256
-#endif
-
-#ifndef TMGR_PIPE_PROFILE_MAX
-#define TMGR_PIPE_PROFILE_MAX 256
-#endif
-
-struct tmgr_port {
- TAILQ_ENTRY(tmgr_port) node;
- char name[NAME_SIZE];
- struct rte_sched_port *s;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
-};
-
-TAILQ_HEAD(tmgr_port_list, tmgr_port);
-
-int
-tmgr_init(void);
-
-struct tmgr_port *
-tmgr_port_find(const char *name);
-
-struct tmgr_port_params {
- uint64_t rate;
- uint32_t n_subports_per_port;
- uint32_t n_pipes_per_subport;
- uint32_t frame_overhead;
- uint32_t mtu;
- uint32_t cpu_id;
-};
-
-int
-tmgr_subport_profile_add(struct rte_sched_subport_profile_params *sp);
-
-int
-tmgr_pipe_profile_add(struct rte_sched_pipe_params *p);
-
-struct tmgr_port *
-tmgr_port_create(const char *name, struct tmgr_port_params *params);
-
-int
-tmgr_subport_config(const char *port_name,
- uint32_t subport_id,
- uint32_t subport_profile_id);
-
-int
-tmgr_pipe_config(const char *port_name,
- uint32_t subport_id,
- uint32_t pipe_id_first,
- uint32_t pipe_id_last,
- uint32_t pipe_profile_id);
-
-#endif /* _INCLUDE_TMGR_H_ */
diff --git a/examples/meson.build b/examples/meson.build
index 25d9c88457f51f6e806b8dcb20564b3b5ab299b5..544ec5eadd82c3799b3fb884b07a73faa840651f 100644
--- a/examples/meson.build
+++ b/examples/meson.build
@@ -19,7 +19,6 @@ all_examples = [
'flow_filtering',
'helloworld',
'ip_fragmentation',
- 'ip_pipeline',
'ip_reassembly',
'ipsec-secgw',
'ipv4_multicast',
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 4/7] pipeline: remove legacy API
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (11 preceding siblings ...)
2026-07-28 16:35 ` [PATCH v4 3/7] examples/ip_pipeline: remove example Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 5/7] table: " Stephen Hemminger
` (2 subsequent siblings)
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy pipeline API (rte_pipeline_*) together with the
port and table action APIs built on top of it, as announced for
removal in the 24.11 release. The SWX pipeline API remains.
The sched dependency was only used by the table action API,
so drop it.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 3 -
doc/guides/prog_guide/packet_framework.rst | 203 --
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 4 +
lib/pipeline/meson.build | 8 +-
lib/pipeline/rte_pipeline.c | 1640 ---------
lib/pipeline/rte_pipeline.h | 840 -----
lib/pipeline/rte_port_in_action.c | 539 ---
lib/pipeline/rte_port_in_action.h | 311 --
lib/pipeline/rte_table_action.c | 3483 --------------------
lib/pipeline/rte_table_action.h | 1137 -------
11 files changed, 5 insertions(+), 8168 deletions(-)
delete mode 100644 lib/pipeline/rte_pipeline.c
delete mode 100644 lib/pipeline/rte_pipeline.h
delete mode 100644 lib/pipeline/rte_port_in_action.c
delete mode 100644 lib/pipeline/rte_port_in_action.h
delete mode 100644 lib/pipeline/rte_table_action.c
delete mode 100644 lib/pipeline/rte_table_action.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 92960421194604a9bc69da1eb6af7fc727cdb310..17c15027b8bd3aae13b992b4bfd038ef8b2bb5cd 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -196,9 +196,6 @@ The public API headers are grouped by topics:
[hash](@ref rte_table_hash.h),
[array](@ref rte_table_array.h),
[stub](@ref rte_table_stub.h)
- * [pipeline](@ref rte_pipeline.h)
- [port_in_action](@ref rte_port_in_action.h)
- [table_action](@ref rte_table_action.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index ac302938dcca5b933075602bbd49ccaf66f0a777..9eb2c5d3de31fa88fd0f1b8246e7482f144ac011 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -942,209 +942,6 @@ Additional notes:
This does not impact the performance of the key lookup operation,
as the probability of having the bucket in extended state is relatively small.
-Pipeline Library Design
------------------------
-
-A pipeline is defined by:
-
-#. The set of input ports;
-
-#. The set of output ports;
-
-#. The set of tables;
-
-#. The set of actions.
-
-The input ports are connected with the output ports through tree-like topologies of interconnected tables.
-The table entries contain the actions defining the operations to be executed on the input packets and the packet flow within the pipeline.
-
-Connectivity of Ports and Tables
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-To avoid any dependencies on the order in which pipeline elements are created,
-the connectivity of pipeline elements is defined after all the pipeline input ports,
-output ports and tables have been created.
-
-General connectivity rules:
-
-#. Each input port is connected to a single table. No input port should be left unconnected;
-
-#. The table connectivity to other tables or to output ports is regulated by the next hop actions of each table entry and the default table entry.
- The table connectivity is fluid, as the table entries and the default table entry can be updated during run-time.
-
- * A table can have multiple entries (including the default entry) connected to the same output port.
- A table can have different entries connected to different output ports.
- Different tables can have entries (including default table entry) connected to the same output port.
-
- * A table can have multiple entries (including the default entry) connected to another table,
- in which case all these entries have to point to the same table.
- This constraint is enforced by the API and prevents tree-like topologies from being created (allowing table chaining only),
- with the purpose of simplifying the implementation of the pipeline run-time execution engine.
-
-Port Actions
-~~~~~~~~~~~~
-
-Port Action Handler
-^^^^^^^^^^^^^^^^^^^
-
-An action handler can be assigned to each input/output port to define actions to be executed on each input packet that is received by the port.
-Defining the action handler for a specific input/output port is optional (i.e. the action handler can be disabled).
-
-For input ports, the action handler is executed after RX function. For output ports, the action handler is executed before the TX function.
-
-The action handler can decide to drop packets.
-
-Table Actions
-~~~~~~~~~~~~~
-
-Table Action Handler
-^^^^^^^^^^^^^^^^^^^^
-
-An action handler to be executed on each input packet can be assigned to each table.
-Defining the action handler for a specific table is optional (i.e. the action handler can be disabled).
-
-The action handler is executed after the table lookup operation is performed and the table entry associated with each input packet is identified.
-The action handler can only handle the user-defined actions, while the reserved actions (e.g. the next hop actions) are handled by the Packet Framework.
-The action handler can decide to drop the input packet.
-
-Reserved Actions
-^^^^^^^^^^^^^^^^
-
-The reserved actions are handled directly by the Packet Framework without the user being able to change their meaning
-through the table action handler configuration.
-A special category of the reserved actions is represented by the next hop actions, which regulate the packet flow between input ports,
-tables and output ports through the pipeline.
-:numref:`packet_framework_table_qos_33` lists the next hop actions.
-
-.. _packet_framework_table_qos_33:
-
-.. table:: Next Hop Actions (Reserved)
-
- +---+---------------------+-----------------------------------------------------------------------------------+
- | # | Next hop action | Description |
- | | | |
- +===+=====================+===================================================================================+
- | 1 | Drop | Drop the current packet. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 2 | Send to output port | Send the current packet to specified output port. The output port ID is metadata |
- | | | stored in the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
- | 3 | Send to table | Send the current packet to specified table. The table ID is metadata stored in |
- | | | the same table entry. |
- | | | |
- +---+---------------------+-----------------------------------------------------------------------------------+
-
-User Actions
-^^^^^^^^^^^^
-
-For each table, the meaning of user actions is defined through the configuration of the table action handler.
-Different tables can be configured with different action handlers, therefore the meaning of the user actions
-and their associated meta-data is private to each table.
-Within the same table, all the table entries (including the table default entry) share the same definition
-for the user actions and their associated meta-data,
-with each table entry having its own set of enabled user actions and its own copy of the action meta-data.
-:numref:`packet_framework_table_qos_34` contains a non-exhaustive list of user action examples.
-
-.. _packet_framework_table_qos_34:
-
-.. table:: User Action Examples
-
- +---+-----------------------------------+---------------------------------------------------------------------+
- | # | User action | Description |
- | | | |
- +===+===================================+=====================================================================+
- | 1 | Metering | Per flow traffic metering using the srTCM and trTCM algorithms. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 2 | Statistics | Update the statistics counters maintained per flow. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 3 | App ID | Per flow state machine fed by variable length sequence of packets |
- | | | at the flow initialization with the purpose of identifying the |
- | | | traffic type and application. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 4 | Push/pop labels | Push/pop VLAN/MPLS labels to/from the current packet. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 5 | Network Address Translation (NAT) | Translate between the internal (LAN) and external (WAN) IP |
- | | | destination/source address and/or L4 protocol destination/source |
- | | | port. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 6 | TTL update | Decrement IP TTL and, in case of IPv4 packets, update the IP |
- | | | checksum. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
- | 7 | Sym Crypto | Generate Cryptodev session based on the user-specified algorithm |
- | | | and key(s), and assemble the cryptodev operation based on the |
- | | | predefined offsets. |
- | | | |
- +---+-----------------------------------+---------------------------------------------------------------------+
-
-Multicore Scaling
------------------
-
-A complex application is typically split across multiple cores, with cores communicating through SW queues.
-There is usually a performance limit on the number of table lookups
-and actions that can be fitted on the same CPU core due to HW constraints like:
-available CPU cycles, cache memory size, cache transfer BW, memory transfer BW, etc.
-
-As the application is split across multiple CPU cores, the Packet Framework facilitates the creation of several pipelines,
-the assignment of each such pipeline to a different CPU core
-and the interconnection of all CPU core-level pipelines into a single application-level complex pipeline.
-For example, if CPU core A is assigned to run pipeline P1 and CPU core B pipeline P2,
-then the interconnection of P1 with P2 could be achieved by having the same set of SW queues act like output ports
-for P1 and input ports for P2.
-
-This approach enables the application development using the pipeline, run-to-completion (clustered) or hybrid (mixed) models.
-
-It is allowed for the same core to run several pipelines, but it is not allowed for several cores to run the same pipeline.
-
-Shared Data Structures
-~~~~~~~~~~~~~~~~~~~~~~
-
-The threads performing table lookup are actually table writers rather than just readers.
-Even if the specific table lookup algorithm is thread-safe for multiple readers
-(e. g. read-only access of the search algorithm data structures is enough to conduct the lookup operation),
-once the table entry for the current packet is identified, the thread is typically expected to update the action meta-data stored in the table entry
-(e.g. increment the counter tracking the number of packets that hit this table entry), and thus modify the table entry.
-During the time this thread is accessing this table entry (either writing or reading; duration is application specific),
-for data consistency reasons, no other threads (threads performing table lookup or entry add/delete operations) are allowed to modify this table entry.
-
-Mechanisms to share the same table between multiple threads:
-
-#. **Multiple writer threads.**
- Threads need to use synchronization primitives like semaphores (distinct semaphore per table entry) or atomic instructions.
- The cost of semaphores is usually high, even when the semaphore is free.
- The cost of atomic instructions is normally higher than the cost of regular instructions.
-
-#. **Multiple writer threads, with single thread performing table lookup operations and multiple threads performing table entry add/delete operations.**
- The threads performing table entry add/delete operations send table update requests to the reader (typically through message passing queues),
- which does the actual table updates and then sends the response back to the request initiator.
-
-#. **Single writer thread performing table entry add/delete operations and multiple reader threads that perform table lookup operations with read-only access to the table entries.**
- The reader threads use the main table copy while the writer is updating the mirror copy.
- Once the writer update is done, the writer can signal to the readers and busy wait until all readers swap between the main copy (which now becomes the mirror copy) and
- the mirror copy (which now becomes the main copy).
-
-Interfacing with Accelerators
------------------------------
-
-The presence of accelerators is usually detected during the initialization phase by inspecting the HW devices that are part of the system (e.g. by PCI bus enumeration).
-Typical devices with acceleration capabilities are:
-
-* Inline accelerators: NICs, switches, FPGAs, etc;
-
-* Look-aside accelerators: chipsets, FPGAs, Intel QuickAssist, etc.
-
-Usually, to support a specific functional block, specific implementation of Packet Framework tables and/or ports and/or actions has to be provided for each accelerator,
-with all the implementations sharing the same API: pure SW implementation (no acceleration), implementation using accelerator A, implementation using accelerator B, etc.
-The selection between these implementations could be done at build time or at run-time (recommended), based on which accelerators are present in the system,
-with no application changes required.
-
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 6ad7698c6b8c4f950c9642798bbad36acc814ef9..758652a492e600b267feba131ddcf943106c8c8b 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* 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_*)
- will gradually transition from experimental to stable status.
-
* table: The table library legacy API (functions rte_table_*)
will be deprecated and subsequently removed in DPDK 24.11 release.
Before this, the new table library API (functions rte_swx_table_*)
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index fc84ba367ea730c393caf11883a09024b6c07688..f7d34aa1ee7fd363f456ecf27effdbfb65efbad5 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -84,6 +84,10 @@ Removed Items
the legacy pipeline library API.
The ``pipeline`` example application covers the SWX pipeline API.
+* Removed the legacy pipeline library API: ``rte_pipeline_*``,
+ ``rte_port_in_action_*`` and ``rte_table_action_*`` functions.
+ The SWX pipeline API (``rte_swx_pipeline_*``) remains.
+
API Changes
-----------
diff --git a/lib/pipeline/meson.build b/lib/pipeline/meson.build
index 823c7929a7f4734b7e23554b2929290c60faf6c0..997ded67925433316aa447f6004b944a2247f2fc 100644
--- a/lib/pipeline/meson.build
+++ b/lib/pipeline/meson.build
@@ -10,21 +10,15 @@ endif
cflags += no_wvla_cflag
sources = files(
- 'rte_pipeline.c',
- 'rte_port_in_action.c',
- 'rte_table_action.c',
'rte_swx_ipsec.c',
'rte_swx_pipeline.c',
'rte_swx_pipeline_spec.c',
'rte_swx_ctl.c',
)
headers = files(
- 'rte_pipeline.h',
- 'rte_port_in_action.h',
- 'rte_table_action.h',
'rte_swx_ipsec.h',
'rte_swx_pipeline.h',
'rte_swx_extern.h',
'rte_swx_ctl.h',
)
-deps += ['port', 'table', 'meter', 'sched', 'cryptodev', 'ipsec']
+deps += ['port', 'table', 'meter', 'cryptodev', 'ipsec']
diff --git a/lib/pipeline/rte_pipeline.c b/lib/pipeline/rte_pipeline.c
deleted file mode 100644
index fa3c8b77ee4043efeb0060a0e08e17a5cdb17d1d..0000000000000000000000000000000000000000
--- a/lib/pipeline/rte_pipeline.c
+++ /dev/null
@@ -1,1640 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <string.h>
-#include <stdio.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-
-#include "rte_pipeline.h"
-
-RTE_LOG_REGISTER_DEFAULT(pipeline_logtype, INFO);
-#define RTE_LOGTYPE_PIPELINE pipeline_logtype
-
-#define PIPELINE_LOG(level, ...) \
- RTE_LOG_LINE(level, PIPELINE, "" __VA_ARGS__)
-
-#define RTE_TABLE_INVALID UINT32_MAX
-
-#ifdef RTE_PIPELINE_STATS_COLLECT
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask) \
- __extension__ ({ (p)->n_pkts_ah_drop = rte_popcount64(mask); })
-
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter) \
- __extension__ ({ (counter) += (p)->n_pkts_ah_drop; (p)->n_pkts_ah_drop = 0; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p) \
- __extension__ ({ (p)->pkts_drop_mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; })
-
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter) \
-__extension__ ({ \
- uint64_t mask = (p)->action_mask0[RTE_PIPELINE_ACTION_DROP]; \
- mask ^= (p)->pkts_drop_mask; \
- (counter) += rte_popcount64(mask); \
-})
-
-#else
-
-#define RTE_PIPELINE_STATS_AH_DROP_WRITE(p, mask)
-#define RTE_PIPELINE_STATS_AH_DROP_READ(p, counter)
-#define RTE_PIPELINE_STATS_TABLE_DROP0(p)
-#define RTE_PIPELINE_STATS_TABLE_DROP1(p, counter)
-
-#endif
-
-struct rte_port_in {
- /* Input parameters */
- struct rte_port_in_ops ops;
- rte_pipeline_port_in_action_handler f_action;
- void *arg_ah;
- uint32_t burst_size;
-
- /* The table to which this port is connected */
- uint32_t table_id;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* List of enabled ports */
- struct rte_port_in *next;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_port_out {
- /* Input parameters */
- struct rte_port_out_ops ops;
- rte_pipeline_port_out_action_handler f_action;
- void *arg_ah;
-
- /* Handle to low-level port */
- void *h_port;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-struct rte_table {
- /* Input parameters */
- struct rte_table_ops ops;
- rte_pipeline_table_action_handler_hit f_action_hit;
- rte_pipeline_table_action_handler_miss f_action_miss;
- void *arg_ah;
- struct rte_pipeline_table_entry *default_entry;
- uint32_t entry_size;
-
- uint32_t table_next_id;
- uint32_t table_next_id_valid;
-
- /* Handle to the low-level table object */
- void *h_table;
-
- /* Statistics */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
- uint64_t n_pkts_dropped_lkp_hit;
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-#define RTE_PIPELINE_MAX_NAME_SZ 124
-
-struct __rte_cache_aligned rte_pipeline {
- /* Input parameters */
- char name[RTE_PIPELINE_MAX_NAME_SZ];
- int socket_id;
- uint32_t offset_port_id;
-
- /* Internal tables */
- struct rte_port_in ports_in[RTE_PIPELINE_PORT_IN_MAX];
- struct rte_port_out ports_out[RTE_PIPELINE_PORT_OUT_MAX];
- struct rte_table tables[RTE_PIPELINE_TABLE_MAX];
-
- /* Occupancy of internal tables */
- uint32_t num_ports_in;
- uint32_t num_ports_out;
- uint32_t num_tables;
-
- /* List of enabled ports */
- uint64_t enabled_port_in_mask;
- struct rte_port_in *port_in_next;
-
- /* Pipeline run structures */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_pipeline_table_entry *entries[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t action_mask0[RTE_PIPELINE_ACTIONS];
- uint64_t action_mask1[RTE_PIPELINE_ACTIONS];
- uint64_t pkts_mask;
- uint64_t n_pkts_ah_drop;
- uint64_t pkts_drop_mask;
-};
-
-static inline uint32_t
-rte_mask_get_next(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask << ((63 - pos) & 0x3F)) |
- (mask >> ((pos + 1) & 0x3F));
- return (rte_ctz64(mask_rot) - (63 - pos)) & 0x3F;
-}
-
-static inline uint32_t
-rte_mask_get_prev(uint64_t mask, uint32_t pos)
-{
- uint64_t mask_rot = (mask >> (pos & 0x3F)) |
- (mask << ((64 - pos) & 0x3F));
- return ((63 - rte_clz64(mask_rot)) + pos) & 0x3F;
-}
-
-static void
-rte_pipeline_table_free(struct rte_table *table);
-
-static void
-rte_pipeline_port_in_free(struct rte_port_in *port);
-
-static void
-rte_pipeline_port_out_free(struct rte_port_out *port);
-
-/*
- * Pipeline
- */
-static int
-rte_pipeline_check_params(struct rte_pipeline_params *params)
-{
- if (params == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter params", __func__);
- return -EINVAL;
- }
-
- /* name */
- if (params->name == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter name", __func__);
- return -EINVAL;
- }
-
- /* socket */
- if (params->socket_id < 0) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for parameter socket_id",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_create)
-struct rte_pipeline *
-rte_pipeline_create(struct rte_pipeline_params *params)
-{
- struct rte_pipeline *p;
- int status;
-
- /* Check input parameters */
- status = rte_pipeline_check_params(params);
- if (status != 0) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline params check failed (%d)",
- __func__, status);
- return NULL;
- }
-
- /* Allocate memory for the pipeline on requested socket */
- p = rte_zmalloc_socket("PIPELINE", sizeof(struct rte_pipeline),
- RTE_CACHE_LINE_SIZE, params->socket_id);
-
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Pipeline memory allocation failed", __func__);
- return NULL;
- }
-
- /* Save input parameters */
- strlcpy(p->name, params->name, RTE_PIPELINE_MAX_NAME_SZ);
- p->socket_id = params->socket_id;
- p->offset_port_id = params->offset_port_id;
-
- /* Initialize pipeline internal data structure */
- p->num_ports_in = 0;
- p->num_ports_out = 0;
- p->num_tables = 0;
- p->enabled_port_in_mask = 0;
- p->port_in_next = NULL;
- p->pkts_mask = 0;
- p->n_pkts_ah_drop = 0;
-
- return p;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_free)
-int
-rte_pipeline_free(struct rte_pipeline *p)
-{
- uint32_t i;
-
- /* Check input parameters */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: rte_pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free input ports */
- for (i = 0; i < p->num_ports_in; i++) {
- struct rte_port_in *port = &p->ports_in[i];
-
- rte_pipeline_port_in_free(port);
- }
-
- /* Free tables */
- for (i = 0; i < p->num_tables; i++) {
- struct rte_table *table = &p->tables[i];
-
- rte_pipeline_table_free(table);
- }
-
- /* Free output ports */
- for (i = 0; i < p->num_ports_out; i++) {
- struct rte_port_out *port = &p->ports_out[i];
-
- rte_pipeline_port_out_free(port);
- }
-
- /* Free pipeline memory */
- rte_free(p);
-
- return 0;
-}
-
-/*
- * Table
- */
-static int
-rte_table_check_params(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (table_id == NULL) {
- PIPELINE_LOG(ERR, "%s: table_id parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_lookup == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_lookup function pointer is NULL", __func__);
- return -EINVAL;
- }
-
- /* De we have room for one more table? */
- if (p->num_tables == RTE_PIPELINE_TABLE_MAX) {
- PIPELINE_LOG(ERR,
- "%s: Incorrect value for num_tables parameter",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_create)
-int
-rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id)
-{
- struct rte_table *table;
- struct rte_pipeline_table_entry *default_entry;
- void *h_table;
- uint32_t entry_size, id;
- int status;
-
- /* Check input arguments */
- status = rte_table_check_params(p, params, table_id);
- if (status != 0)
- return status;
-
- id = p->num_tables;
- table = &p->tables[id];
-
- /* Allocate space for the default table entry */
- entry_size = sizeof(struct rte_pipeline_table_entry) +
- params->action_data_size;
- default_entry = rte_zmalloc_socket(
- "PIPELINE", entry_size, RTE_CACHE_LINE_SIZE, p->socket_id);
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: Failed to allocate default entry", __func__);
- return -EINVAL;
- }
-
- /* Create the table */
- h_table = params->ops->f_create(params->arg_create, p->socket_id,
- entry_size);
- if (h_table == NULL) {
- rte_free(default_entry);
- PIPELINE_LOG(ERR, "%s: Table creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_tables++;
- *table_id = id;
-
- /* Save input parameters */
- table->ops = *params->ops;
- table->f_action_hit = params->f_action_hit;
- table->f_action_miss = params->f_action_miss;
- table->arg_ah = params->arg_ah;
- table->entry_size = entry_size;
-
- /* Clear the lookup miss actions (to be set later through API) */
- table->default_entry = default_entry;
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- /* Initialize table internal data structure */
- table->h_table = h_table;
- table->table_next_id = 0;
- table->table_next_id_valid = 0;
-
- return 0;
-}
-
-void
-rte_pipeline_table_free(struct rte_table *table)
-{
- if (table->ops.f_free != NULL)
- table->ops.f_free(table->h_table);
-
- rte_free(table->default_entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_add)
-int
-rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (default_entry == NULL) {
- PIPELINE_LOG(ERR,
- "%s: default_entry parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (default_entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Set the lookup miss actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = default_entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- memcpy(table->default_entry, default_entry, table->entry_size);
-
- *default_entry_ptr = table->default_entry;
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_default_entry_delete)
-int
-rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR,
- "%s: pipeline parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- /* Save the current contents of the default entry */
- if (entry)
- memcpy(entry, table->default_entry, table->entry_size);
-
- /* Clear the lookup miss actions */
- memset(table->default_entry, 0, table->entry_size);
- table->default_entry->action = RTE_PIPELINE_ACTION_DROP;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add)
-int
-rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entry == NULL) {
- PIPELINE_LOG(ERR, "%s: entry parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entry->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
-
- /* Add entry */
- if ((entry->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entry->table_id;
- table->table_next_id_valid = 1;
- }
-
- return (table->ops.f_add)(table->h_table, key, (void *) entry,
- key_found, (void **) entry_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete)
-int
-rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (key == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete)(table->h_table, key, key_found, entry);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_add_bulk)
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr)
-{
- struct rte_table *table;
- uint32_t i;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: keys parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if (entries == NULL) {
- PIPELINE_LOG(ERR, "%s: entries parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_add_bulk == NULL) {
- PIPELINE_LOG(ERR, "%s: f_add_bulk function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- table->table_next_id_valid &&
- (entries[i]->table_id != table->table_next_id)) {
- PIPELINE_LOG(ERR,
- "%s: Tree-like topologies not allowed", __func__);
- return -EINVAL;
- }
- }
-
- /* Add entry */
- for (i = 0; i < n_keys; i++) {
- if ((entries[i]->action == RTE_PIPELINE_ACTION_TABLE) &&
- (table->table_next_id_valid == 0)) {
- table->table_next_id = entries[i]->table_id;
- table->table_next_id_valid = 1;
- }
- }
-
- return (table->ops.f_add_bulk)(table->h_table, keys, (void **) entries,
- n_keys, key_found, (void **) entries_ptr);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_entry_delete_bulk)
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries)
-{
- struct rte_table *table;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (keys == NULL) {
- PIPELINE_LOG(ERR, "%s: key parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table_id %d out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
-
- if (table->ops.f_delete_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_delete function pointer NULL", __func__);
- return -EINVAL;
- }
-
- return (table->ops.f_delete_bulk)(table->h_table, keys, n_keys, key_found,
- (void **) entries);
-}
-
-/*
- * Port
- */
-static int
-rte_pipeline_port_in_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_rx == NULL) {
- PIPELINE_LOG(ERR, "%s: f_rx function pointer NULL",
- __func__);
- return -EINVAL;
- }
-
- /* burst_size */
- if ((params->burst_size == 0) ||
- (params->burst_size > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PIPELINE_LOG(ERR, "%s: invalid value for burst_size",
- __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_in == RTE_PIPELINE_PORT_IN_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_in", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-rte_pipeline_port_out_check_params(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params == NULL) {
- PIPELINE_LOG(ERR, "%s: params parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id == NULL) {
- PIPELINE_LOG(ERR, "%s: port_id parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* ops */
- if (params->ops == NULL) {
- PIPELINE_LOG(ERR, "%s: params->ops parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_create == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_create function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx function pointer NULL", __func__);
- return -EINVAL;
- }
-
- if (params->ops->f_tx_bulk == NULL) {
- PIPELINE_LOG(ERR,
- "%s: f_tx_bulk function pointer NULL", __func__);
- return -EINVAL;
- }
-
- /* Do we have room for one more port? */
- if (p->num_ports_out == RTE_PIPELINE_PORT_OUT_MAX) {
- PIPELINE_LOG(ERR,
- "%s: invalid value for num_ports_out", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_create)
-int
-rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id)
-{
- struct rte_port_in *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_in_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_in;
- port = &p->ports_in[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_in++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
- port->burst_size = params->burst_size;
-
- /* Initialize port internal data structure */
- port->table_id = RTE_TABLE_INVALID;
- port->h_port = h_port;
- port->next = NULL;
-
- return 0;
-}
-
-void
-rte_pipeline_port_in_free(struct rte_port_in *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_create)
-int
-rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id)
-{
- struct rte_port_out *port;
- void *h_port;
- uint32_t id;
- int status;
-
- /* Check input arguments */
- status = rte_pipeline_port_out_check_params(p, params, port_id);
- if (status != 0)
- return status;
-
- id = p->num_ports_out;
- port = &p->ports_out[id];
-
- /* Create the port */
- h_port = params->ops->f_create(params->arg_create, p->socket_id);
- if (h_port == NULL) {
- PIPELINE_LOG(ERR, "%s: Port creation failed", __func__);
- return -EINVAL;
- }
-
- /* Commit current table to the pipeline */
- p->num_ports_out++;
- *port_id = id;
-
- /* Save input parameters */
- port->ops = *params->ops;
- port->f_action = params->f_action;
- port->arg_ah = params->arg_ah;
-
- /* Initialize port internal data structure */
- port->h_port = h_port;
-
- return 0;
-}
-
-void
-rte_pipeline_port_out_free(struct rte_port_out *port)
-{
- if (port->ops.f_free != NULL)
- port->ops.f_free(port->h_port);
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_connect_to_table)
-int
-rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id)
-{
- struct rte_port_in *port;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: Table ID %u is out of range",
- __func__, table_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
- port->table_id = table_id;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_enable)
-int
-rte_pipeline_port_in_enable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already enabled */
- port_mask = 1LLU << port_id;
- if (p->enabled_port_in_mask & port_mask)
- return 0;
-
- p->enabled_port_in_mask |= port_mask;
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port;
- port->next = port_next;
-
- /* Check if list of enabled ports was previously empty */
- if (p->enabled_port_in_mask == port_mask)
- p->port_in_next = port;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_disable)
-int
-rte_pipeline_port_in_disable(struct rte_pipeline *p, uint32_t port_id)
-{
- struct rte_port_in *port, *port_prev, *port_next;
- uint64_t port_mask;
- uint32_t port_prev_id, port_next_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR, "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- /* Return if current input port is already disabled */
- port_mask = 1LLU << port_id;
- if ((p->enabled_port_in_mask & port_mask) == 0)
- return 0;
-
- p->enabled_port_in_mask &= ~port_mask;
-
- /* Return if no other enabled ports */
- if (p->enabled_port_in_mask == 0) {
- p->port_in_next = NULL;
-
- return 0;
- }
-
- /* Add current input port to the pipeline chain of enabled ports */
- port_prev_id = rte_mask_get_prev(p->enabled_port_in_mask, port_id);
- port_next_id = rte_mask_get_next(p->enabled_port_in_mask, port_id);
-
- port_prev = &p->ports_in[port_prev_id];
- port_next = &p->ports_in[port_next_id];
-
- port_prev->next = port_next;
-
- /* Check if the port which has just been disabled is next to serve */
- if (port == p->port_in_next)
- p->port_in_next = port_next;
-
- return 0;
-}
-
-/*
- * Pipeline run-time
- */
-RTE_EXPORT_SYMBOL(rte_pipeline_check)
-int
-rte_pipeline_check(struct rte_pipeline *p)
-{
- uint32_t port_in_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- /* Check that pipeline has at least one input port, one table and one
- output port */
- if (p->num_ports_in == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 input port",
- __func__);
- return -EINVAL;
- }
- if (p->num_tables == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 table",
- __func__);
- return -EINVAL;
- }
- if (p->num_ports_out == 0) {
- PIPELINE_LOG(ERR, "%s: must have at least 1 output port",
- __func__);
- return -EINVAL;
- }
-
- /* Check that all input ports are connected */
- for (port_in_id = 0; port_in_id < p->num_ports_in; port_in_id++) {
- struct rte_port_in *port_in = &p->ports_in[port_in_id];
-
- if (port_in->table_id == RTE_TABLE_INVALID) {
- PIPELINE_LOG(ERR,
- "%s: Port IN ID %u is not connected",
- __func__, port_in_id);
- return -EINVAL;
- }
- }
-
- return 0;
-}
-
-static inline void
-rte_pipeline_compute_masks(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->action_mask1[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask1[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos = p->entries[i]->action;
-
- p->action_mask1[pos] |= pkt_mask;
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- uint32_t pos;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pos = p->entries[i]->action;
- p->action_mask1[pos] |= pkt_mask;
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_bulk(struct rte_pipeline *p,
- uint64_t pkts_mask, uint32_t port_id)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- p->pkts_mask = pkts_mask;
-
- /* Output port user actions */
- if (port_out->f_action != NULL) {
- port_out->f_action(p, p->pkts, pkts_mask, port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
- }
-
- /* Output port TX */
- if (p->pkts_mask != 0)
- port_out->ops.f_tx_bulk(port_out->h_port,
- p->pkts,
- p->pkts_mask);
-}
-
-static inline void
-rte_pipeline_action_handler_port(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id = p->entries[i]->port_id;
- struct rte_port_out *port_out =
- &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = p->entries[i]->port_id;
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_port_meta(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- p->pkts_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = p->pkts[i];
- uint32_t port_out_id =
- RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- struct rte_port_out *port_out = &p->ports_out[
- port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- uint64_t pkt_mask = 1LLU << i;
-
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
- struct rte_mbuf *pkt;
- struct rte_port_out *port_out;
- uint32_t port_out_id;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- pkt = p->pkts[i];
- port_out_id = RTE_MBUF_METADATA_UINT32(pkt,
- p->offset_port_id);
- port_out = &p->ports_out[port_out_id];
-
- /* Output port user actions */
- if (port_out->f_action == NULL) /* Output port TX */
- port_out->ops.f_tx(port_out->h_port, pkt);
- else {
- port_out->f_action(p,
- p->pkts,
- pkt_mask,
- port_out->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_out->n_pkts_dropped_by_ah);
-
- /* Output port TX */
- if (pkt_mask & p->pkts_mask)
- port_out->ops.f_tx(port_out->h_port,
- pkt);
- }
- }
- }
-}
-
-static inline void
-rte_pipeline_action_handler_drop(struct rte_pipeline *p, uint64_t pkts_mask)
-{
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- rte_pktmbuf_free(p->pkts[i]);
- } else {
- uint32_t i;
-
- for (i = 0; i < RTE_PORT_IN_BURST_SIZE_MAX; i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if ((pkt_mask & pkts_mask) == 0)
- continue;
-
- rte_pktmbuf_free(p->pkts[i]);
- }
- }
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_run)
-int
-rte_pipeline_run(struct rte_pipeline *p)
-{
- struct rte_port_in *port_in = p->port_in_next;
- uint32_t n_pkts, table_id;
-
- if (port_in == NULL)
- return 0;
-
- /* Input port RX */
- n_pkts = port_in->ops.f_rx(port_in->h_port, p->pkts,
- port_in->burst_size);
- if (n_pkts == 0) {
- p->port_in_next = port_in->next;
- return 0;
- }
-
- p->pkts_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] = 0;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
-
- /* Input port user actions */
- if (port_in->f_action != NULL) {
- port_in->f_action(p, p->pkts, n_pkts, port_in->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- port_in->n_pkts_dropped_by_ah);
- }
-
- /* Table */
- for (table_id = port_in->table_id; p->pkts_mask != 0; ) {
- struct rte_table *table;
- uint64_t lookup_hit_mask, lookup_miss_mask;
-
- /* Lookup */
- table = &p->tables[table_id];
- table->ops.f_lookup(table->h_table, p->pkts, p->pkts_mask,
- &lookup_hit_mask, (void **) p->entries);
- lookup_miss_mask = p->pkts_mask & (~lookup_hit_mask);
-
- /* Lookup miss */
- if (lookup_miss_mask != 0) {
- struct rte_pipeline_table_entry *default_entry =
- table->default_entry;
-
- p->pkts_mask = lookup_miss_mask;
-
- /* Table user actions */
- if (table->f_action_miss != NULL) {
- table->f_action_miss(p,
- p->pkts,
- lookup_miss_mask,
- default_entry,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_miss_ah);
- }
-
- /* Table reserved actions */
- if ((default_entry->action == RTE_PIPELINE_ACTION_PORT) &&
- (p->pkts_mask != 0))
- rte_pipeline_action_handler_port_bulk(p,
- p->pkts_mask,
- default_entry->port_id);
- else {
- uint32_t pos = default_entry->action;
-
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
-
- p->action_mask0[pos] |= p->pkts_mask;
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_miss);
- }
- }
-
- /* Lookup hit */
- if (lookup_hit_mask != 0) {
- p->pkts_mask = lookup_hit_mask;
-
- /* Table user actions */
- if (table->f_action_hit != NULL) {
- table->f_action_hit(p,
- p->pkts,
- lookup_hit_mask,
- p->entries,
- table->arg_ah);
-
- RTE_PIPELINE_STATS_AH_DROP_READ(p,
- table->n_pkts_dropped_by_lkp_hit_ah);
- }
-
- /* Table reserved actions */
- RTE_PIPELINE_STATS_TABLE_DROP0(p);
- rte_pipeline_compute_masks(p, p->pkts_mask);
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_DROP];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT];
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_PORT_META];
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] |=
- p->action_mask1[
- RTE_PIPELINE_ACTION_TABLE];
-
- RTE_PIPELINE_STATS_TABLE_DROP1(p,
- table->n_pkts_dropped_lkp_hit);
- }
-
- /* Prepare for next iteration */
- p->pkts_mask = p->action_mask0[RTE_PIPELINE_ACTION_TABLE];
- table_id = table->table_next_id;
- p->action_mask0[RTE_PIPELINE_ACTION_TABLE] = 0;
- }
-
- /* Table reserved action PORT */
- rte_pipeline_action_handler_port(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT]);
-
- /* Table reserved action PORT META */
- rte_pipeline_action_handler_port_meta(p,
- p->action_mask0[RTE_PIPELINE_ACTION_PORT_META]);
-
- /* Table reserved action DROP */
- rte_pipeline_action_handler_drop(p,
- p->action_mask0[RTE_PIPELINE_ACTION_DROP]);
-
- /* Pick candidate for next port IN to serve */
- p->port_in_next = port_in->next;
-
- return (int) n_pkts;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_flush)
-int
-rte_pipeline_flush(struct rte_pipeline *p)
-{
- uint32_t port_id;
-
- /* Check input arguments */
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- for (port_id = 0; port_id < p->num_ports_out; port_id++) {
- struct rte_port_out *port = &p->ports_out[port_id];
-
- if (port->ops.f_flush != NULL)
- port->ops.f_flush(port->h_port);
- }
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_packet_insert)
-int
-rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id, struct rte_mbuf *pkt)
-{
- struct rte_port_out *port_out = &p->ports_out[port_id];
-
- port_out->ops.f_tx(port_out->h_port, pkt); /* Output port TX */
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_hijack)
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_ah_packet_drop)
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask)
-{
- pkts_mask &= p->pkts_mask;
- p->pkts_mask &= ~pkts_mask;
- p->action_mask0[RTE_PIPELINE_ACTION_DROP] |= pkts_mask;
-
- RTE_PIPELINE_STATS_AH_DROP_WRITE(p, pkts_mask);
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_in_stats_read)
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear)
-{
- struct rte_port_in *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_in) {
- PIPELINE_LOG(ERR,
- "%s: port IN ID %u is out of range",
- __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_in[port_id];
-
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_port_out_stats_read)
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear)
-{
- struct rte_port_out *port;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL", __func__);
- return -EINVAL;
- }
-
- if (port_id >= p->num_ports_out) {
- PIPELINE_LOG(ERR,
- "%s: port OUT ID %u is out of range", __func__, port_id);
- return -EINVAL;
- }
-
- port = &p->ports_out[port_id];
- if (port->ops.f_stats != NULL) {
- retval = port->ops.f_stats(port->h_port, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL)
- stats->n_pkts_dropped_by_ah = port->n_pkts_dropped_by_ah;
-
- if (clear != 0)
- port->n_pkts_dropped_by_ah = 0;
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_pipeline_table_stats_read)
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear)
-{
- struct rte_table *table;
- int retval;
-
- if (p == NULL) {
- PIPELINE_LOG(ERR, "%s: pipeline parameter NULL",
- __func__);
- return -EINVAL;
- }
-
- if (table_id >= p->num_tables) {
- PIPELINE_LOG(ERR,
- "%s: table %u is out of range", __func__, table_id);
- return -EINVAL;
- }
-
- table = &p->tables[table_id];
- if (table->ops.f_stats != NULL) {
- retval = table->ops.f_stats(table->h_table, &stats->stats, clear);
- if (retval != 0)
- return retval;
- } else if (stats != NULL)
- memset(&stats->stats, 0, sizeof(stats->stats));
-
- if (stats != NULL) {
- stats->n_pkts_dropped_by_lkp_hit_ah =
- table->n_pkts_dropped_by_lkp_hit_ah;
- stats->n_pkts_dropped_by_lkp_miss_ah =
- table->n_pkts_dropped_by_lkp_miss_ah;
- stats->n_pkts_dropped_lkp_hit = table->n_pkts_dropped_lkp_hit;
- stats->n_pkts_dropped_lkp_miss = table->n_pkts_dropped_lkp_miss;
- }
-
- if (clear != 0) {
- table->n_pkts_dropped_by_lkp_hit_ah = 0;
- table->n_pkts_dropped_by_lkp_miss_ah = 0;
- table->n_pkts_dropped_lkp_hit = 0;
- table->n_pkts_dropped_lkp_miss = 0;
- }
-
- return 0;
-}
diff --git a/lib/pipeline/rte_pipeline.h b/lib/pipeline/rte_pipeline.h
deleted file mode 100644
index c9e7172453efc38976fc4a1c53efb7aa849ccc96..0000000000000000000000000000000000000000
--- a/lib/pipeline/rte_pipeline.h
+++ /dev/null
@@ -1,840 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PIPELINE_H__
-#define __INCLUDE_RTE_PIPELINE_H__
-
-/**
- * @file
- * RTE Pipeline
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard methodology (logically similar to OpenFlow) for rapid development
- * of complex packet processing pipelines out of ports, tables and actions.
- *
- * <B>Basic operation.</B> A pipeline is constructed by connecting its input
- * ports to its output ports through a chain of lookup tables. As result of
- * lookup operation into the current table, one of the table entries (or the
- * default table entry, in case of lookup miss) is identified to provide the
- * actions to be executed on the current packet and the associated action
- * meta-data. The behavior of user actions is defined through the configurable
- * table action handler, while the reserved actions define the next hop for the
- * current packet (either another table, an output port or packet drop) and are
- * handled transparently by the framework.
- *
- * <B>Initialization and run-time flows.</B> Once all the pipeline elements
- * (input ports, tables, output ports) have been created, input ports connected
- * to tables, table action handlers configured, tables populated with the
- * initial set of entries (actions and action meta-data) and input ports
- * enabled, the pipeline runs automatically, pushing packets from input ports
- * to tables and output ports. At each table, the identified user actions are
- * being executed, resulting in action meta-data (stored in the table entry)
- * and packet meta-data (stored with the packet descriptor) being updated. The
- * pipeline tables can have further updates and input ports can be disabled or
- * enabled later on as required.
- *
- * <B>Multi-core scaling.</B> Typically, each CPU core will run its own
- * pipeline instance. Complex application-level pipelines can be implemented by
- * interconnecting multiple CPU core-level pipelines in tree-like topologies,
- * as the same port devices (e.g. SW rings) can serve as output ports for the
- * pipeline running on CPU core A, as well as input ports for the pipeline
- * running on CPU core B. This approach enables the application development
- * using the pipeline (CPU cores connected serially), cluster/run-to-completion
- * (CPU cores connected in parallel) or mixed (pipeline of CPU core clusters)
- * programming models.
- *
- * <B>Thread safety.</B> It is possible to have multiple pipelines running on
- * the same CPU core, but it is not allowed (for thread safety reasons) to have
- * multiple CPU cores running the same pipeline instance.
- */
-
-#include <stdint.h>
-
-#include <rte_port.h>
-#include <rte_table.h>
-#include <rte_common.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_mbuf;
-
-/*
- * Pipeline
- */
-/** Opaque data type for pipeline */
-struct rte_pipeline;
-
-/** Parameters for pipeline creation */
-struct rte_pipeline_params {
- /** Pipeline name */
- const char *name;
-
- /** CPU socket ID where memory for the pipeline and its elements (ports
- and tables) should be allocated */
- int socket_id;
-
- /** Offset within packet meta-data to port_id to be used by action
- "Send packet to output port read from packet meta-data". Has to be
- 4-byte aligned. */
- uint32_t offset_port_id;
-};
-
-/** Pipeline port in stats. */
-struct rte_pipeline_port_in_stats {
- /** Port in stats. */
- struct rte_port_in_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-
-};
-
-/** Pipeline port out stats. */
-struct rte_pipeline_port_out_stats {
- /** Port out stats. */
- struct rte_port_out_stats stats;
-
- /** Number of packets dropped by action handler. */
- uint64_t n_pkts_dropped_by_ah;
-};
-
-/** Pipeline table stats. */
-struct rte_pipeline_table_stats {
- /** Table stats. */
- struct rte_table_stats stats;
-
- /** Number of packets dropped by lookup hit action handler. */
- uint64_t n_pkts_dropped_by_lkp_hit_ah;
-
- /** Number of packets dropped by lookup miss action handler. */
- uint64_t n_pkts_dropped_by_lkp_miss_ah;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_hit;
-
- /** Number of packets dropped by pipeline in behalf of this
- * table based on action specified in table entry. */
- uint64_t n_pkts_dropped_lkp_miss;
-};
-
-/**
- * Pipeline create
- *
- * @param params
- * Parameters for pipeline creation
- * @return
- * Handle to pipeline instance on success or NULL otherwise
- */
-struct rte_pipeline *rte_pipeline_create(struct rte_pipeline_params *params);
-
-/**
- * Pipeline free
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_free(struct rte_pipeline *p);
-
-/**
- * Pipeline consistency check
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_check(struct rte_pipeline *p);
-
-/**
- * Pipeline run
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * Number of packets read and processed
- */
-int rte_pipeline_run(struct rte_pipeline *p);
-
-/**
- * Pipeline flush
- *
- * @param p
- * Handle to pipeline instance
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_flush(struct rte_pipeline *p);
-
-/*
- * Actions
- */
-/** Reserved actions */
-enum rte_pipeline_action {
- /** Drop the packet */
- RTE_PIPELINE_ACTION_DROP = 0,
-
- /** Send packet to output port */
- RTE_PIPELINE_ACTION_PORT,
-
- /** Send packet to output port read from packet meta-data */
- RTE_PIPELINE_ACTION_PORT_META,
-
- /** Send packet to table */
- RTE_PIPELINE_ACTION_TABLE,
-
- /** Number of reserved actions */
- RTE_PIPELINE_ACTIONS
-};
-
-/*
- * Table
- */
-/** Maximum number of tables allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_TABLE_MAX 64
-
-/**
- * Head format for the table entry of any pipeline table. For any given
- * pipeline table, all table entries should have the same size and format. For
- * any given pipeline table, the table entry has to start with a head of this
- * structure, which contains the reserved actions and their associated
- * meta-data, and then optionally continues with user actions and their
- * associated meta-data. As all the currently defined reserved actions are
- * mutually exclusive, only one reserved action can be set per table entry.
- */
-struct rte_pipeline_table_entry {
- /** Reserved action */
- enum rte_pipeline_action action;
-
- union {
- /** Output port ID (meta-data for "Send packet to output port"
- action) */
- uint32_t port_id;
- /** Table ID (meta-data for "Send packet to table" action) */
- uint32_t table_id;
- };
- /** Start of table entry area for user defined actions and meta-data */
- uint8_t action_data[];
-};
-
-/**
- * Pipeline table action handler on lookup hit
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet and element n of entries array is pointing to a valid table
- * entry associated with the packet, with the association typically done by
- * the table lookup operation. Otherwise, element n of pkts array and element
- * n of entries array will not be accessed.
- * @param entries
- * Set of table entries specified as array of up to 64 pointers to struct
- * rte_pipeline_table_entry
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_hit)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg);
-
-/**
- * Pipeline table action handler on lookup miss
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param entry
- * Single table entry associated with all the valid packets from the input
- * burst, specified as pointer to struct rte_pipeline_table_entry.
- * This entry is the pipeline table default entry that is associated by the
- * table lookup operation with the input packets that have resulted in lookup
- * miss.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_table_action_handler_miss)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry *entry,
- void *arg);
-
-/** Parameters for pipeline table creation. Action handlers have to be either
- both enabled or both disabled (they can be disabled by setting them to
- NULL). */
-struct rte_pipeline_table_params {
- /** Table operations (specific to each table type) */
- struct rte_table_ops *ops;
- /** Opaque param to be passed to the table create operation when
- invoked */
- void *arg_create;
- /** Callback function to execute the user actions on input packets in
- case of lookup hit */
- rte_pipeline_table_action_handler_hit f_action_hit;
- /** Callback function to execute the user actions on input packets in
- case of lookup miss */
- rte_pipeline_table_action_handler_miss f_action_miss;
-
- /** Opaque parameter to be passed to lookup hit and/or lookup miss
- action handlers when invoked */
- void *arg_ah;
- /** Memory size to be reserved per table entry for storing the user
- actions and their meta-data */
- uint32_t action_data_size;
-};
-
-/**
- * Pipeline table create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline table creation
- * @param table_id
- * Table ID. Valid only within the scope of table IDs of the current
- * pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_create(struct rte_pipeline *p,
- struct rte_pipeline_table_params *params,
- uint32_t *table_id);
-
-/**
- * Pipeline table default entry add
- *
- * The contents of the table default entry is updated with the provided actions
- * and meta-data. When the default entry is not configured (by using this
- * function), the built-in default entry has the action "Drop" and meta-data
- * set to all-zeros.
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param default_entry
- * New contents for the table default entry
- * @param default_entry_ptr
- * On successful invocation, pointer to the default table entry which can be
- * used for further read-write accesses to this table entry. This pointer
- * is valid until the default entry is deleted or re-added.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *default_entry,
- struct rte_pipeline_table_entry **default_entry_ptr);
-
-/**
- * Pipeline table default entry delete
- *
- * The new contents of the table default entry is set to reserved action "Drop
- * the packet" with meta-data cleared (i.e. set to all-zeros).
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param entry
- * On successful invocation, when entry points to a valid buffer, the
- * previous contents of the table default entry (as it was just before the
- * delete operation) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_default_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param entry
- * New contents for the table entry identified by key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * already present in the table before the add operation and to FALSE (value
- * 0) if not
- * @param entry_ptr
- * On successful invocation, pointer to the table entry associated with key.
- * This can be used for further read-write accesses to this table entry and
- * is valid until the key is deleted from the table or re-added (usually for
- * associating different actions and/or action meta-data to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- struct rte_pipeline_table_entry *entry,
- int *key_found,
- struct rte_pipeline_table_entry **entry_ptr);
-
-/**
- * Pipeline table entry delete
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param key
- * Table entry key
- * @param key_found
- * On successful invocation, set to TRUE (value different than 0) if key was
- * found in the table before the delete operation and to FALSE (value 0) if
- * not
- * @param entry
- * On successful invocation, when key is found in the table and entry points
- * to a valid buffer, the table entry contents (as it was before the delete
- * was performed) is copied to this buffer
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete(struct rte_pipeline *p,
- uint32_t table_id,
- void *key,
- int *key_found,
- struct rte_pipeline_table_entry *entry);
-
-/**
- * Pipeline table entry add bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param entries
- * Array containing new contents for every table entry identified by key
- * @param n_keys
- * Number of keys to add
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was already present in the table
- * before the add operation and to FALSE (value 0) if not
- * @param entries_ptr
- * On successful invocation, array *entries_ptr stores pointer to every table
- * entry associated with key. This can be used for further read-write accesses
- * to this table entry and is valid until the key is deleted from the table or
- * re-added (usually for associating different actions and/or action meta-data
- * to the current key)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_add_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- struct rte_pipeline_table_entry **entries,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries_ptr);
-
-/**
- * Pipeline table entry delete bulk
- *
- * @param p
- * Handle to pipeline instance
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @param keys
- * Array containing table entry keys
- * @param n_keys
- * Number of keys to delete
- * @param key_found
- * On successful invocation, key_found for every item in the array is set to
- * TRUE (value different than 0) if key was found in the table before the
- * delete operation and to FALSE (value 0) if not
- * @param entries
- * If entries pointer is NULL, this pointer is ignored for every entry found.
- * Else, after successful invocation, if specific key is found in the table
- * and entry points to a valid buffer, the table entry contents (as it was
- * before the delete was performed) is copied to this buffer.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_entry_delete_bulk(struct rte_pipeline *p,
- uint32_t table_id,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- struct rte_pipeline_table_entry **entries);
-
-/**
- * Read pipeline table stats.
- *
- * This function reads table statistics identified by *table_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param table_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_table_stats_read(struct rte_pipeline *p, uint32_t table_id,
- struct rte_pipeline_table_stats *stats, int clear);
-
-/*
- * Port IN
- */
-/** Maximum number of input ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_IN_MAX 64
-
-/**
- * Pipeline input port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param n
- * Number of packets in the input burst. This parameter specifies that
- * elements 0 to (n-1) of pkts array are valid.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_in_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n,
- void *arg);
-
-/** Parameters for pipeline input port creation */
-struct rte_pipeline_port_in_params {
- /** Input port operations (specific to each table type) */
- struct rte_port_in_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function to execute the user actions on input packets.
- Disabled if set to NULL. */
- rte_pipeline_port_in_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-
- /** Recommended burst size for the RX operation(in number of pkts) */
- uint32_t burst_size;
-};
-
-/**
- * Pipeline input port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline input port creation
- * @param port_id
- * Input port ID. Valid only within the scope of input port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_create(struct rte_pipeline *p,
- struct rte_pipeline_port_in_params *params,
- uint32_t *port_id);
-
-/**
- * Pipeline input port connect to table
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @param table_id
- * Table ID (returned by previous invocation of pipeline table create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_connect_to_table(struct rte_pipeline *p,
- uint32_t port_id,
- uint32_t table_id);
-
-/**
- * Pipeline input port enable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_enable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Pipeline input port disable
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Port ID (returned by previous invocation of pipeline input port create)
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_disable(struct rte_pipeline *p,
- uint32_t port_id);
-
-/**
- * Read pipeline port in stats.
- *
- * This function reads port in statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_in_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats, int clear);
-
-/*
- * Port OUT
- */
-/** Maximum number of output ports allowed for any given pipeline instance. The
- value of this parameter cannot be changed. */
-#define RTE_PIPELINE_PORT_OUT_MAX 64
-
-/**
- * Pipeline output port action handler
- *
- * The action handler can decide to drop packets by resetting the associated
- * packet bit in the pkts_mask parameter. In this case, the action handler is
- * required not to free the packet buffer, which will be freed eventually by
- * the pipeline.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @param arg
- * Opaque parameter registered by the user at the pipeline table creation
- * time
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_pipeline_port_out_action_handler)(
- struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- void *arg);
-
-/** Parameters for pipeline output port creation. The action handlers have to
-be either both enabled or both disabled (by setting them to NULL). When
-enabled, the pipeline selects between them at different moments, based on the
-number of packets that have to be sent to the same output port. */
-struct rte_pipeline_port_out_params {
- /** Output port operations (specific to each table type) */
- struct rte_port_out_ops *ops;
- /** Opaque parameter to be passed to create operation when invoked */
- void *arg_create;
-
- /** Callback function executing the user actions on bust of input
- packets */
- rte_pipeline_port_out_action_handler f_action;
- /** Opaque parameter to be passed to the action handler when invoked */
- void *arg_ah;
-};
-
-/**
- * Pipeline output port create
- *
- * @param p
- * Handle to pipeline instance
- * @param params
- * Parameters for pipeline output port creation
- * @param port_id
- * Output port ID. Valid only within the scope of output port IDs of the
- * current pipeline. Only returned after a successful invocation.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_create(struct rte_pipeline *p,
- struct rte_pipeline_port_out_params *params,
- uint32_t *port_id);
-
-/**
- * Read pipeline port out stats.
- *
- * This function reads port out statistics identified by *port_id* of given
- * pipeline *p*.
- *
- * @param p
- * Handle to pipeline instance.
- * @param port_id
- * Port ID what stats will be returned.
- * @param stats
- * Statistics buffer.
- * @param clear
- * If not 0 clear stats after reading.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_stats_read(struct rte_pipeline *p, uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats, int clear);
-
-/*
- * Functions to be called as part of the port IN/OUT or table action handlers
- */
-/**
- * Action handler packet insert to output port
- *
- * This function can be called by any input/output port or table action handler
- * to send a packet out through one of the pipeline output ports. This packet is
- * generated by the action handler, i.e. this packet is not part of the burst of
- * packets read from one of the pipeline input ports and currently processed by
- * the pipeline (this packet is not an element of the pkts array input parameter
- * of the action handler).
- *
- * @param p
- * Handle to pipeline instance
- * @param port_id
- * Output port ID (returned by previous invocation of pipeline output port
- * create) to send the packet specified by pkt
- * @param pkt
- * New packet generated by the action handler
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_port_out_packet_insert(struct rte_pipeline *p,
- uint32_t port_id,
- struct rte_mbuf *pkt);
-
-#define rte_pipeline_ah_port_out_packet_insert \
- rte_pipeline_port_out_packet_insert
-
-/**
- * Action handler packet hijack
- *
- * This function can be called by any input/output port or table action handler
- * to hijack selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The hijacked
- * packets are removed from any further pipeline processing, with the action
- * handler now having the full ownership for these packets.
- *
- * The action handler can further send the hijacked packets out through any
- * pipeline output port by calling the rte_pipeline_ah_port_out_packet_insert()
- * function. The action handler can also drop these packets by calling the
- * rte_pktmbuf_free() function, although a better alternative is provided by
- * the action handler using the rte_pipeline_ah_packet_drop() function.
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be hijacked by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is hijacked.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_hijack(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-/**
- * Action handler packet drop
- *
- * This function is called by the pipeline action handlers (port in/out, table)
- * to drop the packets selected using packet mask.
- *
- * This function can be called by any input/output port or table action handler
- * to drop selected packets from the burst of packets read from one of the
- * pipeline input ports and currently processed by the pipeline. The dropped
- * packets are removed from any further pipeline processing and the packet
- * buffers are eventually freed to their buffer pool.
- *
- * This function updates the drop statistics counters correctly, therefore the
- * recommended approach for dropping packets by the action handlers is to call
- * this function as opposed to the action handler hijacking the packets first
- * and then dropping them invisibly to the pipeline (by using the
- * rte_pktmbuf_free() function).
- *
- * @param p
- * Handle to pipeline instance
- * @param pkts_mask
- * 64-bit bitmask specifying which of the packets handed over for processing
- * to the action handler is to be dropped by the action handler. When
- * pkts_mask bit n is set, then element n of the pkts array (input argument to
- * the action handler) is dropped.
- * @return
- * 0 on success, error code otherwise
- */
-int rte_pipeline_ah_packet_drop(struct rte_pipeline *p,
- uint64_t pkts_mask);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/pipeline/rte_port_in_action.c b/lib/pipeline/rte_port_in_action.c
deleted file mode 100644
index 2378e64de9aa48b2829c4725fbe092e0a8930df9..0000000000000000000000000000000000000000
--- a/lib/pipeline/rte_port_in_action.c
+++ /dev/null
@@ -1,539 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_in_action.h"
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-static int
-fltr_cfg_check(struct rte_port_in_action_fltr_config *cfg)
-{
- if (cfg == NULL)
- return -1;
-
- return 0;
-}
-
-struct fltr_data {
- uint32_t port_id;
-};
-
-static void
-fltr_init(struct fltr_data *data,
- struct rte_port_in_action_fltr_config *cfg)
-{
- data->port_id = cfg->port_id;
-}
-
-static int
-fltr_apply(struct fltr_data *data,
- struct rte_port_in_action_fltr_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- data->port_id = p->port_id;
-
- return 0;
-}
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_port_in_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct lb_data {
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-static void
-lb_init(struct lb_data *data,
- struct rte_port_in_action_lb_config *cfg)
-{
- memcpy(data->port_id, cfg->port_id, sizeof(cfg->port_id));
-}
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_port_in_action_lb_params *p)
-{
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- memcpy(data->port_id, p->port_id, sizeof(p->port_id));
-
- return 0;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- case RTE_PORT_IN_ACTION_LB:
- return 1;
- default:
- return 0;
- }
-}
-
-#define RTE_PORT_IN_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_port_in_action_fltr_config fltr;
- struct rte_port_in_action_lb_config lb;
-};
-
-static size_t
-action_cfg_size(enum rte_port_in_action_type action)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct rte_port_in_action_fltr_config);
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct rte_port_in_action_lb_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_port_in_action_type type)
-{
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return &ap_config->fltr;
-
- case RTE_PORT_IN_ACTION_LB:
- return &ap_config->lb;
-
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_port_in_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_PORT_IN_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_port_in_action_type action,
- struct ap_config *ap_config __rte_unused)
-{
- switch (action) {
- case RTE_PORT_IN_ACTION_FLTR:
- return sizeof(struct fltr_data);
-
- case RTE_PORT_IN_ACTION_LB:
- return sizeof(struct lb_data);
-
- default:
- return 0;
- }
-}
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_PORT_IN_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_port_in_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_port_in_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_create, 18.05)
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id)
-{
- struct rte_port_in_action_profile *ap;
-
- /* Memory allocation */
- ap = rte_zmalloc_socket(NULL,
- sizeof(struct rte_port_in_action_profile),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (ap == NULL)
- return NULL;
-
- return ap;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_action_register, 18.05)
-int
-rte_port_in_action_profile_action_register(struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- status = fltr_cfg_check(action_config);
- break;
-
- case RTE_PORT_IN_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_freeze, 18.05)
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_profile_free, 18.05)
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-struct rte_port_in_action {
- struct ap_config cfg;
- struct ap_data data;
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static __rte_always_inline void *
-action_data_get(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- size_t offset = action->data.offset[type];
-
- return &action->memory[offset];
-}
-
-static void
-action_data_init(struct rte_port_in_action *action,
- enum rte_port_in_action_type type)
-{
- void *data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- fltr_init(data, &action->cfg.fltr);
- return;
-
- case RTE_PORT_IN_ACTION_LB:
- lb_init(data, &action->cfg.lb);
- return;
-
- default:
- return;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_create, 18.05)
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_port_in_action *action;
- size_t size;
- uint32_t i;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- size = sizeof(struct rte_port_in_action) + profile->data.total_size;
- size = RTE_CACHE_LINE_ROUNDUP(size);
-
- action = rte_zmalloc_socket(NULL,
- size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- for (i = 0; i < RTE_PORT_IN_ACTION_MAX; i++)
- if (action->cfg.action_mask & (1LLU << i))
- action_data_init(action,
- (enum rte_port_in_action_type)i);
-
- return action;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_apply, 18.05)
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(action, type);
-
- switch (type) {
- case RTE_PORT_IN_ACTION_FLTR:
- return fltr_apply(action_data,
- action_params);
-
- case RTE_PORT_IN_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-ah_filter_on_match(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or == 0) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_filter_on_mismatch(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_fltr_config *cfg = &action->cfg.fltr;
- uint64_t *key_mask = (uint64_t *) cfg->key_mask;
- uint64_t *key = (uint64_t *) cfg->key;
- uint32_t key_offset = cfg->key_offset;
- struct fltr_data *data = action_data_get(action,
- RTE_PORT_IN_ACTION_FLTR);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- key_offset);
-
- uint64_t xor0 = (pkt_key[0] & key_mask[0]) ^ key[0];
- uint64_t xor1 = (pkt_key[1] & key_mask[1]) ^ key[1];
- uint64_t or = xor0 | xor1;
-
- if (or) {
- rte_pipeline_ah_packet_hijack(p, 1LLU << i);
- rte_pipeline_port_out_packet_insert(p,
- data->port_id, pkt);
- }
- }
-
- return 0;
-}
-
-static int
-ah_lb(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint32_t n_pkts,
- void *arg)
-{
- struct rte_port_in_action *action = arg;
- struct rte_port_in_action_lb_config *cfg = &action->cfg.lb;
- struct lb_data *data = action_data_get(action, RTE_PORT_IN_ACTION_LB);
- uint64_t pkt_mask = RTE_LEN2MASK(n_pkts, uint64_t);
- uint32_t i;
-
- rte_pipeline_ah_packet_hijack(p, pkt_mask);
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(pkt,
- cfg->key_offset);
-
- uint64_t digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- uint64_t pos = digest & (RTE_PORT_IN_ACTION_LB_TABLE_SIZE - 1);
- uint32_t port_id = data->port_id[pos];
-
- rte_pipeline_port_out_packet_insert(p, port_id, pkt);
- }
-
- return 0;
-}
-
-static rte_pipeline_port_in_action_handler
-ah_selector(struct rte_port_in_action *action)
-{
- if (action->cfg.action_mask == 0)
- return NULL;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_FLTR)
- return (action->cfg.fltr.filter_on_match) ?
- ah_filter_on_match : ah_filter_on_mismatch;
-
- if (action->cfg.action_mask == 1LLU << RTE_PORT_IN_ACTION_LB)
- return ah_lb;
-
- return NULL;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_params_get, 18.05)
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params)
-{
- rte_pipeline_port_in_action_handler f_action;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action = ah_selector(action);
-
- /* Fill in params */
- params->f_action = f_action;
- params->arg_ah = (f_action) ? action : NULL;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_in_action_free, 18.05)
-int
-rte_port_in_action_free(struct rte_port_in_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_port_in_action.h b/lib/pipeline/rte_port_in_action.h
deleted file mode 100644
index 9d17bae98871de314de7e6279e3d6799d45315c6..0000000000000000000000000000000000000000
--- a/lib/pipeline/rte_port_in_action.h
+++ /dev/null
@@ -1,311 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IN_ACTION_H__
-#define __INCLUDE_RTE_PORT_IN_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Input Port Actions
- *
- * This API provides a common set of actions for pipeline input ports to speed
- * up application development.
- *
- * Each pipeline input port can be assigned an action handler to be executed
- * on every input packet during the pipeline execution. The pipeline library
- * allows the user to define his own input port actions by providing customized
- * input port action handler. While the user can still follow this process, this
- * API is intended to provide a quicker development alternative for a set of
- * predefined actions.
- *
- * The typical steps to use this API are:
- * - Define an input port action profile. This is a configuration template that
- * can potentially be shared by multiple input ports from the same or
- * different pipelines, with different input ports from the same pipeline
- * able to use different action profiles. For every input port using a given
- * action profile, the profile defines the set of actions and the action
- * configuration to be executed by the input port. API functions:
- * rte_port_in_action_profile_create(),
- * rte_port_in_action_profile_action_register(),
- * rte_port_in_action_profile_freeze().
- *
- * - Instantiate the input port action profile to create input port action
- * objects. Each pipeline input port has its own action object.
- * API functions: rte_port_in_action_create().
- *
- * - Use the input port action object to generate the input port action handler
- * invoked by the pipeline. API functions:
- * rte_port_in_action_params_get().
- *
- * - Use the input port action object to generate the internal data structures
- * used by the input port action handler based on given action parameters.
- * API functions: rte_port_in_action_apply().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Input port actions. */
-enum rte_port_in_action_type {
- /** Filter selected input packets. */
- RTE_PORT_IN_ACTION_FLTR = 0,
-
- /** Load balance. */
- RTE_PORT_IN_ACTION_LB,
-};
-
-/**
- * RTE_PORT_IN_ACTION_FLTR
- */
-/** Filter key size (number of bytes) */
-#define RTE_PORT_IN_ACTION_FLTR_KEY_SIZE 16
-
-/** Filter action configuration (per action profile). */
-struct rte_port_in_action_fltr_config {
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask. */
- uint8_t key_mask[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** Key value. */
- uint8_t key[RTE_PORT_IN_ACTION_FLTR_KEY_SIZE];
-
- /** When non-zero, all the input packets that match the *key* (with the
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- * When zero, all the input packets that do NOT match the *key* (with
- * *key_mask* applied) are sent to the pipeline output port *port_id*.
- */
- int filter_on_match;
-
- /** Pipeline output port ID to send the filtered input packets to.
- * Can be updated later.
- *
- * @see struct rte_port_in_action_fltr_params
- */
- uint32_t port_id;
-};
-
-/** Filter action parameters (per action). */
-struct rte_port_in_action_fltr_params {
- /** Pipeline output port ID to send the filtered input packets to. */
- uint32_t port_id;
-};
-
-/**
- * RTE_PORT_IN_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_PORT_IN_ACTION_LB_TABLE_SIZE 16
-
-/** Load balance action configuration (per action profile). */
-struct rte_port_in_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask(*key_size* bytes are valid). */
- uint8_t key_mask[RTE_PORT_IN_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table. Can be updated later.
- *
- * @see struct rte_port_in_action_lb_params
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/** Load balance action parameters (per action). */
-struct rte_port_in_action_lb_params {
- /** Table defining the weight of each pipeline output port. The weights
- * are set in 1/RTE_PORT_IN_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_PORT_IN_ACTION_LB_TABLE_SIZE to a given output port
- * (0 <= N <= RTE_PORT_IN_ACTION_LB_TABLE_SIZE), the output port needs
- * to show up exactly N times in this table.
- */
- uint32_t port_id[RTE_PORT_IN_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * Input port action profile.
- */
-struct rte_port_in_action_profile;
-
-/**
- * Input port action profile create.
- *
- * @param[in] socket_id
- * CPU socket ID for the internal data structures memory allocation.
- * @return
- * Input port action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_port_in_action_profile *
-rte_port_in_action_profile_create(uint32_t socket_id);
-
-/**
- * Input port action profile free.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid).
- * If profile is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_free(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action profile action register.
- *
- * @param[in] profile
- * Input port action profile handle (needs to be valid and not in frozen
- * state).
- * @param[in] type
- * Specific input port action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_port_in_action_*type*_config is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_profile_action_register(
- struct rte_port_in_action_profile *profile,
- enum rte_port_in_action_type type,
- void *action_config);
-
-/**
- * Input port action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * input port action objects.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and not in frozen
- * state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_port_in_action_create()
- */
-__rte_experimental
-int
-rte_port_in_action_profile_freeze(struct rte_port_in_action_profile *profile);
-
-/**
- * Input port action.
- */
-struct rte_port_in_action;
-
-/**
- * Input port action create.
- *
- * Instantiates the given input port action profile to create an input port
- * action object.
- *
- * @param[in] profile
- * Input port profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new input
- * port action object should be allocated.
- * @return
- * Handle to input port action object on success, NULL on error.
- */
-__rte_experimental
-struct rte_port_in_action *
-rte_port_in_action_create(struct rte_port_in_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Input port action free.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * If action is NULL, no operation is performed.
- * @return
- * Always zero.
- */
-__rte_experimental
-int
-rte_port_in_action_free(struct rte_port_in_action *action);
-
-/**
- * Input port params get.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[inout] params
- * Pipeline input port parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_params_get(struct rte_port_in_action *action,
- struct rte_pipeline_port_in_params *params);
-
-/**
- * Input port action apply.
- *
- * @param[in] action
- * Handle to input port action object (needs to be valid).
- * @param[in] type
- * Specific input port action previously registered for the input port action
- * profile of the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_port_in_action_*type*_params is defined, it needs to point to
- * a valid instance of this structure, otherwise it needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_port_in_action_apply(struct rte_port_in_action *action,
- enum rte_port_in_action_type type,
- void *action_params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_PORT_IN_ACTION_H__ */
diff --git a/lib/pipeline/rte_table_action.c b/lib/pipeline/rte_table_action.c
deleted file mode 100644
index c990d7eb5646e0b669d8c7f42bcfd9424359791f..0000000000000000000000000000000000000000
--- a/lib/pipeline/rte_table_action.c
+++ /dev/null
@@ -1,3483 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-#include <stdlib.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_byteorder.h>
-#include <rte_cycles.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_udp.h>
-#include <rte_vxlan.h>
-#include <rte_cryptodev.h>
-
-#include "rte_table_action.h"
-
-#define rte_htons rte_cpu_to_be_16
-#define rte_htonl rte_cpu_to_be_32
-
-#define rte_ntohs rte_be_to_cpu_16
-#define rte_ntohl rte_be_to_cpu_32
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-#define fwd_data rte_pipeline_table_entry
-
-static int
-fwd_apply(struct fwd_data *data,
- struct rte_table_action_fwd_params *p)
-{
- data->action = p->action;
-
- if (p->action == RTE_PIPELINE_ACTION_PORT)
- data->port_id = p->id;
-
- if (p->action == RTE_PIPELINE_ACTION_TABLE)
- data->table_id = p->id;
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-static int
-lb_cfg_check(struct rte_table_action_lb_config *cfg)
-{
- if ((cfg == NULL) ||
- (cfg->key_size < RTE_TABLE_ACTION_LB_KEY_SIZE_MIN) ||
- (cfg->key_size > RTE_TABLE_ACTION_LB_KEY_SIZE_MAX) ||
- (!rte_is_power_of_2(cfg->key_size)) ||
- (cfg->f_hash == NULL))
- return -1;
-
- return 0;
-}
-
-struct __rte_packed_begin lb_data {
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-} __rte_packed_end;
-
-static int
-lb_apply(struct lb_data *data,
- struct rte_table_action_lb_params *p)
-{
- memcpy(data->out, p->out, sizeof(data->out));
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_lb(struct rte_mbuf *mbuf,
- struct lb_data *data,
- struct rte_table_action_lb_config *cfg)
-{
- uint8_t *pkt_key = RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->key_offset);
- uint32_t *out = RTE_MBUF_METADATA_UINT32_PTR(mbuf, cfg->out_offset);
- uint64_t digest, pos;
- uint32_t out_val;
-
- digest = cfg->f_hash(pkt_key,
- cfg->key_mask,
- cfg->key_size,
- cfg->seed);
- pos = digest & (RTE_TABLE_ACTION_LB_TABLE_SIZE - 1);
- out_val = data->out[pos];
-
- *out = out_val;
-}
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-static int
-mtr_cfg_check(struct rte_table_action_mtr_config *mtr)
-{
- if ((mtr->alg == RTE_TABLE_ACTION_METER_SRTCM) ||
- ((mtr->n_tc != 1) && (mtr->n_tc != 4)) ||
- (mtr->n_bytes_enabled != 0))
- return -ENOTSUP;
- return 0;
-}
-
-struct mtr_trtcm_data {
- struct rte_meter_trtcm trtcm;
- uint64_t stats[RTE_COLORS];
-};
-
-#define MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data) \
- (((data)->stats[RTE_COLOR_GREEN] & 0xF8LLU) >> 3)
-
-static void
-mtr_trtcm_data_meter_profile_id_set(struct mtr_trtcm_data *data,
- uint32_t profile_id)
-{
- data->stats[RTE_COLOR_GREEN] &= ~0xF8LLU;
- data->stats[RTE_COLOR_GREEN] |= (profile_id % 32) << 3;
-}
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color)\
- (((data)->stats[(color)] & 4LLU) >> 2)
-
-#define MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color)\
- ((enum rte_color)((data)->stats[(color)] & 3LLU))
-
-static void
-mtr_trtcm_data_policer_action_set(struct mtr_trtcm_data *data,
- enum rte_color color,
- enum rte_table_action_policer action)
-{
- if (action == RTE_TABLE_ACTION_POLICER_DROP) {
- data->stats[color] |= 4LLU;
- } else {
- data->stats[color] &= ~7LLU;
- data->stats[color] |= color & 3LLU;
- }
-}
-
-static uint64_t
-mtr_trtcm_data_stats_get(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- return data->stats[color] >> 8;
-}
-
-static void
-mtr_trtcm_data_stats_reset(struct mtr_trtcm_data *data,
- enum rte_color color)
-{
- data->stats[color] &= 0xFFLU;
-}
-
-#define MTR_TRTCM_DATA_STATS_INC(data, color) \
- ((data)->stats[(color)] += (1LLU << 8))
-
-static size_t
-mtr_data_size(struct rte_table_action_mtr_config *mtr)
-{
- return mtr->n_tc * sizeof(struct mtr_trtcm_data);
-}
-
-struct dscp_table_entry_data {
- enum rte_color color;
- uint16_t tc;
- uint16_t tc_queue;
-};
-
-struct dscp_table_data {
- struct dscp_table_entry_data entry[64];
-};
-
-struct meter_profile_data {
- struct rte_meter_trtcm_profile profile;
- uint32_t profile_id;
- int valid;
-};
-
-static struct meter_profile_data *
-meter_profile_data_find(struct meter_profile_data *mp,
- uint32_t mp_size,
- uint32_t profile_id)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (mp_data->valid && (mp_data->profile_id == profile_id))
- return mp_data;
- }
-
- return NULL;
-}
-
-static struct meter_profile_data *
-meter_profile_data_find_unused(struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- for (i = 0; i < mp_size; i++) {
- struct meter_profile_data *mp_data = &mp[i];
-
- if (!mp_data->valid)
- return mp_data;
- }
-
- return NULL;
-}
-
-static int
-mtr_apply_check(struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
-
- if (p->tc_mask > RTE_LEN2MASK(cfg->n_tc, uint32_t))
- return -EINVAL;
-
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-mtr_apply(struct mtr_trtcm_data *data,
- struct rte_table_action_mtr_params *p,
- struct rte_table_action_mtr_config *cfg,
- struct meter_profile_data *mp,
- uint32_t mp_size)
-{
- uint32_t i;
- int status;
-
- /* Check input arguments */
- status = mtr_apply_check(p, cfg, mp, mp_size);
- if (status)
- return status;
-
- /* Apply */
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_tc_params *p_tc = &p->mtr[i];
- struct mtr_trtcm_data *data_tc = &data[i];
- struct meter_profile_data *mp_data;
-
- if ((p->tc_mask & (1LLU << i)) == 0)
- continue;
-
- /* Find profile */
- mp_data = meter_profile_data_find(mp,
- mp_size,
- p_tc->meter_profile_id);
- if (!mp_data)
- return -EINVAL;
-
- memset(data_tc, 0, sizeof(*data_tc));
-
- /* Meter object */
- status = rte_meter_trtcm_config(&data_tc->trtcm,
- &mp_data->profile);
- if (status)
- return status;
-
- /* Meter profile */
- mtr_trtcm_data_meter_profile_id_set(data_tc,
- mp_data - mp);
-
- /* Policer actions */
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_GREEN,
- p_tc->policer[RTE_COLOR_GREEN]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_YELLOW,
- p_tc->policer[RTE_COLOR_YELLOW]);
-
- mtr_trtcm_data_policer_action_set(data_tc,
- RTE_COLOR_RED,
- p_tc->policer[RTE_COLOR_RED]);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_mtr(struct rte_mbuf *mbuf,
- struct mtr_trtcm_data *data,
- struct dscp_table_data *dscp_table,
- struct meter_profile_data *mp,
- uint64_t time,
- uint32_t dscp,
- uint16_t total_length)
-{
- uint64_t drop_mask;
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- enum rte_color color_in, color_meter, color_policer;
- uint32_t tc, mp_id;
-
- tc = dscp_entry->tc;
- color_in = dscp_entry->color;
- data += tc;
- mp_id = MTR_TRTCM_DATA_METER_PROFILE_ID_GET(data);
-
- /* Meter */
- color_meter = rte_meter_trtcm_color_aware_check(
- &data->trtcm,
- &mp[mp_id].profile,
- time,
- total_length,
- color_in);
-
- /* Stats */
- MTR_TRTCM_DATA_STATS_INC(data, color_meter);
-
- /* Police */
- drop_mask = MTR_TRTCM_DATA_POLICER_ACTION_DROP_GET(data, color_meter);
- color_policer =
- MTR_TRTCM_DATA_POLICER_ACTION_COLOR_GET(data, color_meter);
- rte_mbuf_sched_color_set(mbuf, (uint8_t)color_policer);
-
- return drop_mask;
-}
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-static int
-tm_cfg_check(struct rte_table_action_tm_config *tm)
-{
- if ((tm->n_subports_per_port == 0) ||
- (rte_is_power_of_2(tm->n_subports_per_port) == 0) ||
- (tm->n_subports_per_port > UINT16_MAX) ||
- (tm->n_pipes_per_subport == 0) ||
- (rte_is_power_of_2(tm->n_pipes_per_subport) == 0))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin tm_data {
- uint32_t queue_id;
- uint32_t reserved;
-} __rte_packed_end;
-
-static int
-tm_apply_check(struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- if ((p->subport_id >= cfg->n_subports_per_port) ||
- (p->pipe_id >= cfg->n_pipes_per_subport))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-tm_apply(struct tm_data *data,
- struct rte_table_action_tm_params *p,
- struct rte_table_action_tm_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = tm_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- data->queue_id = p->subport_id <<
- (rte_ctz32(cfg->n_pipes_per_subport) + 4) |
- p->pipe_id << 4;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tm(struct rte_mbuf *mbuf,
- struct tm_data *data,
- struct dscp_table_data *dscp_table,
- uint32_t dscp)
-{
- struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp];
- uint32_t queue_id = data->queue_id |
- dscp_entry->tc_queue;
- rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc,
- (uint8_t)dscp_entry->color);
-}
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-static int
-encap_valid(enum rte_table_action_encap_type encap)
-{
- switch (encap) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 1;
- default:
- return 0;
- }
-}
-
-static int
-encap_cfg_check(struct rte_table_action_encap_config *encap)
-{
- if ((encap->encap_mask == 0) ||
- (rte_popcount64(encap->encap_mask) != 1))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct encap_ether_data {
- struct rte_ether_hdr ether;
-};
-
-#define VLAN(pcp, dei, vid) \
- ((uint16_t)((((uint64_t)(pcp)) & 0x7LLU) << 13) | \
- ((((uint64_t)(dei)) & 0x1LLU) << 12) | \
- (((uint64_t)(vid)) & 0xFFFLLU)) \
-
-struct encap_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
-};
-
-struct encap_qinq_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
-};
-
-#define ETHER_TYPE_MPLS_UNICAST 0x8847
-
-#define ETHER_TYPE_MPLS_MULTICAST 0x8848
-
-#define MPLS(label, tc, s, ttl) \
- ((uint32_t)(((((uint64_t)(label)) & 0xFFFFFLLU) << 12) |\
- ((((uint64_t)(tc)) & 0x7LLU) << 9) | \
- ((((uint64_t)(s)) & 0x1LLU) << 8) | \
- (((uint64_t)(ttl)) & 0xFFLLU)))
-
-struct __rte_aligned(2) __rte_packed_begin encap_mpls_data {
- struct rte_ether_hdr ether;
- uint32_t mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
- uint32_t mpls_count;
-} __rte_packed_end;
-
-#define PPP_PROTOCOL_IP 0x0021
-
-struct pppoe_ppp_hdr {
- uint16_t ver_type_code;
- uint16_t session_id;
- uint16_t length;
- uint16_t protocol;
-};
-
-struct encap_pppoe_data {
- struct rte_ether_hdr ether;
- struct pppoe_ppp_hdr pppoe_ppp;
-};
-
-#define IP_PROTO_UDP 17
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_data {
- struct rte_ether_hdr ether;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv4_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv4_hdr ipv4;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_data {
- struct rte_ether_hdr ether;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_vxlan_ipv6_vlan_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr vlan;
- struct rte_ipv6_hdr ipv6;
- struct rte_udp_hdr udp;
- struct rte_vxlan_hdr vxlan;
-} __rte_packed_end;
-
-struct __rte_aligned(2) __rte_packed_begin encap_qinq_pppoe_data {
- struct rte_ether_hdr ether;
- struct rte_vlan_hdr svlan;
- struct rte_vlan_hdr cvlan;
- struct pppoe_ppp_hdr pppoe_ppp;
-} __rte_packed_end;
-
-static size_t
-encap_data_size(struct rte_table_action_encap_config *encap)
-{
- switch (encap->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- return sizeof(struct encap_ether_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- return sizeof(struct encap_vlan_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- return sizeof(struct encap_qinq_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- return sizeof(struct encap_mpls_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- return sizeof(struct encap_pppoe_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- if (encap->vxlan.ip_version)
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv4_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv4_data);
- else
- if (encap->vxlan.vlan)
- return sizeof(struct encap_vxlan_ipv6_vlan_data);
- else
- return sizeof(struct encap_vxlan_ipv6_data);
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return sizeof(struct encap_qinq_pppoe_data);
-
- default:
- return 0;
- }
-}
-
-static int
-encap_apply_check(struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((encap_valid(p->type) == 0) ||
- ((cfg->encap_mask & (1LLU << p->type)) == 0))
- return -EINVAL;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- if ((p->mpls.mpls_count == 0) ||
- (p->mpls.mpls_count > RTE_TABLE_ACTION_MPLS_LABELS_MAX))
- return -EINVAL;
-
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return 0;
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return 0;
-
- default:
- return -EINVAL;
- }
-}
-
-static int
-encap_ether_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_ether_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->ether.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->ether.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_vlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_vlan_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vlan.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vlan.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vlan.vlan.pcp,
- p->vlan.vlan.dei,
- p->vlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_common_config *common_cfg)
-{
- struct encap_qinq_data *d = data;
- uint16_t ethertype = (common_cfg->ip_version) ?
- RTE_ETHER_TYPE_IPV4 :
- RTE_ETHER_TYPE_IPV6;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_QINQ);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(ethertype);
-
- return 0;
-}
-
-static int
-encap_qinq_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_qinq_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->qinq.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->qinq.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* SVLAN */
- d->svlan.vlan_tci = rte_htons(VLAN(p->qinq.svlan.pcp,
- p->qinq.svlan.dei,
- p->qinq.svlan.vid));
- d->svlan.eth_proto = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* CVLAN */
- d->cvlan.vlan_tci = rte_htons(VLAN(p->qinq.cvlan.pcp,
- p->qinq.cvlan.dei,
- p->qinq.cvlan.vid));
- d->cvlan.eth_proto = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->qinq_pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_mpls_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_mpls_data *d = data;
- uint16_t ethertype = (p->mpls.unicast) ?
- ETHER_TYPE_MPLS_UNICAST :
- ETHER_TYPE_MPLS_MULTICAST;
- uint32_t i;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->mpls.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->mpls.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(ethertype);
-
- /* MPLS */
- for (i = 0; i < p->mpls.mpls_count - 1; i++)
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 0,
- p->mpls.mpls[i].ttl));
-
- d->mpls[i] = rte_htonl(MPLS(p->mpls.mpls[i].label,
- p->mpls.mpls[i].tc,
- 1,
- p->mpls.mpls[i].ttl));
-
- d->mpls_count = p->mpls.mpls_count;
- return 0;
-}
-
-static int
-encap_pppoe_apply(void *data,
- struct rte_table_action_encap_params *p)
-{
- struct encap_pppoe_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->pppoe.ether.da, &d->ether.dst_addr);
- rte_ether_addr_copy(&p->pppoe.ether.sa, &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_PPPOE_SESSION);
-
- /* PPPoE and PPP*/
- d->pppoe_ppp.ver_type_code = rte_htons(0x1100);
- d->pppoe_ppp.session_id = rte_htons(p->pppoe.pppoe.session_id);
- d->pppoe_ppp.length = 0; /* not pre-computed */
- d->pppoe_ppp.protocol = rte_htons(PPP_PROTOCOL_IP);
-
- return 0;
-}
-
-static int
-encap_vxlan_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg)
-{
- if ((p->vxlan.vxlan.vni > 0xFFFFFF) ||
- (cfg->vxlan.ip_version && (p->vxlan.ipv4.dscp > 0x3F)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.flow_label > 0xFFFFF)) ||
- (!cfg->vxlan.ip_version && (p->vxlan.ipv6.dscp > 0x3F)) ||
- (cfg->vxlan.vlan && (p->vxlan.vlan.vid > 0xFFF)))
- return -1;
-
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv4_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv4_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV4);
-
- /* IPv4*/
- d->ipv4.version_ihl = 0x45;
- d->ipv4.type_of_service = p->vxlan.ipv4.dscp << 2;
- d->ipv4.total_length = 0; /* not pre-computed */
- d->ipv4.packet_id = 0;
- d->ipv4.fragment_offset = 0;
- d->ipv4.time_to_live = p->vxlan.ipv4.ttl;
- d->ipv4.next_proto_id = IP_PROTO_UDP;
- d->ipv4.hdr_checksum = 0;
- d->ipv4.src_addr = rte_htonl(p->vxlan.ipv4.sa);
- d->ipv4.dst_addr = rte_htonl(p->vxlan.ipv4.da);
-
- d->ipv4.hdr_checksum = rte_ipv4_cksum(&d->ipv4);
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
- else
- if (cfg->vxlan.vlan) {
- struct encap_vxlan_ipv6_vlan_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_VLAN);
-
- /* VLAN */
- d->vlan.vlan_tci = rte_htons(VLAN(p->vxlan.vlan.pcp,
- p->vxlan.vlan.dei,
- p->vxlan.vlan.vid));
- d->vlan.eth_proto = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- } else {
- struct encap_vxlan_ipv6_data *d = data;
-
- /* Ethernet */
- rte_ether_addr_copy(&p->vxlan.ether.da,
- &d->ether.dst_addr);
- rte_ether_addr_copy(&p->vxlan.ether.sa,
- &d->ether.src_addr);
- d->ether.ether_type = rte_htons(RTE_ETHER_TYPE_IPV6);
-
- /* IPv6*/
- d->ipv6.vtc_flow = rte_htonl((6 << 28) |
- (p->vxlan.ipv6.dscp << 22) |
- p->vxlan.ipv6.flow_label);
- d->ipv6.payload_len = 0; /* not pre-computed */
- d->ipv6.proto = IP_PROTO_UDP;
- d->ipv6.hop_limits = p->vxlan.ipv6.hop_limit;
- d->ipv6.src_addr = p->vxlan.ipv6.sa;
- d->ipv6.dst_addr = p->vxlan.ipv6.da;
-
- /* UDP */
- d->udp.src_port = rte_htons(p->vxlan.udp.sp);
- d->udp.dst_port = rte_htons(p->vxlan.udp.dp);
- d->udp.dgram_len = 0; /* not pre-computed */
- d->udp.dgram_cksum = 0;
-
- /* VXLAN */
- d->vxlan.vx_flags = rte_htonl(0x08000000);
- d->vxlan.vx_vni = rte_htonl(p->vxlan.vxlan.vni << 8);
-
- return 0;
- }
-}
-
-static int
-encap_apply(void *data,
- struct rte_table_action_encap_params *p,
- struct rte_table_action_encap_config *cfg,
- struct rte_table_action_common_config *common_cfg)
-{
- int status;
-
- /* Check input arguments */
- status = encap_apply_check(p, cfg);
- if (status)
- return status;
-
- switch (p->type) {
- case RTE_TABLE_ACTION_ENCAP_ETHER:
- return encap_ether_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_VLAN:
- return encap_vlan_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ:
- return encap_qinq_apply(data, p, common_cfg);
-
- case RTE_TABLE_ACTION_ENCAP_MPLS:
- return encap_mpls_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_PPPOE:
- return encap_pppoe_apply(data, p);
-
- case RTE_TABLE_ACTION_ENCAP_VXLAN:
- return encap_vxlan_apply(data, p, cfg);
-
- case RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- return encap_qinq_pppoe_apply(data, p);
-
- default:
- return -EINVAL;
- }
-}
-
-static __rte_always_inline uint16_t
-encap_vxlan_ipv4_checksum_update(uint16_t cksum0,
- uint16_t total_length)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Add total length (one's complement logic) */
- cksum1 += total_length;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void *
-encap(void *dst, const void *src, size_t n)
-{
- dst = ((uint8_t *) dst) - n;
- return rte_memcpy(dst, src, n);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv4_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv4_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv4_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv4_total_length, ipv4_hdr_cksum, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv4_total_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr) +
- sizeof(struct rte_ipv4_hdr));
- ipv4_hdr_cksum = encap_vxlan_ipv4_checksum_update(vxlan_tbl->ipv4.hdr_checksum,
- rte_htons(ipv4_total_length));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv4.total_length = rte_htons(ipv4_total_length);
- vxlan_pkt->ipv4.hdr_checksum = ipv4_hdr_cksum;
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap_vxlan_ipv6_vlan(struct rte_mbuf *mbuf,
- struct encap_vxlan_ipv6_vlan_data *vxlan_tbl,
- struct rte_table_action_encap_config *cfg)
-{
- uint32_t ether_offset = cfg->vxlan.data_offset;
- void *ether = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ether_offset);
- struct encap_vxlan_ipv6_vlan_data *vxlan_pkt;
- uint16_t ether_length, ipv6_payload_length, udp_length;
-
- ether_length = (uint16_t)mbuf->pkt_len;
- ipv6_payload_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
- udp_length = ether_length +
- (sizeof(struct rte_vxlan_hdr) +
- sizeof(struct rte_udp_hdr));
-
- vxlan_pkt = encap(ether, vxlan_tbl, sizeof(*vxlan_tbl));
- vxlan_pkt->ipv6.payload_len = rte_htons(ipv6_payload_length);
- vxlan_pkt->udp.dgram_len = rte_htons(udp_length);
-
- mbuf->data_off = ether_offset - (sizeof(struct rte_mbuf) + sizeof(*vxlan_pkt));
- mbuf->pkt_len = mbuf->data_len = ether_length + sizeof(*vxlan_pkt);
-}
-
-static __rte_always_inline void
-pkt_work_encap(struct rte_mbuf *mbuf,
- void *data,
- struct rte_table_action_encap_config *cfg,
- void *ip,
- uint16_t total_length,
- uint32_t ip_offset)
-{
- switch (cfg->encap_mask) {
- case 1LLU << RTE_TABLE_ACTION_ENCAP_ETHER:
- encap(ip, data, sizeof(struct encap_ether_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_ether_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_ether_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VLAN:
- encap(ip, data, sizeof(struct encap_vlan_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_vlan_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_vlan_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ:
- encap(ip, data, sizeof(struct encap_qinq_data));
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_data);
- break;
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_MPLS:
- {
- struct encap_mpls_data *mpls = data;
- size_t size = sizeof(struct rte_ether_hdr) +
- mpls->mpls_count * 4;
-
- encap(ip, data, size);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) + size);
- mbuf->pkt_len = mbuf->data_len = total_length + size;
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_PPPOE:
- {
- struct encap_pppoe_data *pppoe =
- encap(ip, data, sizeof(struct encap_pppoe_data));
- pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE:
- {
- struct encap_qinq_pppoe_data *qinq_pppoe =
- encap(ip, data, sizeof(struct encap_qinq_pppoe_data));
- qinq_pppoe->pppoe_ppp.length = rte_htons(total_length + 2);
- mbuf->data_off = ip_offset - (sizeof(struct rte_mbuf) +
- sizeof(struct encap_qinq_pppoe_data));
- mbuf->pkt_len = mbuf->data_len = total_length +
- sizeof(struct encap_qinq_pppoe_data);
- break;
- }
-
- case 1LLU << RTE_TABLE_ACTION_ENCAP_VXLAN:
- {
- if (cfg->vxlan.ip_version)
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv4_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv4(mbuf, data, cfg);
- else
- if (cfg->vxlan.vlan)
- pkt_work_encap_vxlan_ipv6_vlan(mbuf, data, cfg);
- else
- pkt_work_encap_vxlan_ipv6(mbuf, data, cfg);
- }
-
- default:
- break;
- }
-}
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-static int
-nat_cfg_check(struct rte_table_action_nat_config *nat)
-{
- if ((nat->proto != 0x06) &&
- (nat->proto != 0x11))
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin nat_ipv4_data {
- uint32_t addr;
- uint16_t port;
-} __rte_packed_end;
-
-struct __rte_packed_begin nat_ipv6_data {
- struct rte_ipv6_addr addr;
- uint16_t port;
-} __rte_packed_end;
-
-static size_t
-nat_data_size(struct rte_table_action_nat_config *nat __rte_unused,
- struct rte_table_action_common_config *common)
-{
- int ip_version = common->ip_version;
-
- return (ip_version) ?
- sizeof(struct nat_ipv4_data) :
- sizeof(struct nat_ipv6_data);
-}
-
-static int
-nat_apply_check(struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- if ((p->ip_version && (cfg->ip_version == 0)) ||
- ((p->ip_version == 0) && cfg->ip_version))
- return -EINVAL;
-
- return 0;
-}
-
-static int
-nat_apply(void *data,
- struct rte_table_action_nat_params *p,
- struct rte_table_action_common_config *cfg)
-{
- int status;
-
- /* Check input arguments */
- status = nat_apply_check(p, cfg);
- if (status)
- return status;
-
- /* Apply */
- if (p->ip_version) {
- struct nat_ipv4_data *d = data;
-
- d->addr = rte_htonl(p->addr.ipv4);
- d->port = rte_htons(p->port);
- } else {
- struct nat_ipv6_data *d = data;
-
- d->addr = p->addr.ipv6;
- d->port = rte_htons(p->port);
- }
-
- return 0;
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv4_tcp_udp_checksum_update(uint16_t cksum0,
- uint32_t ip0,
- uint32_t ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= (ip0 >> 16) + (ip0 & 0xFFFF) + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += (ip1 >> 16) + (ip1 & 0xFFFF) + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline uint16_t
-nat_ipv6_tcp_udp_checksum_update(uint16_t cksum0,
- uint16_t *ip0,
- uint16_t *ip1,
- uint16_t port0,
- uint16_t port1)
-{
- int32_t cksum1;
-
- cksum1 = cksum0;
- cksum1 = ~cksum1 & 0xFFFF;
-
- /* Subtract ip0 and port 0 (one's complement logic) */
- cksum1 -= ip0[0] + ip0[1] + ip0[2] + ip0[3] +
- ip0[4] + ip0[5] + ip0[6] + ip0[7] + port0;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- /* Add ip1 and port1 (one's complement logic) */
- cksum1 += ip1[0] + ip1[1] + ip1[2] + ip1[3] +
- ip1[4] + ip1[5] + ip1[6] + ip1[7] + port1;
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
- cksum1 = (cksum1 & 0xFFFF) + (cksum1 >> 16);
-
- return (uint16_t)(~cksum1);
-}
-
-static __rte_always_inline void
-pkt_ipv4_work_nat(struct rte_ipv4_hdr *ip,
- struct nat_ipv4_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->src_addr,
- data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->src_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->src_addr,
- data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->src_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t ip_cksum, tcp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- tcp_cksum = nat_ipv4_tcp_udp_checksum_update(tcp->cksum,
- ip->dst_addr,
- data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t ip_cksum, udp_cksum;
-
- ip_cksum = nat_ipv4_checksum_update(ip->hdr_checksum,
- ip->dst_addr,
- data->addr);
-
- udp_cksum = nat_ipv4_tcp_udp_checksum_update(udp->dgram_cksum,
- ip->dst_addr,
- data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- ip->hdr_checksum = ip_cksum;
- udp->dst_port = data->port;
- if (udp->dgram_cksum)
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-static __rte_always_inline void
-pkt_ipv6_work_nat(struct rte_ipv6_hdr *ip,
- struct nat_ipv6_data *data,
- struct rte_table_action_nat_config *cfg)
-{
- if (cfg->source_nat) {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- tcp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- tcp->src_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->src_addr,
- (uint16_t *)&data->addr,
- udp->src_port,
- data->port);
-
- ip->src_addr = data->addr;
- udp->src_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- } else {
- if (cfg->proto == 0x6) {
- struct rte_tcp_hdr *tcp = (struct rte_tcp_hdr *) &ip[1];
- uint16_t tcp_cksum;
-
- tcp_cksum = nat_ipv6_tcp_udp_checksum_update(tcp->cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- tcp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- tcp->dst_port = data->port;
- tcp->cksum = tcp_cksum;
- } else {
- struct rte_udp_hdr *udp = (struct rte_udp_hdr *) &ip[1];
- uint16_t udp_cksum;
-
- udp_cksum = nat_ipv6_tcp_udp_checksum_update(udp->dgram_cksum,
- (uint16_t *)&ip->dst_addr,
- (uint16_t *)&data->addr,
- udp->dst_port,
- data->port);
-
- ip->dst_addr = data->addr;
- udp->dst_port = data->port;
- udp->dgram_cksum = udp_cksum;
- }
- }
-}
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-static int
-ttl_cfg_check(struct rte_table_action_ttl_config *ttl)
-{
- if (ttl->drop == 0)
- return -ENOTSUP;
-
- return 0;
-}
-
-struct __rte_packed_begin ttl_data {
- uint32_t n_packets;
-} __rte_packed_end;
-
-#define TTL_INIT(data, decrement) \
- ((data)->n_packets = (decrement) ? 1 : 0)
-
-#define TTL_DEC_GET(data) \
- ((uint8_t)((data)->n_packets & 1))
-
-#define TTL_STATS_RESET(data) \
- ((data)->n_packets = ((data)->n_packets & 1))
-
-#define TTL_STATS_READ(data) \
- ((data)->n_packets >> 1)
-
-#define TTL_STATS_ADD(data, value) \
- ((data)->n_packets = \
- (((((data)->n_packets >> 1) + (value)) << 1) | \
- ((data)->n_packets & 1)))
-
-static int
-ttl_apply(void *data,
- struct rte_table_action_ttl_params *p)
-{
- struct ttl_data *d = data;
-
- TTL_INIT(d, p->decrement);
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv4_work_ttl(struct rte_ipv4_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint16_t cksum = ip->hdr_checksum;
- uint8_t ttl = ip->time_to_live;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- cksum += ttl_diff;
- ttl -= ttl_diff;
-
- ip->hdr_checksum = cksum;
- ip->time_to_live = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-static __rte_always_inline uint64_t
-pkt_ipv6_work_ttl(struct rte_ipv6_hdr *ip,
- struct ttl_data *data)
-{
- uint32_t drop;
- uint8_t ttl = ip->hop_limits;
- uint8_t ttl_diff = TTL_DEC_GET(data);
-
- ttl -= ttl_diff;
-
- ip->hop_limits = ttl;
-
- drop = (ttl == 0) ? 1 : 0;
- TTL_STATS_ADD(data, drop);
-
- return drop;
-}
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-static int
-stats_cfg_check(struct rte_table_action_stats_config *stats)
-{
- if ((stats->n_packets_enabled == 0) && (stats->n_bytes_enabled == 0))
- return -EINVAL;
-
- return 0;
-}
-
-struct __rte_packed_begin stats_data {
- uint64_t n_packets;
- uint64_t n_bytes;
-} __rte_packed_end;
-
-static int
-stats_apply(struct stats_data *data,
- struct rte_table_action_stats_params *p)
-{
- data->n_packets = p->n_packets;
- data->n_bytes = p->n_bytes;
-
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_stats(struct stats_data *data,
- uint16_t total_length)
-{
- data->n_packets++;
- data->n_bytes += total_length;
-}
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-struct __rte_packed_begin time_data {
- uint64_t time;
-} __rte_packed_end;
-
-static int
-time_apply(struct time_data *data,
- struct rte_table_action_time_params *p)
-{
- data->time = p->time;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_time(struct time_data *data,
- uint64_t time)
-{
- data->time = time;
-}
-
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-
-#define CRYPTO_OP_MASK_CIPHER 0x1
-#define CRYPTO_OP_MASK_AUTH 0x2
-#define CRYPTO_OP_MASK_AEAD 0x4
-
-struct crypto_op_sym_iv_aad {
- struct rte_crypto_op op;
- struct rte_crypto_sym_op sym_op;
- union {
- struct {
- uint8_t cipher_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t auth_iv[
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- } cipher_auth;
-
- struct {
- uint8_t iv[RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX];
- uint8_t aad[RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX];
- } aead_iv_aad;
-
- } iv_aad;
-};
-
-struct __rte_packed_begin sym_crypto_data {
-
- union {
- struct {
-
- /** Length of cipher iv. */
- uint16_t cipher_iv_len;
-
- /** Offset from start of IP header to the cipher iv. */
- uint16_t cipher_iv_data_offset;
-
- /** Length of cipher iv to be updated in the mbuf. */
- uint16_t cipher_iv_update_len;
-
- /** Offset from start of IP header to the auth iv. */
- uint16_t auth_iv_data_offset;
-
- /** Length of auth iv in the mbuf. */
- uint16_t auth_iv_len;
-
- /** Length of auth iv to be updated in the mbuf. */
- uint16_t auth_iv_update_len;
-
- } cipher_auth;
- struct {
-
- /** Length of iv. */
- uint16_t iv_len;
-
- /** Offset from start of IP header to the aead iv. */
- uint16_t iv_data_offset;
-
- /** Length of iv to be updated in the mbuf. */
- uint16_t iv_update_len;
-
- /** Length of aad */
- uint16_t aad_len;
-
- /** Offset from start of IP header to the aad. */
- uint16_t aad_data_offset;
-
- /** Length of aad to updated in the mbuf. */
- uint16_t aad_update_len;
-
- } aead;
- };
-
- /** Offset from start of IP header to the data. */
- uint16_t data_offset;
-
- /** Digest length. */
- uint16_t digest_len;
-
- /** block size */
- uint16_t block_size;
-
- /** Mask of crypto operation */
- uint16_t op_mask;
-
- /** Session pointer. */
- struct rte_cryptodev_sym_session *session;
-
- /** Direction of crypto, encrypt or decrypt */
- uint16_t direction;
-
- /** Private data size to store cipher iv / aad. */
- uint8_t iv_aad_data[32];
-
-} __rte_packed_end;
-
-static int
-sym_crypto_cfg_check(struct rte_table_action_sym_crypto_config *cfg)
-{
- if (!rte_cryptodev_is_valid_dev(cfg->cryptodev_id))
- return -EINVAL;
- if (cfg->mp_create == NULL || cfg->mp_init == NULL)
- return -EINVAL;
-
- return 0;
-}
-
-static int
-get_block_size(const struct rte_crypto_sym_xform *xform, uint8_t cdev_id)
-{
- struct rte_cryptodev_info dev_info;
- const struct rte_cryptodev_capabilities *cap;
- uint32_t i;
-
- rte_cryptodev_info_get(cdev_id, &dev_info);
-
- for (i = 0; dev_info.capabilities[i].op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
- i++) {
- cap = &dev_info.capabilities[i];
-
- if (cap->sym.xform_type != xform->type)
- continue;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) &&
- (cap->sym.cipher.algo == xform->cipher.algo))
- return cap->sym.cipher.block_size;
-
- if ((xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) &&
- (cap->sym.aead.algo == xform->aead.algo))
- return cap->sym.aead.block_size;
-
- if (xform->type == RTE_CRYPTO_SYM_XFORM_NOT_SPECIFIED)
- break;
- }
-
- return -1;
-}
-
-static int
-sym_crypto_apply(struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- struct rte_table_action_sym_crypto_params *p)
-{
- const struct rte_crypto_cipher_xform *cipher_xform = NULL;
- const struct rte_crypto_auth_xform *auth_xform = NULL;
- const struct rte_crypto_aead_xform *aead_xform = NULL;
- struct rte_crypto_sym_xform *xform = p->xform;
- struct rte_cryptodev_sym_session *session;
- int ret;
-
- memset(data, 0, sizeof(*data));
-
- while (xform) {
- if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER) {
- cipher_xform = &xform->cipher;
-
- if (cipher_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- if (cipher_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_CIPHER;
-
- data->cipher_auth.cipher_iv_len =
- cipher_xform->iv.length;
- data->cipher_auth.cipher_iv_data_offset = (uint16_t)
- p->cipher_auth.cipher_iv_update.offset;
- data->cipher_auth.cipher_iv_update_len = (uint16_t)
- p->cipher_auth.cipher_iv_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.cipher_iv.val,
- p->cipher_auth.cipher_iv.length);
-
- data->direction = cipher_xform->op;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH) {
- auth_xform = &xform->auth;
- if (auth_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX)
- return -ENOMEM;
- data->op_mask |= CRYPTO_OP_MASK_AUTH;
-
- data->cipher_auth.auth_iv_len = auth_xform->iv.length;
- data->cipher_auth.auth_iv_data_offset = (uint16_t)
- p->cipher_auth.auth_iv_update.offset;
- data->cipher_auth.auth_iv_update_len = (uint16_t)
- p->cipher_auth.auth_iv_update.length;
- data->digest_len = auth_xform->digest_length;
-
- data->direction = (auth_xform->op ==
- RTE_CRYPTO_AUTH_OP_GENERATE) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
-
- } else if (xform->type == RTE_CRYPTO_SYM_XFORM_AEAD) {
- aead_xform = &xform->aead;
-
- if ((aead_xform->iv.length >
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX) || (
- aead_xform->aad_length >
- RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX))
- return -EINVAL;
- if (aead_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET)
- return -EINVAL;
-
- ret = get_block_size(xform, cfg->cryptodev_id);
- if (ret < 0)
- return -1;
- data->block_size = (uint16_t)ret;
- data->op_mask |= CRYPTO_OP_MASK_AEAD;
-
- data->digest_len = aead_xform->digest_length;
- data->aead.iv_len = aead_xform->iv.length;
- data->aead.aad_len = aead_xform->aad_length;
-
- data->aead.iv_data_offset = (uint16_t)
- p->aead.iv_update.offset;
- data->aead.iv_update_len = (uint16_t)
- p->aead.iv_update.length;
- data->aead.aad_data_offset = (uint16_t)
- p->aead.aad_update.offset;
- data->aead.aad_update_len = (uint16_t)
- p->aead.aad_update.length;
-
- rte_memcpy(data->iv_aad_data,
- p->aead.iv.val,
- p->aead.iv.length);
-
- rte_memcpy(data->iv_aad_data + p->aead.iv.length,
- p->aead.aad.val,
- p->aead.aad.length);
-
- data->direction = (aead_xform->op ==
- RTE_CRYPTO_AEAD_OP_ENCRYPT) ?
- RTE_CRYPTO_CIPHER_OP_ENCRYPT :
- RTE_CRYPTO_CIPHER_OP_DECRYPT;
- } else
- return -EINVAL;
-
- xform = xform->next;
- }
-
- if (auth_xform && auth_xform->iv.length) {
- if (cipher_xform) {
- if (auth_xform->iv.offset !=
- RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET +
- cipher_xform->iv.length)
- return -EINVAL;
-
- rte_memcpy(data->iv_aad_data + cipher_xform->iv.length,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- } else {
- rte_memcpy(data->iv_aad_data,
- p->cipher_auth.auth_iv.val,
- p->cipher_auth.auth_iv.length);
- }
- }
-
- session = rte_cryptodev_sym_session_create(cfg->cryptodev_id,
- p->xform, cfg->mp_create);
- if (!session)
- return -ENOMEM;
-
- data->data_offset = (uint16_t)p->data_offset;
- data->session = session;
-
- return 0;
-}
-
-static __rte_always_inline uint64_t
-pkt_work_sym_crypto(struct rte_mbuf *mbuf, struct sym_crypto_data *data,
- struct rte_table_action_sym_crypto_config *cfg,
- uint16_t ip_offset)
-{
- struct crypto_op_sym_iv_aad *crypto_op = (struct crypto_op_sym_iv_aad *)
- RTE_MBUF_METADATA_UINT8_PTR(mbuf, cfg->op_offset);
- struct rte_crypto_op *op = &crypto_op->op;
- struct rte_crypto_sym_op *sym = op->sym;
- uint32_t pkt_offset = sizeof(*mbuf) + mbuf->data_off;
- uint32_t payload_len = pkt_offset + mbuf->data_len - data->data_offset;
-
- op->type = RTE_CRYPTO_OP_TYPE_SYMMETRIC;
- op->sess_type = RTE_CRYPTO_OP_WITH_SESSION;
- op->phys_addr = rte_mbuf_iova_get(mbuf) + cfg->op_offset - sizeof(*mbuf);
- op->status = RTE_CRYPTO_OP_STATUS_NOT_PROCESSED;
- sym->m_src = mbuf;
- sym->m_dst = NULL;
- sym->session = data->session;
-
- /** pad the packet */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT) {
- uint32_t append_len = RTE_ALIGN_CEIL(payload_len,
- data->block_size) - payload_len;
-
- if (unlikely(rte_pktmbuf_append(mbuf, append_len +
- data->digest_len) == NULL))
- return 1;
-
- payload_len += append_len;
- } else
- payload_len -= data->digest_len;
-
- if (data->op_mask & CRYPTO_OP_MASK_CIPHER) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.cipher_iv;
-
- sym->cipher.data.length = payload_len;
- sym->cipher.data.offset = data->data_offset - pkt_offset;
-
- if (data->cipher_auth.cipher_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.cipher_iv_data_offset
- + ip_offset);
-
- /** For encryption, update the pkt iv field, otherwise
- * update the iv_aad_field
- */
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_update_len);
- else
- rte_memcpy(data->iv_aad_data, pkt_iv,
- data->cipher_auth.cipher_iv_update_len);
- }
-
- /** write iv */
- rte_memcpy(iv, data->iv_aad_data,
- data->cipher_auth.cipher_iv_len);
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AUTH) {
- /** authentication always start from IP header. */
- sym->auth.data.offset = ip_offset - pkt_offset;
- sym->auth.data.length = mbuf->data_len - sym->auth.data.offset -
- data->digest_len;
- sym->auth.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->auth.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
-
- if (data->cipher_auth.auth_iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->cipher_auth.auth_iv_data_offset
- + ip_offset);
- uint8_t *data_iv = data->iv_aad_data +
- data->cipher_auth.cipher_iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->cipher_auth.auth_iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->cipher_auth.auth_iv_update_len);
- }
-
- if (data->cipher_auth.auth_iv_len) {
- /** prepare cipher op */
- uint8_t *iv = crypto_op->iv_aad.cipher_auth.auth_iv;
-
- rte_memcpy(iv, data->iv_aad_data +
- data->cipher_auth.cipher_iv_len,
- data->cipher_auth.auth_iv_len);
- }
- }
-
- if (data->op_mask & CRYPTO_OP_MASK_AEAD) {
- uint8_t *iv = crypto_op->iv_aad.aead_iv_aad.iv;
- uint8_t *aad = crypto_op->iv_aad.aead_iv_aad.aad;
-
- sym->aead.aad.data = aad;
- sym->aead.aad.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- aad - rte_pktmbuf_mtod(mbuf, uint8_t *));
- sym->aead.digest.data = rte_pktmbuf_mtod_offset(mbuf,
- uint8_t *, rte_pktmbuf_pkt_len(mbuf) -
- data->digest_len);
- sym->aead.digest.phys_addr = rte_pktmbuf_iova_offset(mbuf,
- rte_pktmbuf_pkt_len(mbuf) - data->digest_len);
- sym->aead.data.offset = data->data_offset - pkt_offset;
- sym->aead.data.length = payload_len;
-
- if (data->aead.iv_update_len) {
- uint8_t *pkt_iv = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.iv_data_offset + ip_offset);
- uint8_t *data_iv = data->iv_aad_data;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_iv, data_iv,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_iv, pkt_iv,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(iv, data->iv_aad_data, data->aead.iv_len);
-
- if (data->aead.aad_update_len) {
- uint8_t *pkt_aad = RTE_MBUF_METADATA_UINT8_PTR(mbuf,
- data->aead.aad_data_offset + ip_offset);
- uint8_t *data_aad = data->iv_aad_data +
- data->aead.iv_len;
-
- if (data->direction == RTE_CRYPTO_CIPHER_OP_ENCRYPT)
- rte_memcpy(pkt_aad, data_aad,
- data->aead.iv_update_len);
- else
- rte_memcpy(data_aad, pkt_aad,
- data->aead.iv_update_len);
- }
-
- rte_memcpy(aad, data->iv_aad_data + data->aead.iv_len,
- data->aead.aad_len);
- }
-
- return 0;
-}
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-struct __rte_packed_begin tag_data {
- uint32_t tag;
-} __rte_packed_end;
-
-static int
-tag_apply(struct tag_data *data,
- struct rte_table_action_tag_params *p)
-{
- data->tag = p->tag;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_tag(struct rte_mbuf *mbuf,
- struct tag_data *data)
-{
- mbuf->hash.fdir.hi = data->tag;
- mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-static __rte_always_inline void
-pkt4_work_tag(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct tag_data *data0,
- struct tag_data *data1,
- struct tag_data *data2,
- struct tag_data *data3)
-{
- mbuf0->hash.fdir.hi = data0->tag;
- mbuf1->hash.fdir.hi = data1->tag;
- mbuf2->hash.fdir.hi = data2->tag;
- mbuf3->hash.fdir.hi = data3->tag;
-
- mbuf0->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf1->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf2->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
- mbuf3->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
-}
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-struct __rte_packed_begin decap_data {
- uint16_t n;
-} __rte_packed_end;
-
-static int
-decap_apply(struct decap_data *data,
- struct rte_table_action_decap_params *p)
-{
- data->n = p->n;
- return 0;
-}
-
-static __rte_always_inline void
-pkt_work_decap(struct rte_mbuf *mbuf,
- struct decap_data *data)
-{
- uint16_t data_off = mbuf->data_off;
- uint16_t data_len = mbuf->data_len;
- uint32_t pkt_len = mbuf->pkt_len;
- uint16_t n = data->n;
-
- mbuf->data_off = data_off + n;
- mbuf->data_len = data_len - n;
- mbuf->pkt_len = pkt_len - n;
-}
-
-static __rte_always_inline void
-pkt4_work_decap(struct rte_mbuf *mbuf0,
- struct rte_mbuf *mbuf1,
- struct rte_mbuf *mbuf2,
- struct rte_mbuf *mbuf3,
- struct decap_data *data0,
- struct decap_data *data1,
- struct decap_data *data2,
- struct decap_data *data3)
-{
- uint16_t data_off0 = mbuf0->data_off;
- uint16_t data_len0 = mbuf0->data_len;
- uint32_t pkt_len0 = mbuf0->pkt_len;
-
- uint16_t data_off1 = mbuf1->data_off;
- uint16_t data_len1 = mbuf1->data_len;
- uint32_t pkt_len1 = mbuf1->pkt_len;
-
- uint16_t data_off2 = mbuf2->data_off;
- uint16_t data_len2 = mbuf2->data_len;
- uint32_t pkt_len2 = mbuf2->pkt_len;
-
- uint16_t data_off3 = mbuf3->data_off;
- uint16_t data_len3 = mbuf3->data_len;
- uint32_t pkt_len3 = mbuf3->pkt_len;
-
- uint16_t n0 = data0->n;
- uint16_t n1 = data1->n;
- uint16_t n2 = data2->n;
- uint16_t n3 = data3->n;
-
- mbuf0->data_off = data_off0 + n0;
- mbuf0->data_len = data_len0 - n0;
- mbuf0->pkt_len = pkt_len0 - n0;
-
- mbuf1->data_off = data_off1 + n1;
- mbuf1->data_len = data_len1 - n1;
- mbuf1->pkt_len = pkt_len1 - n1;
-
- mbuf2->data_off = data_off2 + n2;
- mbuf2->data_len = data_len2 - n2;
- mbuf2->pkt_len = pkt_len2 - n2;
-
- mbuf3->data_off = data_off3 + n3;
- mbuf3->data_len = data_len3 - n3;
- mbuf3->pkt_len = pkt_len3 - n3;
-}
-
-/**
- * Action profile
- */
-static int
-action_valid(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- case RTE_TABLE_ACTION_LB:
- case RTE_TABLE_ACTION_MTR:
- case RTE_TABLE_ACTION_TM:
- case RTE_TABLE_ACTION_ENCAP:
- case RTE_TABLE_ACTION_NAT:
- case RTE_TABLE_ACTION_TTL:
- case RTE_TABLE_ACTION_STATS:
- case RTE_TABLE_ACTION_TIME:
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- case RTE_TABLE_ACTION_TAG:
- case RTE_TABLE_ACTION_DECAP:
- return 1;
- default:
- return 0;
- }
-}
-
-
-#define RTE_TABLE_ACTION_MAX 64
-
-struct ap_config {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-static size_t
-action_cfg_size(enum rte_table_action_type action)
-{
- switch (action) {
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct rte_table_action_lb_config);
- case RTE_TABLE_ACTION_MTR:
- return sizeof(struct rte_table_action_mtr_config);
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct rte_table_action_tm_config);
- case RTE_TABLE_ACTION_ENCAP:
- return sizeof(struct rte_table_action_encap_config);
- case RTE_TABLE_ACTION_NAT:
- return sizeof(struct rte_table_action_nat_config);
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct rte_table_action_ttl_config);
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct rte_table_action_stats_config);
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sizeof(struct rte_table_action_sym_crypto_config);
- default:
- return 0;
- }
-}
-
-static void*
-action_cfg_get(struct ap_config *ap_config,
- enum rte_table_action_type type)
-{
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- return &ap_config->lb;
-
- case RTE_TABLE_ACTION_MTR:
- return &ap_config->mtr;
-
- case RTE_TABLE_ACTION_TM:
- return &ap_config->tm;
-
- case RTE_TABLE_ACTION_ENCAP:
- return &ap_config->encap;
-
- case RTE_TABLE_ACTION_NAT:
- return &ap_config->nat;
-
- case RTE_TABLE_ACTION_TTL:
- return &ap_config->ttl;
-
- case RTE_TABLE_ACTION_STATS:
- return &ap_config->stats;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return &ap_config->sym_crypto;
- default:
- return NULL;
- }
-}
-
-static void
-action_cfg_set(struct ap_config *ap_config,
- enum rte_table_action_type type,
- void *action_cfg)
-{
- void *dst = action_cfg_get(ap_config, type);
-
- if (dst)
- memcpy(dst, action_cfg, action_cfg_size(type));
-
- ap_config->action_mask |= 1LLU << type;
-}
-
-struct ap_data {
- size_t offset[RTE_TABLE_ACTION_MAX];
- size_t total_size;
-};
-
-static size_t
-action_data_size(enum rte_table_action_type action,
- struct ap_config *ap_config)
-{
- switch (action) {
- case RTE_TABLE_ACTION_FWD:
- return sizeof(struct fwd_data);
-
- case RTE_TABLE_ACTION_LB:
- return sizeof(struct lb_data);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_data_size(&ap_config->mtr);
-
- case RTE_TABLE_ACTION_TM:
- return sizeof(struct tm_data);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_data_size(&ap_config->encap);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_data_size(&ap_config->nat,
- &ap_config->common);
-
- case RTE_TABLE_ACTION_TTL:
- return sizeof(struct ttl_data);
-
- case RTE_TABLE_ACTION_STATS:
- return sizeof(struct stats_data);
-
- case RTE_TABLE_ACTION_TIME:
- return sizeof(struct time_data);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return (sizeof(struct sym_crypto_data));
-
- case RTE_TABLE_ACTION_TAG:
- return sizeof(struct tag_data);
-
- case RTE_TABLE_ACTION_DECAP:
- return sizeof(struct decap_data);
-
- default:
- return 0;
- }
-}
-
-
-static void
-action_data_offset_set(struct ap_data *ap_data,
- struct ap_config *ap_config)
-{
- uint64_t action_mask = ap_config->action_mask;
- size_t offset;
- uint32_t action;
-
- memset(ap_data->offset, 0, sizeof(ap_data->offset));
-
- offset = 0;
- for (action = 0; action < RTE_TABLE_ACTION_MAX; action++)
- if (action_mask & (1LLU << action)) {
- ap_data->offset[action] = offset;
- offset += action_data_size((enum rte_table_action_type)action,
- ap_config);
- }
-
- ap_data->total_size = offset;
-}
-
-struct rte_table_action_profile {
- struct ap_config cfg;
- struct ap_data data;
- int frozen;
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_create, 18.05)
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common)
-{
- struct rte_table_action_profile *ap;
-
- /* Check input arguments */
- if (common == NULL)
- return NULL;
-
- /* Memory allocation */
- ap = calloc(1, sizeof(struct rte_table_action_profile));
- if (ap == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&ap->cfg.common, common, sizeof(*common));
-
- return ap;
-}
-
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_action_register, 18.05)
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config)
-{
- int status;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- profile->frozen ||
- (action_valid(type) == 0) ||
- (profile->cfg.action_mask & (1LLU << type)) ||
- ((action_cfg_size(type) == 0) && action_config) ||
- (action_cfg_size(type) && (action_config == NULL)))
- return -EINVAL;
-
- switch (type) {
- case RTE_TABLE_ACTION_LB:
- status = lb_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_MTR:
- status = mtr_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TM:
- status = tm_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_ENCAP:
- status = encap_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_NAT:
- status = nat_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_TTL:
- status = ttl_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_STATS:
- status = stats_cfg_check(action_config);
- break;
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- status = sym_crypto_cfg_check(action_config);
- break;
-
- default:
- status = 0;
- break;
- }
-
- if (status)
- return status;
-
- /* Action enable */
- action_cfg_set(&profile->cfg, type, action_config);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_freeze, 18.05)
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile)
-{
- if (profile->frozen)
- return -EBUSY;
-
- profile->cfg.action_mask |= 1LLU << RTE_TABLE_ACTION_FWD;
- action_data_offset_set(&profile->data, &profile->cfg);
- profile->frozen = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_profile_free, 18.05)
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile)
-{
- if (profile == NULL)
- return 0;
-
- free(profile);
- return 0;
-}
-
-/**
- * Action
- */
-#define METER_PROFILES_MAX 32
-
-struct rte_table_action {
- struct ap_config cfg;
- struct ap_data data;
- struct dscp_table_data dscp_table;
- struct meter_profile_data mp[METER_PROFILES_MAX];
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_create, 18.05)
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id)
-{
- struct rte_table_action *action;
-
- /* Check input arguments */
- if ((profile == NULL) ||
- (profile->frozen == 0))
- return NULL;
-
- /* Memory allocation */
- action = rte_zmalloc_socket(NULL,
- sizeof(struct rte_table_action),
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (action == NULL)
- return NULL;
-
- /* Initialization */
- memcpy(&action->cfg, &profile->cfg, sizeof(profile->cfg));
- memcpy(&action->data, &profile->data, sizeof(profile->data));
-
- return action;
-}
-
-static __rte_always_inline void *
-action_data_get(void *data,
- struct rte_table_action *action,
- enum rte_table_action_type type)
-{
- size_t offset = action->data.offset[type];
- uint8_t *data_bytes = data;
-
- return &data_bytes[offset];
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_apply, 18.05)
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params)
-{
- void *action_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (data == NULL) ||
- (action_valid(type) == 0) ||
- ((action->cfg.action_mask & (1LLU << type)) == 0) ||
- (action_params == NULL))
- return -EINVAL;
-
- /* Data update */
- action_data = action_data_get(data, action, type);
-
- switch (type) {
- case RTE_TABLE_ACTION_FWD:
- return fwd_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_LB:
- return lb_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_MTR:
- return mtr_apply(action_data,
- action_params,
- &action->cfg.mtr,
- action->mp,
- RTE_DIM(action->mp));
-
- case RTE_TABLE_ACTION_TM:
- return tm_apply(action_data,
- action_params,
- &action->cfg.tm);
-
- case RTE_TABLE_ACTION_ENCAP:
- return encap_apply(action_data,
- action_params,
- &action->cfg.encap,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_NAT:
- return nat_apply(action_data,
- action_params,
- &action->cfg.common);
-
- case RTE_TABLE_ACTION_TTL:
- return ttl_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_STATS:
- return stats_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_TIME:
- return time_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_SYM_CRYPTO:
- return sym_crypto_apply(action_data,
- &action->cfg.sym_crypto,
- action_params);
-
- case RTE_TABLE_ACTION_TAG:
- return tag_apply(action_data,
- action_params);
-
- case RTE_TABLE_ACTION_DECAP:
- return decap_apply(action_data,
- action_params);
-
- default:
- return -EINVAL;
- }
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_dscp_table_update, 18.05)
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table)
-{
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TM))) == 0) ||
- (dscp_mask == 0) ||
- (table == NULL))
- return -EINVAL;
-
- for (i = 0; i < RTE_DIM(table->entry); i++) {
- struct dscp_table_entry_data *data =
- &action->dscp_table.entry[i];
- struct rte_table_action_dscp_table_entry *entry =
- &table->entry[i];
-
- if ((dscp_mask & (1LLU << i)) == 0)
- continue;
-
- data->color = entry->color;
- data->tc = entry->tc_id;
- data->tc_queue = entry->tc_queue_id;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_add, 18.05)
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile)
-{
- struct meter_profile_data *mp_data;
- uint32_t status;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (profile == NULL))
- return -EINVAL;
-
- if (profile->alg != RTE_TABLE_ACTION_METER_TRTCM)
- return -ENOTSUP;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (mp_data)
- return -EEXIST;
-
- mp_data = meter_profile_data_find_unused(action->mp,
- RTE_DIM(action->mp));
- if (!mp_data)
- return -ENOSPC;
-
- /* Install new profile */
- status = rte_meter_trtcm_profile_config(&mp_data->profile,
- &profile->trtcm);
- if (status)
- return status;
-
- mp_data->profile_id = meter_profile_id;
- mp_data->valid = 1;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_profile_delete, 18.05)
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id)
-{
- struct meter_profile_data *mp_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0))
- return -EINVAL;
-
- mp_data = meter_profile_data_find(action->mp,
- RTE_DIM(action->mp),
- meter_profile_id);
- if (!mp_data)
- return 0;
-
- /* Uninstall profile */
- mp_data->valid = 0;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_meter_read, 18.05)
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear)
-{
- struct mtr_trtcm_data *mtr_data;
- uint32_t i;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) == 0) ||
- (data == NULL) ||
- (tc_mask > RTE_LEN2MASK(action->cfg.mtr.n_tc, uint32_t)))
- return -EINVAL;
-
- mtr_data = action_data_get(data, action, RTE_TABLE_ACTION_MTR);
-
- /* Read */
- if (stats) {
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct rte_table_action_mtr_counters_tc *dst =
- &stats->stats[i];
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- dst->n_packets[RTE_COLOR_GREEN] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_GREEN);
-
- dst->n_packets[RTE_COLOR_YELLOW] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_YELLOW);
-
- dst->n_packets[RTE_COLOR_RED] =
- mtr_trtcm_data_stats_get(src, RTE_COLOR_RED);
-
- dst->n_packets_valid = 1;
- dst->n_bytes_valid = 0;
- }
-
- stats->tc_mask = tc_mask;
- }
-
- /* Clear */
- if (clear)
- for (i = 0; i < RTE_TABLE_ACTION_TC_MAX; i++) {
- struct mtr_trtcm_data *src = &mtr_data[i];
-
- if ((tc_mask & (1 << i)) == 0)
- continue;
-
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_GREEN);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_YELLOW);
- mtr_trtcm_data_stats_reset(src, RTE_COLOR_RED);
- }
-
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_ttl_read, 18.05)
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear)
-{
- struct ttl_data *ttl_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TTL)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- ttl_data = action_data_get(data, action, RTE_TABLE_ACTION_TTL);
-
- /* Read */
- if (stats)
- stats->n_packets = TTL_STATS_READ(ttl_data);
-
- /* Clear */
- if (clear)
- TTL_STATS_RESET(ttl_data);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_stats_read, 18.05)
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear)
-{
- struct stats_data *stats_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_STATS)) == 0) ||
- (data == NULL))
- return -EINVAL;
-
- stats_data = action_data_get(data, action,
- RTE_TABLE_ACTION_STATS);
-
- /* Read */
- if (stats) {
- stats->n_packets = stats_data->n_packets;
- stats->n_bytes = stats_data->n_bytes;
- stats->n_packets_valid = 1;
- stats->n_bytes_valid = 1;
- }
-
- /* Clear */
- if (clear) {
- stats_data->n_packets = 0;
- stats_data->n_bytes = 0;
- }
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_time_read, 18.05)
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp)
-{
- struct time_data *time_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_TIME)) == 0) ||
- (data == NULL) ||
- (timestamp == NULL))
- return -EINVAL;
-
- time_data = action_data_get(data, action, RTE_TABLE_ACTION_TIME);
-
- /* Read */
- *timestamp = time_data->time;
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_crypto_sym_session_get, 18.11)
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data)
-{
- struct sym_crypto_data *sym_crypto_data;
-
- /* Check input arguments */
- if ((action == NULL) ||
- ((action->cfg.action_mask &
- (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) == 0) ||
- (data == NULL))
- return NULL;
-
- sym_crypto_data = action_data_get(data, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- return sym_crypto_data->session;
-}
-
-static __rte_always_inline uint64_t
-pkt_work(struct rte_mbuf *mbuf,
- struct rte_pipeline_table_entry *table_entry,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask = 0;
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip = RTE_MBUF_METADATA_UINT32_PTR(mbuf, ip_offset);
-
- uint32_t dscp;
- uint16_t total_length;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr = ip;
-
- dscp = hdr->type_of_service >> 2;
- total_length = rte_ntohs(hdr->total_length);
- } else {
- struct rte_ipv6_hdr *hdr = ip;
-
- dscp = (rte_ntohl(hdr->vtc_flow) & 0x0F600000) >> 18;
- total_length = rte_ntohs(hdr->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf,
- data,
- &cfg->lb);
- }
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask |= pkt_work_mtr(mbuf,
- data,
- &action->dscp_table,
- action->mp,
- time,
- dscp,
- total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf,
- data,
- &action->dscp_table,
- dscp);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt_work_decap(mbuf, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf,
- data,
- &cfg->encap,
- ip,
- total_length,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version)
- pkt_ipv4_work_nat(ip, data, &cfg->nat);
- else
- pkt_ipv6_work_nat(ip, data, &cfg->nat);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version)
- drop_mask |= pkt_ipv4_work_ttl(ip, data);
- else
- drop_mask |= pkt_ipv6_work_ttl(ip, data);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data, total_length);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data =
- action_data_get(table_entry, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data = action_data_get(table_entry, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask |= pkt_work_sym_crypto(mbuf, data, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data = action_data_get(table_entry,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt_work_tag(mbuf, data);
- }
-
- return drop_mask;
-}
-
-static __rte_always_inline uint64_t
-pkt4_work(struct rte_mbuf **mbufs,
- struct rte_pipeline_table_entry **table_entries,
- uint64_t time,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t drop_mask0 = 0;
- uint64_t drop_mask1 = 0;
- uint64_t drop_mask2 = 0;
- uint64_t drop_mask3 = 0;
-
- struct rte_mbuf *mbuf0 = mbufs[0];
- struct rte_mbuf *mbuf1 = mbufs[1];
- struct rte_mbuf *mbuf2 = mbufs[2];
- struct rte_mbuf *mbuf3 = mbufs[3];
-
- struct rte_pipeline_table_entry *table_entry0 = table_entries[0];
- struct rte_pipeline_table_entry *table_entry1 = table_entries[1];
- struct rte_pipeline_table_entry *table_entry2 = table_entries[2];
- struct rte_pipeline_table_entry *table_entry3 = table_entries[3];
-
- uint32_t ip_offset = action->cfg.common.ip_offset;
- void *ip0 = RTE_MBUF_METADATA_UINT32_PTR(mbuf0, ip_offset);
- void *ip1 = RTE_MBUF_METADATA_UINT32_PTR(mbuf1, ip_offset);
- void *ip2 = RTE_MBUF_METADATA_UINT32_PTR(mbuf2, ip_offset);
- void *ip3 = RTE_MBUF_METADATA_UINT32_PTR(mbuf3, ip_offset);
-
- uint32_t dscp0, dscp1, dscp2, dscp3;
- uint16_t total_length0, total_length1, total_length2, total_length3;
-
- if (cfg->common.ip_version) {
- struct rte_ipv4_hdr *hdr0 = ip0;
- struct rte_ipv4_hdr *hdr1 = ip1;
- struct rte_ipv4_hdr *hdr2 = ip2;
- struct rte_ipv4_hdr *hdr3 = ip3;
-
- dscp0 = hdr0->type_of_service >> 2;
- dscp1 = hdr1->type_of_service >> 2;
- dscp2 = hdr2->type_of_service >> 2;
- dscp3 = hdr3->type_of_service >> 2;
-
- total_length0 = rte_ntohs(hdr0->total_length);
- total_length1 = rte_ntohs(hdr1->total_length);
- total_length2 = rte_ntohs(hdr2->total_length);
- total_length3 = rte_ntohs(hdr3->total_length);
- } else {
- struct rte_ipv6_hdr *hdr0 = ip0;
- struct rte_ipv6_hdr *hdr1 = ip1;
- struct rte_ipv6_hdr *hdr2 = ip2;
- struct rte_ipv6_hdr *hdr3 = ip3;
-
- dscp0 = (rte_ntohl(hdr0->vtc_flow) & 0x0F600000) >> 18;
- dscp1 = (rte_ntohl(hdr1->vtc_flow) & 0x0F600000) >> 18;
- dscp2 = (rte_ntohl(hdr2->vtc_flow) & 0x0F600000) >> 18;
- dscp3 = (rte_ntohl(hdr3->vtc_flow) & 0x0F600000) >> 18;
-
- total_length0 = rte_ntohs(hdr0->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length1 = rte_ntohs(hdr1->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length2 = rte_ntohs(hdr2->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- total_length3 = rte_ntohs(hdr3->payload_len) +
- sizeof(struct rte_ipv6_hdr);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_LB);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_LB);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_LB);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_LB);
-
- pkt_work_lb(mbuf0,
- data0,
- &cfg->lb);
-
- pkt_work_lb(mbuf1,
- data1,
- &cfg->lb);
-
- pkt_work_lb(mbuf2,
- data2,
- &cfg->lb);
-
- pkt_work_lb(mbuf3,
- data3,
- &cfg->lb);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_MTR);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_MTR);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_MTR);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_MTR);
-
- drop_mask0 |= pkt_work_mtr(mbuf0,
- data0,
- &action->dscp_table,
- action->mp,
- time,
- dscp0,
- total_length0);
-
- drop_mask1 |= pkt_work_mtr(mbuf1,
- data1,
- &action->dscp_table,
- action->mp,
- time,
- dscp1,
- total_length1);
-
- drop_mask2 |= pkt_work_mtr(mbuf2,
- data2,
- &action->dscp_table,
- action->mp,
- time,
- dscp2,
- total_length2);
-
- drop_mask3 |= pkt_work_mtr(mbuf3,
- data3,
- &action->dscp_table,
- action->mp,
- time,
- dscp3,
- total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TM);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TM);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TM);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TM);
-
- pkt_work_tm(mbuf0,
- data0,
- &action->dscp_table,
- dscp0);
-
- pkt_work_tm(mbuf1,
- data1,
- &action->dscp_table,
- dscp1);
-
- pkt_work_tm(mbuf2,
- data2,
- &action->dscp_table,
- dscp2);
-
- pkt_work_tm(mbuf3,
- data3,
- &action->dscp_table,
- dscp3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_DECAP);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_DECAP);
-
- pkt4_work_decap(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_ENCAP);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_ENCAP);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_ENCAP);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_ENCAP);
-
- pkt_work_encap(mbuf0,
- data0,
- &cfg->encap,
- ip0,
- total_length0,
- ip_offset);
-
- pkt_work_encap(mbuf1,
- data1,
- &cfg->encap,
- ip1,
- total_length1,
- ip_offset);
-
- pkt_work_encap(mbuf2,
- data2,
- &cfg->encap,
- ip2,
- total_length2,
- ip_offset);
-
- pkt_work_encap(mbuf3,
- data3,
- &cfg->encap,
- ip3,
- total_length3,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_NAT);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_NAT);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_NAT);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_NAT);
-
- if (cfg->common.ip_version) {
- pkt_ipv4_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv4_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv4_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv4_work_nat(ip3, data3, &cfg->nat);
- } else {
- pkt_ipv6_work_nat(ip0, data0, &cfg->nat);
- pkt_ipv6_work_nat(ip1, data1, &cfg->nat);
- pkt_ipv6_work_nat(ip2, data2, &cfg->nat);
- pkt_ipv6_work_nat(ip3, data3, &cfg->nat);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TTL);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TTL);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TTL);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TTL);
-
- if (cfg->common.ip_version) {
- drop_mask0 |= pkt_ipv4_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv4_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv4_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv4_work_ttl(ip3, data3);
- } else {
- drop_mask0 |= pkt_ipv6_work_ttl(ip0, data0);
- drop_mask1 |= pkt_ipv6_work_ttl(ip1, data1);
- drop_mask2 |= pkt_ipv6_work_ttl(ip2, data2);
- drop_mask3 |= pkt_ipv6_work_ttl(ip3, data3);
- }
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_STATS);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_STATS);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_STATS);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_STATS);
-
- pkt_work_stats(data0, total_length0);
- pkt_work_stats(data1, total_length1);
- pkt_work_stats(data2, total_length2);
- pkt_work_stats(data3, total_length3);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- void *data0 =
- action_data_get(table_entry0, action, RTE_TABLE_ACTION_TIME);
- void *data1 =
- action_data_get(table_entry1, action, RTE_TABLE_ACTION_TIME);
- void *data2 =
- action_data_get(table_entry2, action, RTE_TABLE_ACTION_TIME);
- void *data3 =
- action_data_get(table_entry3, action, RTE_TABLE_ACTION_TIME);
-
- pkt_work_time(data0, time);
- pkt_work_time(data1, time);
- pkt_work_time(data2, time);
- pkt_work_time(data3, time);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- void *data0 = action_data_get(table_entry0, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data1 = action_data_get(table_entry1, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data2 = action_data_get(table_entry2, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
- void *data3 = action_data_get(table_entry3, action,
- RTE_TABLE_ACTION_SYM_CRYPTO);
-
- drop_mask0 |= pkt_work_sym_crypto(mbuf0, data0, &cfg->sym_crypto,
- ip_offset);
- drop_mask1 |= pkt_work_sym_crypto(mbuf1, data1, &cfg->sym_crypto,
- ip_offset);
- drop_mask2 |= pkt_work_sym_crypto(mbuf2, data2, &cfg->sym_crypto,
- ip_offset);
- drop_mask3 |= pkt_work_sym_crypto(mbuf3, data3, &cfg->sym_crypto,
- ip_offset);
- }
-
- if (cfg->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- void *data0 = action_data_get(table_entry0,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data1 = action_data_get(table_entry1,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data2 = action_data_get(table_entry2,
- action,
- RTE_TABLE_ACTION_TAG);
- void *data3 = action_data_get(table_entry3,
- action,
- RTE_TABLE_ACTION_TAG);
-
- pkt4_work_tag(mbuf0, mbuf1, mbuf2, mbuf3,
- data0, data1, data2, data3);
- }
-
- return drop_mask0 |
- (drop_mask1 << 1) |
- (drop_mask2 << 2) |
- (drop_mask3 << 3);
-}
-
-static __rte_always_inline int
-ah(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- struct rte_table_action *action,
- struct ap_config *cfg)
-{
- uint64_t pkts_drop_mask = 0;
- uint64_t time = 0;
-
- if (cfg->action_mask & ((1LLU << RTE_TABLE_ACTION_MTR) |
- (1LLU << RTE_TABLE_ACTION_TIME)))
- time = rte_rdtsc();
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) {
- uint64_t drop_mask;
-
- drop_mask = pkt4_work(&pkts[i],
- &entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
-
- for ( ; i < n_pkts; i++) {
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[i],
- entries[i],
- time,
- action,
- cfg);
-
- pkts_drop_mask |= drop_mask << i;
- }
- } else
- for ( ; pkts_mask; ) {
- uint32_t pos = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pos;
- uint64_t drop_mask;
-
- drop_mask = pkt_work(pkts[pos],
- entries[pos],
- time,
- action,
- cfg);
-
- pkts_mask &= ~pkt_mask;
- pkts_drop_mask |= drop_mask << pos;
- }
-
- rte_pipeline_ah_packet_drop(p, pkts_drop_mask);
-
- return 0;
-}
-
-static int
-ah_default(struct rte_pipeline *p,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- struct rte_pipeline_table_entry **entries,
- void *arg)
-{
- struct rte_table_action *action = arg;
-
- return ah(p,
- pkts,
- pkts_mask,
- entries,
- action,
- &action->cfg);
-}
-
-static rte_pipeline_table_action_handler_hit
-ah_selector(struct rte_table_action *action)
-{
- if (action->cfg.action_mask == (1LLU << RTE_TABLE_ACTION_FWD))
- return NULL;
-
- return ah_default;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_table_params_get, 18.05)
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params)
-{
- rte_pipeline_table_action_handler_hit f_action_hit;
- uint32_t total_size;
-
- /* Check input arguments */
- if ((action == NULL) ||
- (params == NULL))
- return -EINVAL;
-
- f_action_hit = ah_selector(action);
- total_size = rte_align32pow2(action->data.total_size);
-
- /* Fill in params */
- params->f_action_hit = f_action_hit;
- params->f_action_miss = NULL;
- params->arg_ah = (f_action_hit) ? action : NULL;
- params->action_data_size = total_size -
- sizeof(struct rte_pipeline_table_entry);
-
- return 0;
-}
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_table_action_free, 18.05)
-int
-rte_table_action_free(struct rte_table_action *action)
-{
- if (action == NULL)
- return 0;
-
- rte_free(action);
-
- return 0;
-}
diff --git a/lib/pipeline/rte_table_action.h b/lib/pipeline/rte_table_action.h
deleted file mode 100644
index 47a7bdfc01cc33962ccebb4cb7e2f1c5bdf05c84..0000000000000000000000000000000000000000
--- a/lib/pipeline/rte_table_action.h
+++ /dev/null
@@ -1,1137 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_ACTION_H__
-#define __INCLUDE_RTE_TABLE_ACTION_H__
-
-/**
- * @file
- * RTE Pipeline Table Actions
- *
- * This API provides a common set of actions for pipeline tables to speed up
- * application development.
- *
- * Each match-action rule added to a pipeline table has associated data that
- * stores the action context. This data is input to the table action handler
- * called for every input packet that hits the rule as part of the table lookup
- * during the pipeline execution. The pipeline library allows the user to define
- * his own table actions by providing customized table action handlers (table
- * lookup) and complete freedom of setting the rules and their data (table rule
- * add/delete). While the user can still follow this process, this API is
- * intended to provide a quicker development alternative for a set of predefined
- * actions.
- *
- * The typical steps to use this API are:
- * - Define a table action profile. This is a configuration template that can
- * potentially be shared by multiple tables from the same or different
- * pipelines, with different tables from the same pipeline likely to use
- * different action profiles. For every table using a given action profile,
- * the profile defines the set of actions and the action configuration to be
- * implemented for all the table rules. API functions:
- * rte_table_action_profile_create(),
- * rte_table_action_profile_action_register(),
- * rte_table_action_profile_freeze().
- *
- * - Instantiate the table action profile to create table action objects. Each
- * pipeline table has its own table action object. API functions:
- * rte_table_action_create().
- *
- * - Use the table action object to generate the pipeline table action handlers
- * (invoked by the pipeline table lookup operation). API functions:
- * rte_table_action_table_params_get().
- *
- * - Use the table action object to generate the rule data (for the pipeline
- * table rule add operation) based on given action parameters. API functions:
- * rte_table_action_apply().
- *
- * - Use the table action object to read action data (e.g. stats counters) for
- * any given rule. API functions: rte_table_action_XYZ_read().
- *
- * @warning
- * @b EXPERIMENTAL: this API may change without prior notice
- */
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_ether.h>
-#include <rte_ip6.h>
-#include <rte_meter.h>
-#include <rte_table_hash.h>
-
-#include "rte_pipeline.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Table actions. */
-enum rte_table_action_type {
- /** Forward to next pipeline table, output port or drop. */
- RTE_TABLE_ACTION_FWD = 0,
-
- /** Load balance. */
- RTE_TABLE_ACTION_LB,
-
- /** Traffic Metering and Policing. */
- RTE_TABLE_ACTION_MTR,
-
- /** Traffic Management. */
- RTE_TABLE_ACTION_TM,
-
- /** Packet encapsulations. */
- RTE_TABLE_ACTION_ENCAP,
-
- /** Network Address Translation (NAT). */
- RTE_TABLE_ACTION_NAT,
-
- /** Time to Live (TTL) update. */
- RTE_TABLE_ACTION_TTL,
-
- /** Statistics. */
- RTE_TABLE_ACTION_STATS,
-
- /** Timestamp. */
- RTE_TABLE_ACTION_TIME,
-
- /** Crypto. */
- RTE_TABLE_ACTION_SYM_CRYPTO,
-
- /** Tag. */
- RTE_TABLE_ACTION_TAG,
-
- /** Packet decapsulations. */
- RTE_TABLE_ACTION_DECAP,
-};
-
-/** Common action configuration (per table action profile). */
-struct rte_table_action_common_config {
- /** Input packet Internet Protocol (IP) version. Non-zero for IPv4, zero
- * for IPv6.
- */
- int ip_version;
-
- /** IP header offset within the input packet buffer. Offset 0 points to
- * the first byte of the MBUF structure.
- */
- uint32_t ip_offset;
-};
-
-/**
- * RTE_TABLE_ACTION_FWD
- */
-/** Forward action parameters (per table rule). */
-struct rte_table_action_fwd_params {
- /** Forward action. */
- enum rte_pipeline_action action;
-
- /** Pipeline table ID or output port ID. */
- uint32_t id;
-};
-
-/**
- * RTE_TABLE_ACTION_LB
- */
-/** Load balance key size min (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MIN 8
-
-/** Load balance key size max (number of bytes). */
-#define RTE_TABLE_ACTION_LB_KEY_SIZE_MAX 64
-
-/** Load balance table size. */
-#define RTE_TABLE_ACTION_LB_TABLE_SIZE 8
-
-/** Load balance action configuration (per table action profile). */
-struct rte_table_action_lb_config {
- /** Key size (number of bytes). */
- uint32_t key_size;
-
- /** Key offset within the input packet buffer. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t key_offset;
-
- /** Key mask (*key_size* bytes are valid). */
- uint8_t key_mask[RTE_TABLE_ACTION_LB_KEY_SIZE_MAX];
-
- /** Hash function. */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for *f_hash*. */
- uint64_t seed;
-
- /** Output value offset within the input packet buffer. Offset 0 points
- * to the first byte of the MBUF structure.
- */
- uint32_t out_offset;
-};
-
-/** Load balance action parameters (per table rule). */
-struct rte_table_action_lb_params {
- /** Table defining the output values and their weights. The weights are
- * set in 1/RTE_TABLE_ACTION_LB_TABLE_SIZE increments. To assign a
- * weight of N/RTE_TABLE_ACTION_LB_TABLE_SIZE to a given output value
- * (0 <= N <= RTE_TABLE_ACTION_LB_TABLE_SIZE), the same output value
- * needs to show up exactly N times in this table.
- */
- uint32_t out[RTE_TABLE_ACTION_LB_TABLE_SIZE];
-};
-
-/**
- * RTE_TABLE_ACTION_MTR
- */
-/** Max number of traffic classes (TCs). */
-#define RTE_TABLE_ACTION_TC_MAX 16
-
-/** Max number of queues per traffic class. */
-#define RTE_TABLE_ACTION_TC_QUEUE_MAX 16
-
-/** Differentiated Services Code Point (DSCP) translation table entry. */
-struct rte_table_action_dscp_table_entry {
- /** Traffic class. Used by the meter or the traffic management actions.
- * Has to be strictly smaller than *RTE_TABLE_ACTION_TC_MAX*. Traffic
- * class 0 is the highest priority.
- */
- uint32_t tc_id;
-
- /** Traffic class queue. Used by the traffic management action. Has to
- * be strictly smaller than *RTE_TABLE_ACTION_TC_QUEUE_MAX*.
- */
- uint32_t tc_queue_id;
-
- /** Packet color. Used by the meter action as the packet input color
- * for the color aware mode of the traffic metering algorithm.
- */
- enum rte_color color;
-};
-
-/** DSCP translation table. */
-struct rte_table_action_dscp_table {
- /** Array of DSCP table entries */
- struct rte_table_action_dscp_table_entry entry[64];
-};
-
-/** Supported traffic metering algorithms. */
-enum rte_table_action_meter_algorithm {
- /** Single Rate Three Color Marker (srTCM) - IETF RFC 2697. */
- RTE_TABLE_ACTION_METER_SRTCM,
-
- /** Two Rate Three Color Marker (trTCM) - IETF RFC 2698. */
- RTE_TABLE_ACTION_METER_TRTCM,
-};
-
-/** Traffic metering profile (configuration template). */
-struct rte_table_action_meter_profile {
- /** Traffic metering algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- union {
- /** Only valid when *alg* is set to srTCM - IETF RFC 2697. */
- struct rte_meter_srtcm_params srtcm;
-
- /** Only valid when *alg* is set to trTCM - IETF RFC 2698. */
- struct rte_meter_trtcm_params trtcm;
- };
-};
-
-/** Policer actions. */
-enum rte_table_action_policer {
- /** Recolor the packet as green. */
- RTE_TABLE_ACTION_POLICER_COLOR_GREEN = 0,
-
- /** Recolor the packet as yellow. */
- RTE_TABLE_ACTION_POLICER_COLOR_YELLOW,
-
- /** Recolor the packet as red. */
- RTE_TABLE_ACTION_POLICER_COLOR_RED,
-
- /** Drop the packet. */
- RTE_TABLE_ACTION_POLICER_DROP,
-
- /** Number of policer actions. */
- RTE_TABLE_ACTION_POLICER_MAX
-};
-
-/** Meter action configuration per traffic class. */
-struct rte_table_action_mtr_tc_params {
- /** Meter profile ID. */
- uint32_t meter_profile_id;
-
- /** Policer actions. */
- enum rte_table_action_policer policer[RTE_COLORS];
-};
-
-/** Meter action statistics counters per traffic class. */
-struct rte_table_action_mtr_counters_tc {
- /** Number of packets per color at the output of the traffic metering
- * and before the policer actions are executed. Only valid when
- * *n_packets_valid* is non-zero.
- */
- uint64_t n_packets[RTE_COLORS];
-
- /** Number of packet bytes per color at the output of the traffic
- * metering and before the policer actions are executed. Only valid when
- * *n_bytes_valid* is non-zero.
- */
- uint64_t n_bytes[RTE_COLORS];
-
- /** When non-zero, the *n_packets* field is valid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid. */
- int n_bytes_valid;
-};
-
-/** Meter action configuration (per table action profile). */
-struct rte_table_action_mtr_config {
- /** Meter algorithm. */
- enum rte_table_action_meter_algorithm alg;
-
- /** Number of traffic classes. Each traffic class has its own traffic
- * meter and policer instances. Needs to be equal to either 1 or to
- * *RTE_TABLE_ACTION_TC_MAX*.
- */
- uint32_t n_tc;
-
- /** When non-zero, the *n_packets* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* meter stats counter is enabled,
- * otherwise it is disabled.
- *
- * @see struct rte_table_action_mtr_counters_tc
- */
- int n_bytes_enabled;
-};
-
-/** Meter action parameters (per table rule). */
-struct rte_table_action_mtr_params {
- /** Traffic meter and policer parameters for each of the *tc_mask*
- * traffic classes.
- */
- struct rte_table_action_mtr_tc_params mtr[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/** Meter action statistics counters (per table rule). */
-struct rte_table_action_mtr_counters {
- /** Stats counters for each of the *tc_mask* traffic classes. */
- struct rte_table_action_mtr_counters_tc stats[RTE_TABLE_ACTION_TC_MAX];
-
- /** Bit mask defining which traffic class parameters are valid in *mtr*.
- * If bit N is set in *tc_mask*, then parameters for traffic class N are
- * valid in *mtr*.
- */
- uint32_t tc_mask;
-};
-
-/**
- * RTE_TABLE_ACTION_TM
- */
-/** Traffic management action configuration (per table action profile). */
-struct rte_table_action_tm_config {
- /** Number of subports per port. */
- uint32_t n_subports_per_port;
-
- /** Number of pipes per subport. */
- uint32_t n_pipes_per_subport;
-};
-
-/** Traffic management action parameters (per table rule). */
-struct rte_table_action_tm_params {
- /** Subport ID. */
- uint32_t subport_id;
-
- /** Pipe ID. */
- uint32_t pipe_id;
-};
-
-/**
- * RTE_TABLE_ACTION_ENCAP
- */
-/** Supported packet encapsulation types. */
-enum rte_table_action_encap_type {
- /** IP -> { Ether | IP } */
- RTE_TABLE_ACTION_ENCAP_ETHER = 0,
-
- /** IP -> { Ether | VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_VLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ,
-
- /** IP -> { Ether | MPLS | IP } */
- RTE_TABLE_ACTION_ENCAP_MPLS,
-
- /** IP -> { Ether | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_PPPOE,
-
- /** Ether -> { Ether | IP | UDP | VXLAN | Ether }
- * Ether -> { Ether | VLAN | IP | UDP | VXLAN | Ether }
- */
- RTE_TABLE_ACTION_ENCAP_VXLAN,
-
- /** IP -> { Ether | S-VLAN | C-VLAN | PPPoE | PPP | IP } */
- RTE_TABLE_ACTION_ENCAP_QINQ_PPPOE,
-};
-
-/** Pre-computed Ethernet header fields for encapsulation action. */
-struct rte_table_action_ether_hdr {
- struct rte_ether_addr da; /**< Destination address. */
- struct rte_ether_addr sa; /**< Source address. */
-};
-
-/** Pre-computed VLAN header fields for encapsulation action. */
-struct rte_table_action_vlan_hdr {
- uint8_t pcp; /**< Priority Code Point (PCP). */
- uint8_t dei; /**< Drop Eligibility Indicator (DEI). */
- uint16_t vid; /**< VLAN Identifier (VID). */
-};
-
-/** Pre-computed MPLS header fields for encapsulation action. */
-struct rte_table_action_mpls_hdr {
- uint32_t label; /**< Label. */
- uint8_t tc; /**< Traffic Class (TC). */
- uint8_t ttl; /**< Time to Live (TTL). */
-};
-
-/** Pre-computed PPPoE header fields for encapsulation action. */
-struct rte_table_action_pppoe_hdr {
- uint16_t session_id; /**< Session ID. */
-};
-
-/** Pre-computed IPv4 header fields for encapsulation action. */
-struct rte_table_action_ipv4_header {
- uint32_t sa; /**< Source address. */
- uint32_t da; /**< Destination address. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t ttl; /**< Time To Live (TTL). */
-};
-
-/** Pre-computed IPv6 header fields for encapsulation action. */
-struct rte_table_action_ipv6_header {
- struct rte_ipv6_addr sa; /**< Source address. */
- struct rte_ipv6_addr da; /**< Destination address. */
- uint32_t flow_label; /**< Flow label. */
- uint8_t dscp; /**< DiffServ Code Point (DSCP). */
- uint8_t hop_limit; /**< Hop Limit (HL). */
-};
-
-/** Pre-computed UDP header fields for encapsulation action. */
-struct rte_table_action_udp_header {
- uint16_t sp; /**< Source port. */
- uint16_t dp; /**< Destination port. */
-};
-
-/** Pre-computed VXLAN header fields for encapsulation action. */
-struct rte_table_action_vxlan_hdr {
- uint32_t vni; /**< VXLAN Network Identifier (VNI). */
-};
-
-/** Ether encap parameters. */
-struct rte_table_action_encap_ether_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
-};
-
-/** VLAN encap parameters. */
-struct rte_table_action_encap_vlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-};
-
-/** QinQ encap parameters. */
-struct rte_table_action_encap_qinq_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
-};
-
-/** Max number of MPLS labels per output packet for MPLS encapsulation. */
-#ifndef RTE_TABLE_ACTION_MPLS_LABELS_MAX
-#define RTE_TABLE_ACTION_MPLS_LABELS_MAX 4
-#endif
-
-/** MPLS encap parameters. */
-struct rte_table_action_encap_mpls_params {
- /** Ethernet header. */
- struct rte_table_action_ether_hdr ether;
-
- /** MPLS header. */
- struct rte_table_action_mpls_hdr mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
-
- /** Number of MPLS labels in MPLS header. */
- uint32_t mpls_count;
-
- /** Non-zero for MPLS unicast, zero for MPLS multicast. */
- int unicast;
-};
-
-/** PPPoE encap parameters. */
-struct rte_table_action_encap_pppoe_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** VXLAN encap parameters. */
-struct rte_table_action_encap_vxlan_params {
- struct rte_table_action_ether_hdr ether; /**< Ethernet header. */
- struct rte_table_action_vlan_hdr vlan; /**< VLAN header. */
-
- union {
- struct rte_table_action_ipv4_header ipv4; /**< IPv4 header. */
- struct rte_table_action_ipv6_header ipv6; /**< IPv6 header. */
- };
-
- struct rte_table_action_udp_header udp; /**< UDP header. */
- struct rte_table_action_vxlan_hdr vxlan; /**< VXLAN header. */
-};
-
-/** Encap action configuration (per table action profile). */
-struct rte_table_action_encap_config {
- /** Bit mask defining the set of packet encapsulations enabled for the
- * current table action profile. If bit (1 << N) is set in *encap_mask*,
- * then packet encapsulation N is enabled, otherwise it is disabled.
- *
- * @see enum rte_table_action_encap_type
- */
- uint64_t encap_mask;
-
- /** Encapsulation type specific configuration. */
- union {
- struct {
- /** Input packet to be encapsulated: offset within the
- * input packet buffer to the start of the Ethernet
- * frame to be encapsulated. Offset 0 points to the
- * first byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- /** Encapsulation header: non-zero when encapsulation
- * header includes a VLAN tag, zero otherwise.
- */
- int vlan;
-
- /** Encapsulation header: IP version of the IP header
- * within the encapsulation header. Non-zero for IPv4,
- * zero for IPv6.
- */
- int ip_version;
- } vxlan; /**< VXLAN specific configuration. */
- };
-};
-
-/** QinQ_PPPoE encap parameters. */
-struct rte_table_encap_ether_qinq_pppoe {
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_ether_hdr ether;
- struct rte_table_action_vlan_hdr svlan; /**< Service VLAN header. */
- struct rte_table_action_vlan_hdr cvlan; /**< Customer VLAN header. */
- struct rte_table_action_pppoe_hdr pppoe; /**< PPPoE/PPP headers. */
-};
-
-/** Encap action parameters (per table rule). */
-struct rte_table_action_encap_params {
- /** Encapsulation type. */
- enum rte_table_action_encap_type type;
-
- union {
- /** Only valid when *type* is set to Ether. */
- struct rte_table_action_encap_ether_params ether;
-
- /** Only valid when *type* is set to VLAN. */
- struct rte_table_action_encap_vlan_params vlan;
-
- /** Only valid when *type* is set to QinQ. */
- struct rte_table_action_encap_qinq_params qinq;
-
- /** Only valid when *type* is set to MPLS. */
- struct rte_table_action_encap_mpls_params mpls;
-
- /** Only valid when *type* is set to PPPoE. */
- struct rte_table_action_encap_pppoe_params pppoe;
-
- /** Only valid when *type* is set to VXLAN. */
- struct rte_table_action_encap_vxlan_params vxlan;
-
- /** Only valid when *type* is set to QinQ_PPPoE. */
- struct rte_table_encap_ether_qinq_pppoe qinq_pppoe;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_NAT
- */
-/** NAT action configuration (per table action profile). */
-struct rte_table_action_nat_config {
- /** When non-zero, the IP source address and L4 protocol source port are
- * translated. When zero, the IP destination address and L4 protocol
- * destination port are translated.
- */
- int source_nat;
-
- /** Layer 4 protocol, for example TCP (0x06) or UDP (0x11). The checksum
- * field is computed differently and placed at different header offset
- * by each layer 4 protocol.
- */
- uint8_t proto;
-};
-
-/** NAT action parameters (per table rule). */
-struct rte_table_action_nat_params {
- /** IP version for *addr*: non-zero for IPv4, zero for IPv6. */
- int ip_version;
-
- /** IP address. */
- union {
- /** IPv4 address; only valid when *ip_version* is non-zero. */
- uint32_t ipv4;
-
- /** IPv6 address; only valid when *ip_version* is set to 0. */
- struct rte_ipv6_addr ipv6;
- } addr;
-
- /** Port. */
- uint16_t port;
-};
-
-/**
- * RTE_TABLE_ACTION_TTL
- */
-/** TTL action configuration (per table action profile). */
-struct rte_table_action_ttl_config {
- /** When non-zero, the input packets whose updated IPv4 Time to Live
- * (TTL) field or IPv6 Hop Limit (HL) field is zero are dropped.
- * When zero, the input packets whose updated IPv4 TTL field or IPv6 HL
- * field is zero are forwarded as usual (typically for debugging
- * purpose).
- */
- int drop;
-
- /** When non-zero, the *n_packets* stats counter for TTL action is
- * enabled, otherwise disabled.
- *
- * @see struct rte_table_action_ttl_counters
- */
- int n_packets_enabled;
-};
-
-/** TTL action parameters (per table rule). */
-struct rte_table_action_ttl_params {
- /** When non-zero, decrement the IPv4 TTL field and update the checksum
- * field, or decrement the IPv6 HL field. When zero, the IPv4 TTL field
- * or the IPv6 HL field is not changed.
- */
- int decrement;
-};
-
-/** TTL action statistics packets (per table rule). */
-struct rte_table_action_ttl_counters {
- /** Number of IPv4 packets whose updated TTL field is zero or IPv6
- * packets whose updated HL field is zero.
- */
- uint64_t n_packets;
-};
-
-/**
- * RTE_TABLE_ACTION_STATS
- */
-/** Stats action configuration (per table action profile). */
-struct rte_table_action_stats_config {
- /** When non-zero, the *n_packets* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_packets_enabled;
-
- /** When non-zero, the *n_bytes* stats counter is enabled, otherwise
- * disabled.
- *
- * @see struct rte_table_action_stats_counters
- */
- int n_bytes_enabled;
-};
-
-/** Stats action parameters (per table rule). */
-struct rte_table_action_stats_params {
- /** Initial value for the *n_packets* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_packets;
-
- /** Initial value for the *n_bytes* stats counter. Typically set to 0.
- *
- * @see struct rte_table_action_stats_counters
- */
- uint64_t n_bytes;
-};
-
-/** Stats action counters (per table rule). */
-struct rte_table_action_stats_counters {
- /** Number of packets. Valid only when *n_packets_valid* is non-zero. */
- uint64_t n_packets;
-
- /** Number of bytes. Valid only when *n_bytes_valid* is non-zero. */
- uint64_t n_bytes;
-
- /** When non-zero, the *n_packets* field is valid, otherwise invalid. */
- int n_packets_valid;
-
- /** When non-zero, the *n_bytes* field is valid, otherwise invalid. */
- int n_bytes_valid;
-};
-
-/**
- * RTE_TABLE_ACTION_TIME
- */
-/** Timestamp action parameters (per table rule). */
-struct rte_table_action_time_params {
- /** Initial timestamp value. Typically set to current time. */
- uint64_t time;
-};
-
-/**
- * RTE_TABLE_ACTION_CRYPTO
- */
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX
-#define RTE_TABLE_ACTION_SYM_CRYPTO_AAD_SIZE_MAX (16)
-#endif
-
-#ifndef RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET
-#define RTE_TABLE_ACTION_SYM_CRYPTO_IV_OFFSET \
- (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op))
-#endif
-
-/** Common action structure to store the data's value, length, and offset */
-struct rte_table_action_vlo {
- uint8_t *val;
- uint32_t length;
- uint32_t offset;
-};
-
-/** Symmetric crypto action configuration (per table action profile). */
-struct rte_table_action_sym_crypto_config {
- /** Target Cryptodev ID. */
- uint8_t cryptodev_id;
-
- /**
- * Offset to rte_crypto_op structure within the input packet buffer.
- * Offset 0 points to the first byte of the MBUF structure.
- */
- uint32_t op_offset;
-
- /** The mempool for creating cryptodev sessions. */
- struct rte_mempool *mp_create;
-
- /** The mempool for initializing cryptodev sessions. */
- struct rte_mempool *mp_init;
-};
-
-/** Symmetric Crypto action parameters (per table rule). */
-struct rte_table_action_sym_crypto_params {
-
- /** Xform pointer contains all relevant information */
- struct rte_crypto_sym_xform *xform;
-
- /**
- * Offset within the input packet buffer to the first byte of data
- * to be processed by the crypto unit. Offset 0 points to the first
- * byte of the MBUF structure.
- */
- uint32_t data_offset;
-
- union {
- struct {
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv;
-
- /** Cipher iv data. */
- struct rte_table_action_vlo cipher_iv_update;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv;
-
- /** Auth iv data. */
- struct rte_table_action_vlo auth_iv_update;
-
- } cipher_auth;
-
- struct {
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv;
-
- /** AEAD AAD data. */
- struct rte_table_action_vlo aad_update;
-
- /** AEAD iv data. */
- struct rte_table_action_vlo iv_update;
-
- } aead;
- };
-};
-
-/**
- * RTE_TABLE_ACTION_TAG
- */
-/** Tag action parameters (per table rule). */
-struct rte_table_action_tag_params {
- /** Tag to be attached to the input packet. */
- uint32_t tag;
-};
-
-/**
- * RTE_TABLE_ACTION_DECAP
- */
-/** Decap action parameters (per table rule). */
-struct rte_table_action_decap_params {
- /** Number of bytes to be removed from the start of the packet. */
- uint16_t n;
-};
-
-/**
- * Table action profile.
- */
-struct rte_table_action_profile;
-
-/**
- * Table action profile create.
- *
- * @param[in] common
- * Common action configuration.
- * @return
- * Table action profile handle on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_table_action_profile *
-rte_table_action_profile_create(struct rte_table_action_common_config *common);
-
-/**
- * Table action profile free.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_free(struct rte_table_action_profile *profile);
-
-/**
- * Table action profile action register.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @param[in] type
- * Specific table action to be registered for *profile*.
- * @param[in] action_config
- * Configuration for the *type* action.
- * If struct rte_table_action_*type*_config is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_profile_action_register(struct rte_table_action_profile *profile,
- enum rte_table_action_type type,
- void *action_config);
-
-/**
- * Table action profile freeze.
- *
- * Once this function is called successfully, the given profile enters the
- * frozen state with the following immediate effects: no more actions can be
- * registered for this profile, so the profile can be instantiated to create
- * table action objects.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and not in frozen state).
- * @return
- * Zero on success, non-zero error code otherwise.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-int
-rte_table_action_profile_freeze(struct rte_table_action_profile *profile);
-
-/**
- * Table action.
- */
-struct rte_table_action;
-
-/**
- * Table action create.
- *
- * Instantiates the given table action profile to create a table action object.
- *
- * @param[in] profile
- * Table profile action handle (needs to be valid and in frozen state).
- * @param[in] socket_id
- * CPU socket ID where the internal data structures required by the new table
- * action object should be allocated.
- * @return
- * Handle to table action object on success, NULL on error.
- *
- * @see rte_table_action_create()
- */
-__rte_experimental
-struct rte_table_action *
-rte_table_action_create(struct rte_table_action_profile *profile,
- uint32_t socket_id);
-
-/**
- * Table action free.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_free(struct rte_table_action *action);
-
-/**
- * Table action table params get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[inout] params
- * Pipeline table parameters (needs to be pre-allocated).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_table_params_get(struct rte_table_action *action,
- struct rte_pipeline_table_params *params);
-
-/**
- * Table action apply.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) to apply action *type* on.
- * @param[in] type
- * Specific table action previously registered for the table action profile of
- * the *action* object.
- * @param[in] action_params
- * Parameters for the *type* action.
- * If struct rte_table_action_*type*_params is defined by the Table Action
- * API, it needs to point to a valid instance of this structure, otherwise it
- * needs to be set to NULL.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_apply(struct rte_table_action *action,
- void *data,
- enum rte_table_action_type type,
- void *action_params);
-
-/**
- * Table action DSCP table update.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] dscp_mask
- * 64-bit mask defining the DSCP table entries to be updated. If bit N is set
- * in this bit mask, then DSCP table entry N is to be updated, otherwise not.
- * @param[in] table
- * DSCP table.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_dscp_table_update(struct rte_table_action *action,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *table);
-
-/**
- * Table action meter profile add.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID to be used for the *profile* once it is successfully added
- * to the *action* object (needs to be unused by the set of meter profiles
- * currently registered for the *action* object).
- * @param[in] profile
- * Meter profile to be added.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_add(struct rte_table_action *action,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-/**
- * Table action meter profile delete.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] meter_profile_id
- * Meter profile ID of the meter profile to be deleted from the *action*
- * object (needs to be valid for the *action* object).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_profile_delete(struct rte_table_action *action,
- uint32_t meter_profile_id);
-
-/**
- * Table action meter read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with meter action previously
- * applied on it.
- * @param[in] tc_mask
- * Bit mask defining which traffic classes should have the meter stats
- * counters read from *data* and stored into *stats*. If bit N is set in this
- * bit mask, then traffic class N is part of this operation, otherwise it is
- * not. If bit N is set in this bit mask, then traffic class N must be one of
- * the traffic classes that are enabled for the meter action in the table
- * action profile used by the *action* object.
- * @param[inout] stats
- * When non-NULL, it points to the area where the meter stats counters read
- * from *data* are saved. Only the meter stats counters for the *tc_mask*
- * traffic classes are read and stored to *stats*.
- * @param[in] clear
- * When non-zero, the meter stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_meter_read(struct rte_table_action *action,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-/**
- * Table action TTL read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with TTL action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the TTL stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the TTL stats counters are cleared (i.e. set to zero),
- * otherwise the counters are not modified. When the read operation is enabled
- * (*stats* is non-NULL), the clear operation is performed after the read
- * operation is completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_ttl_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear);
-
-/**
- * Table action stats read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with stats action previously
- * applied on it.
- * @param[inout] stats
- * When non-NULL, it points to the area where the stats counters read from
- * *data* are saved.
- * @param[in] clear
- * When non-zero, the stats counters are cleared (i.e. set to zero), otherwise
- * the counters are not modified. When the read operation is enabled (*stats*
- * is non-NULL), the clear operation is performed after the read operation is
- * completed.
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_stats_read(struct rte_table_action *action,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-/**
- * Table action timestamp read.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with timestamp action
- * previously applied on it.
- * @param[inout] timestamp
- * Pre-allocated memory where the timestamp read from *data* is saved (has to
- * be non-NULL).
- * @return
- * Zero on success, non-zero error code otherwise.
- */
-__rte_experimental
-int
-rte_table_action_time_read(struct rte_table_action *action,
- void *data,
- uint64_t *timestamp);
-
-/**
- * Table action cryptodev symmetric session get.
- *
- * @param[in] action
- * Handle to table action object (needs to be valid).
- * @param[in] data
- * Data byte array (typically table rule data) with sym crypto action.
- * @return
- * The pointer to the session on success, NULL otherwise.
- */
-__rte_experimental
-struct rte_cryptodev_sym_session *
-rte_table_action_crypto_sym_session_get(struct rte_table_action *action,
- void *data);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __INCLUDE_RTE_TABLE_ACTION_H__ */
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 5/7] table: remove legacy API
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (12 preceding siblings ...)
2026-07-28 16:35 ` [PATCH v4 4/7] pipeline: remove legacy API Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 6/7] port: " Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 7/7] doc: remove packet framework images Stephen Hemminger
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu, Wathsala Vithanage
Remove the legacy table library API (rte_table_*) as announced
for removal in the 24.11 release. The SWX table API remains.
The lpm and port dependencies were only used by the legacy API,
so drop them. The hash and acl dependencies are still needed by
the SWX exact match and wildcard match tables.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 7 -
doc/guides/prog_guide/packet_framework.rst | 811 -------------
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 3 +
lib/table/meson.build | 30 +-
lib/table/rte_lru.h | 85 --
lib/table/rte_lru_arm64.h | 61 -
lib/table/rte_lru_x86.h | 96 --
lib/table/rte_table.h | 263 -----
lib/table/rte_table_acl.c | 795 -------------
lib/table/rte_table_acl.h | 65 --
lib/table/rte_table_array.c | 210 ----
lib/table/rte_table_array.h | 46 -
lib/table/rte_table_hash.h | 106 --
lib/table/rte_table_hash_cuckoo.c | 327 ------
lib/table/rte_table_hash_cuckoo.h | 57 -
lib/table/rte_table_hash_ext.c | 1011 ----------------
lib/table/rte_table_hash_func.h | 263 -----
lib/table/rte_table_hash_func_arm64.h | 21 -
lib/table/rte_table_hash_key16.c | 1190 -------------------
lib/table/rte_table_hash_key32.c | 1223 --------------------
lib/table/rte_table_hash_key8.c | 1157 ------------------
lib/table/rte_table_hash_lru.c | 959 ---------------
lib/table/rte_table_lpm.c | 369 ------
lib/table/rte_table_lpm.h | 94 --
lib/table/rte_table_lpm_ipv6.c | 370 ------
lib/table/rte_table_stub.c | 95 --
lib/table/rte_table_stub.h | 30 -
lib/table/table_log.c | 7 -
lib/table/table_log.h | 11 -
30 files changed, 4 insertions(+), 9763 deletions(-)
delete mode 100644 lib/table/rte_lru.h
delete mode 100644 lib/table/rte_lru_arm64.h
delete mode 100644 lib/table/rte_lru_x86.h
delete mode 100644 lib/table/rte_table.h
delete mode 100644 lib/table/rte_table_acl.c
delete mode 100644 lib/table/rte_table_acl.h
delete mode 100644 lib/table/rte_table_array.c
delete mode 100644 lib/table/rte_table_array.h
delete mode 100644 lib/table/rte_table_hash.h
delete mode 100644 lib/table/rte_table_hash_cuckoo.c
delete mode 100644 lib/table/rte_table_hash_cuckoo.h
delete mode 100644 lib/table/rte_table_hash_ext.c
delete mode 100644 lib/table/rte_table_hash_func.h
delete mode 100644 lib/table/rte_table_hash_func_arm64.h
delete mode 100644 lib/table/rte_table_hash_key16.c
delete mode 100644 lib/table/rte_table_hash_key32.c
delete mode 100644 lib/table/rte_table_hash_key8.c
delete mode 100644 lib/table/rte_table_hash_lru.c
delete mode 100644 lib/table/rte_table_lpm.c
delete mode 100644 lib/table/rte_table_lpm.h
delete mode 100644 lib/table/rte_table_lpm_ipv6.c
delete mode 100644 lib/table/rte_table_stub.c
delete mode 100644 lib/table/rte_table_stub.h
delete mode 100644 lib/table/table_log.c
delete mode 100644 lib/table/table_log.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 17c15027b8bd3aae13b992b4bfd038ef8b2bb5cd..760b770d6f8ac636e56541b4db609768e6558e11 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -189,13 +189,6 @@ The public API headers are grouped by topics:
[reass](@ref rte_port_ras.h),
[sched](@ref rte_port_sched.h),
[src/sink](@ref rte_port_source_sink.h)
- * [table](@ref rte_table.h):
- [lpm IPv4](@ref rte_table_lpm.h),
- [lpm IPv6](@ref rte_table_lpm_ipv6.h),
- [ACL](@ref rte_table_acl.h),
- [hash](@ref rte_table_hash.h),
- [array](@ref rte_table_array.h),
- [stub](@ref rte_table_stub.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index 9eb2c5d3de31fa88fd0f1b8246e7482f144ac011..98cf3be1099d88f78665b207beb982bd5c534c86 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -131,817 +131,6 @@ The port abstract interface is described below.
| | | |
+---+----------------+-----------------------------------------------------------------------------------------+
-Table Library Design
---------------------
-
-Table Types
-~~~~~~~~~~~
-
-:numref:`packet_framework_table_qos_21` is a non-exhaustive list of types of tables
-that can be implemented with the Packet Framework.
-
-.. _packet_framework_table_qos_21:
-
-.. table:: Table Types
-
- +---+----------------------------+-----------------------------------------------------------------------------+
- | # | Table Type | Description |
- | | | |
- +===+============================+=============================================================================+
- | 1 | Hash table | Lookup key is n-tuple based. |
- | | | |
- | | | Typically, the lookup key is hashed to produce a signature that is used to |
- | | | identify a bucket of entries where the lookup key is searched next. |
- | | | |
- | | | The signature associated with the lookup key of each input packet is either |
- | | | read from the packet descriptor (pre-computed signature) or computed at |
- | | | table lookup time. |
- | | | |
- | | | The table lookup, add entry and delete entry operations, as well as any |
- | | | other pipeline block that pre-computes the signature all have to use the |
- | | | same hashing algorithm to generate the signature. |
- | | | |
- | | | Typically used to implement flow classification tables, ARP caches, routing |
- | | | table for tunnelling protocols, etc. |
- | | | |
- +---+----------------------------+-----------------------------------------------------------------------------+
- | 2 | Longest Prefix Match (LPM) | Lookup key is the IP address. |
- | | | |
- | | | Each table entries has an associated IP prefix (IP and depth). |
- | | | |
- | | | The table lookup operation selects the IP prefix that is matched by the |
- | | | lookup key; in case of multiple matches, the entry with the longest prefix |
- | | | depth wins. |
- | | | |
- | | | Typically used to implement IP routing tables. |
- | | | |
- +---+----------------------------+-----------------------------------------------------------------------------+
- | 3 | Access Control List (ACLs) | Lookup key is 7-tuple of two VLAN/MPLS labels, IP destination address, |
- | | | IP source addresses, L4 protocol, L4 destination port, L4 source port. |
- | | | |
- | | | Each table entry has an associated ACL and priority. The ACL contains bit |
- | | | masks for the VLAN/MPLS labels, IP prefix for IP destination address, IP |
- | | | prefix for IP source addresses, L4 protocol and bitmask, L4 destination |
- | | | port and bit mask, L4 source port and bit mask. |
- | | | |
- | | | The table lookup operation selects the ACL that is matched by the lookup |
- | | | key; in case of multiple matches, the entry with the highest priority wins. |
- | | | |
- | | | Typically used to implement rule databases for firewalls, etc. |
- | | | |
- +---+----------------------------+-----------------------------------------------------------------------------+
- | 4 | Pattern matching search | Lookup key is the packet payload. |
- | | | |
- | | | Table is a database of patterns, with each pattern having a priority |
- | | | assigned. |
- | | | |
- | | | The table lookup operation selects the patterns that is matched by the |
- | | | input packet; in case of multiple matches, the matching pattern with the |
- | | | highest priority wins. |
- | | | |
- +---+----------------------------+-----------------------------------------------------------------------------+
- | 5 | Array | Lookup key is the table entry index itself. |
- | | | |
- +---+----------------------------+-----------------------------------------------------------------------------+
-
-Table Interface
-~~~~~~~~~~~~~~~
-
-Each table is required to implement an abstract interface that defines the initialization
-and run-time operation of the table.
-The table abstract interface is described in :numref:`packet_framework_table_qos_29_1`.
-
-.. _packet_framework_table_qos_29_1:
-
-.. table:: Table Abstract Interface
-
- +---+-----------------+----------------------------------------------------------------------------------------+
- | # | Table operation | Description |
- | | | |
- +===+=================+========================================================================================+
- | 1 | Create | Create the low-level data structures of the lookup table. Can internally allocate |
- | | | memory. |
- | | | |
- +---+-----------------+----------------------------------------------------------------------------------------+
- | 2 | Free | Free up all the resources used by the lookup table. |
- | | | |
- +---+-----------------+----------------------------------------------------------------------------------------+
- | 3 | Add entry | Add new entry to the lookup table. |
- | | | |
- +---+-----------------+----------------------------------------------------------------------------------------+
- | 4 | Delete entry | Delete specific entry from the lookup table. |
- | | | |
- +---+-----------------+----------------------------------------------------------------------------------------+
- | 5 | Lookup | Look up a burst of input packets and return a bit mask specifying the result of the |
- | | | lookup operation for each packet: a set bit signifies lookup hit for the corresponding |
- | | | packet, while a cleared bit a lookup miss. |
- | | | |
- | | | For each lookup hit packet, the lookup operation also returns a pointer to the table |
- | | | entry that was hit, which contains the actions to be applied on the packet and any |
- | | | associated metadata. |
- | | | |
- | | | For each lookup miss packet, the actions to be applied on the packet and any |
- | | | associated metadata are specified by the default table entry preconfigured for lookup |
- | | | miss. |
- | | | |
- +---+-----------------+----------------------------------------------------------------------------------------+
-
-
-Hash Table Design
-~~~~~~~~~~~~~~~~~
-
-Hash Table Overview
-^^^^^^^^^^^^^^^^^^^
-
-Hash tables are important because the key lookup operation is optimized for speed:
-instead of having to linearly search the lookup key through all the keys in the table,
-the search is limited to only the keys stored in a single table bucket.
-
-**Associative Arrays**
-
-An associative array is a function that can be specified as a set of (key, value) pairs,
-with each key from the possible set of input keys present at most once.
-For a given associative array, the possible operations are:
-
-#. *add (key, value)*: When no value is currently associated with *key*, then the (key, *value* ) association is created.
- When *key* is already associated value *value0*, then the association (*key*, *value0*) is removed
- and association *(key, value)* is created;
-
-#. *delete key*: When no value is currently associated with *key*, this operation has no effect.
- When *key* is already associated *value*, then association *(key, value)* is removed;
-
-#. *lookup key*: When no value is currently associated with *key*, then this operation returns void value (lookup miss).
- When *key* is associated with *value*, then this operation returns *value*.
- The *(key, value)* association is not changed.
-
-The matching criterion used to compare the input key against the keys in the associative array is *exact match*,
-as the key size (number of bytes) and the key value (array of bytes) have to match exactly for the two keys under comparison.
-
-**Hash Function**
-
-A hash function deterministically maps data of variable length (key) to data of fixed size (hash value or key signature).
-Typically, the size of the key is bigger than the size of the key signature.
-The hash function basically compresses a long key into a short signature.
-Several keys can share the same signature (collisions).
-
-High quality hash functions have uniform distribution.
-For large number of keys, when dividing the space of signature values into a fixed number of equal intervals (buckets),
-it is desirable to have the key signatures evenly distributed across these intervals (uniform distribution),
-as opposed to most of the signatures going into only a few of the intervals
-and the rest of the intervals being largely unused (non-uniform distribution).
-
-**Hash Table**
-
-A hash table is an associative array that uses a hash function for its operation.
-The reason for using a hash function is to optimize the performance of the lookup operation
-by minimizing the number of table keys that have to be compared against the input key.
-
-Instead of storing the (key, value) pairs in a single list, the hash table maintains multiple lists (buckets).
-For any given key, there is a single bucket where that key might exist, and this bucket is uniquely identified based on the key signature.
-Once the key signature is computed and the hash table bucket identified,
-the key is either located in this bucket or it is not present in the hash table at all,
-so the key search can be narrowed down from the full set of keys currently in the table
-to just the set of keys currently in the identified table bucket.
-
-The performance of the hash table lookup operation is greatly improved,
-provided that the table keys are evenly distributed among the hash table buckets,
-which can be achieved by using a hash function with uniform distribution.
-The rule to map a key to its bucket can simply be to use the key signature (modulo the number of table buckets) as the table bucket ID:
-
- *bucket_id = f_hash(key) % n_buckets;*
-
-By selecting the number of buckets to be a power of two, the modulo operator can be replaced by a bitwise AND logical operation:
-
- *bucket_id = f_hash(key) & (n_buckets - 1);*
-
-considering *n_bits* as the number of bits set in *bucket_mask = n_buckets - 1*,
-this means that all the keys that end up in the same hash table bucket have the lower *n_bits* of their signature identical.
-In order to reduce the number of keys in the same bucket (collisions), the number of hash table buckets needs to be increased.
-
-In packet processing context, the sequence of operations involved in hash table operations
-is described in :numref:`packet_framework_figure_33`:
-
-.. _packet_framework_figure_33:
-
-.. figure:: img/figure33.*
-
- Sequence of Steps for Hash Table Operations in a Packet Processing Context
-
-
-
-Hash Table Use Cases
-^^^^^^^^^^^^^^^^^^^^
-
-**Flow Classification**
-
-*Description:* The flow classification is executed at least once for each input packet.
-This operation maps each incoming packet against one of the known traffic flows in the flow database that typically contains millions of flows.
-
-*Hash table name:* Flow classification table
-
-*Number of keys:* Millions
-
-*Key format:* n-tuple of packet fields that uniquely identify a traffic flow/connection.
-Example: DiffServ 5-tuple of (Source IP address, Destination IP address, L4 protocol, L4 protocol source port, L4 protocol destination port).
-For IPv4 protocol and L4 protocols like TCP, UDP or SCTP, the size of the DiffServ 5-tuple is 13 bytes, while for IPv6 it is 37 bytes.
-
-*Key value (key data):* actions and action meta-data describing what processing to be applied for the packets of the current flow.
-The size of the data associated with each traffic flow can vary from 8 bytes to kilobytes.
-
-**Address Resolution Protocol (ARP)**
-
-*Description:* Once a route has been identified for an IP packet (so the output interface and the IP address of the next hop station are known),
-the MAC address of the next hop station is needed in order to send this packet onto the next leg of the journey
-towards its destination (as identified by its destination IP address).
-The MAC address of the next hop station becomes the destination MAC address of the outgoing Ethernet frame.
-
-*Hash table name:* ARP table
-
-*Number of keys:* Thousands
-
-*Key format:* The pair of (Output interface, Next Hop IP address), which is typically 5 bytes for IPv4 and 17 bytes for IPv6.
-
-*Key value (key data):* MAC address of the next hop station (6 bytes).
-
-Hash Table Types
-^^^^^^^^^^^^^^^^
-
-:numref:`packet_framework_table_qos_22` lists the hash table configuration parameters
-shared by all different hash table types.
-
-.. _packet_framework_table_qos_22:
-
-.. table:: Configuration Parameters Common for All Hash Table Types
-
- +---+---------------------------+------------------------------------------------------------------------------+
- | # | Parameter | Details |
- | | | |
- +===+===========================+==============================================================================+
- | 1 | Key size | Measured as number of bytes. All keys have the same size. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 2 | Key value (key data) size | Measured as number of bytes. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 3 | Number of buckets | Needs to be a power of two. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 4 | Maximum number of keys | Needs to be a power of two. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 5 | Hash function | Examples: jhash, CRC hash, etc. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 6 | Hash function seed | Parameter to be passed to the hash function. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 7 | Key offset | Offset of the lookup key byte array within the packet meta-data stored in |
- | | | the packet buffer. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
-
-Bucket Full Problem
-"""""""""""""""""""
-
-On initialization, each hash table bucket is allocated space for exactly 4 keys.
-As keys are added to the table, it can happen that a given bucket already has 4 keys when a new key has to be added to this bucket.
-The possible options are:
-
-#. **Least Recently Used (LRU) Hash Table.**
- One of the existing keys in the bucket is deleted and the new key is added in its place.
- The number of keys in each bucket never grows bigger than 4. The logic to pick the key to be dropped from the bucket is LRU.
- The hash table lookup operation maintains the order in which the keys in the same bucket are hit, so every time a key is hit,
- it becomes the new Most Recently Used (MRU) key, i.e. the last candidate for drop.
- When a key is added to the bucket, it also becomes the new MRU key.
- When a key needs to be picked and dropped, the first candidate for drop, i.e. the current LRU key, is always picked.
- The LRU logic requires maintaining specific data structures per each bucket.
-
-#. **Extendable Bucket Hash Table.**
- The bucket is extended with space for 4 more keys.
- This is done by allocating additional memory at table initialization time,
- which is used to create a pool of free keys (the size of this pool is configurable and always a multiple of 4).
- On key add operation, the allocation of a group of 4 keys only happens successfully within the limit of free keys,
- otherwise the key add operation fails.
- On key delete operation, a group of 4 keys is freed back to the pool of free keys
- when the key to be deleted is the only key that was used within its group of 4 keys at that time.
- On key lookup operation, if the current bucket is in extended state and a match is not found in the first group of 4 keys,
- the search continues beyond the first group of 4 keys, potentially until all keys in this bucket are examined.
- The extendable bucket logic requires maintaining specific data structures per table and per each bucket.
-
-.. table:: Configuration Parameters Specific to Extendable Bucket Hash Table
-
- +---+---------------------------+--------------------------------------------------+
- | # | Parameter | Details |
- | | | |
- +===+===========================+==================================================+
- | 1 | Number of additional keys | Needs to be a power of two, at least equal to 4. |
- | | | |
- +---+---------------------------+--------------------------------------------------+
-
-
-Signature Computation
-"""""""""""""""""""""
-
-The possible options for key signature computation are:
-
-#. **Pre-computed key signature.**
- The key lookup operation is split between two CPU cores.
- The first CPU core (typically the CPU core that performs packet RX) extracts the key from the input packet,
- computes the key signature and saves both the key and the key signature in the packet buffer as packet meta-data.
- The second CPU core reads both the key and the key signature from the packet meta-data
- and performs the bucket search step of the key lookup operation.
-
-#. **Key signature computed on lookup ("do-sig" version).**
- The same CPU core reads the key from the packet meta-data, uses it to compute the key signature
- and also performs the bucket search step of the key lookup operation.
-
-.. table:: Configuration Parameters Specific to Pre-computed Key Signature Hash Table
-
- +---+------------------+-----------------------------------------------------------------------+
- | # | Parameter | Details |
- | | | |
- +===+==================+=======================================================================+
- | 1 | Signature offset | Offset of the pre-computed key signature within the packet meta-data. |
- | | | |
- +---+------------------+-----------------------------------------------------------------------+
-
-Key Size Optimized Hash Tables
-""""""""""""""""""""""""""""""
-
-For specific key sizes, the data structures and algorithm of key lookup operation can be specially handcrafted for further performance improvements,
-so following options are possible:
-
-#. **Implementation supporting configurable key size.**
-
-#. **Implementation supporting a single key size.**
- Typical key sizes are 8 bytes and 16 bytes.
-
-Bucket Search Logic for Configurable Key Size Hash Tables
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The performance of the bucket search logic is one of the main factors influencing the performance of the key lookup operation.
-The data structures and algorithm are designed to make the best use of Intel CPU architecture resources like:
-cache memory space, cache memory bandwidth, external memory bandwidth, multiple execution units working in parallel,
-out of order instruction execution, special CPU instructions, etc.
-
-The bucket search logic handles multiple input packets in parallel.
-It is built as a pipeline of several stages (3 or 4), with each pipeline stage handling two different packets from the burst of input packets.
-On each pipeline iteration, the packets are pushed to the next pipeline stage: for the 4-stage pipeline,
-two packets (that just completed stage 3) exit the pipeline,
-two packets (that just completed stage 2) are now executing stage 3, two packets (that just completed stage 1) are now executing stage 2,
-two packets (that just completed stage 0) are now executing stage 1 and two packets (next two packets to read from the burst of input packets)
-are entering the pipeline to execute stage 0.
-The pipeline iterations continue until all packets from the burst of input packets execute the last stage of the pipeline.
-
-The bucket search logic is broken into pipeline stages at the boundary of the next memory access.
-Each pipeline stage uses data structures that are stored (with high probability) into the L1 or L2 cache memory of the current CPU core and
-breaks just before the next memory access required by the algorithm.
-The current pipeline stage finalizes by prefetching the data structures required by the next pipeline stage,
-so given enough time for the prefetch to complete,
-when the next pipeline stage eventually gets executed for the same packets,
-it will read the data structures it needs from L1 or L2 cache memory and thus avoid the significant penalty incurred by L2 or L3 cache memory miss.
-
-By prefetching the data structures required by the next pipeline stage in advance (before they are used)
-and switching to executing another pipeline stage for different packets,
-the number of L2 or L3 cache memory misses is greatly reduced, hence one of the main reasons for improved performance.
-This is because the cost of L2/L3 cache memory miss on memory read accesses is high, as usually due to data dependency between instructions,
-the CPU execution units have to stall until the read operation is completed from L3 cache memory or external DRAM memory.
-By using prefetch instructions, the latency of memory read accesses is hidden,
-provided that it is performed early enough before the respective data structure is actually used.
-
-By splitting the processing into several stages that are executed on different packets (the packets from the input burst are interlaced),
-enough work is created to allow the prefetch instructions to complete successfully (before the prefetched data structures are actually accessed) and
-also the data dependency between instructions is loosened.
-For example, for the 4-stage pipeline, stage 0 is executed on packets 0 and 1 and then,
-before same packets 0 and 1 are used (i.e. before stage 1 is executed on packets 0 and 1),
-different packets are used: packets 2 and 3 (executing stage 1), packets 4 and 5 (executing stage 2) and packets 6 and 7 (executing stage 3).
-By executing useful work while the data structures are brought into the L1 or L2 cache memory, the latency of the read memory accesses is hidden.
-By increasing the gap between two consecutive accesses to the same data structure, the data dependency between instructions is loosened;
-this allows making the best use of the super-scalar and out-of-order execution CPU architecture,
-as the number of CPU core execution units that are active (rather than idle or stalled due to data dependency constraints between instructions) is maximized.
-
-The bucket search logic is also implemented without using any branch instructions.
-This avoids the important cost associated with flushing the CPU core execution pipeline on every instance of branch misprediction.
-
-Configurable Key Size Hash Table
-""""""""""""""""""""""""""""""""
-
-:numref:`packet_framework_figure_34`, :numref:`packet_framework_table_qos_25`
-and :numref:`packet_framework_table_qos_26`
-detail the main data structures used to implement configurable key size hash tables
-(either LRU or extendable bucket, either with pre-computed signature or "do-sig").
-
-.. _packet_framework_figure_34:
-
-.. figure:: img/figure34.*
-
- Data Structures for Configurable Key Size Hash Tables
-
-
-.. _packet_framework_table_qos_25:
-
-.. table:: Main Large Data Structures (Arrays) used for Configurable Key Size Hash Tables
-
- +---+-------------------------+------------------------------+---------------------------+-------------------------------+
- | # | Array name | Number of entries | Entry size (bytes) | Description |
- | | | | | |
- +===+=========================+==============================+===========================+===============================+
- | 1 | Bucket array | n_buckets (configurable) | 32 | Buckets of the hash table. |
- | | | | | |
- +---+-------------------------+------------------------------+---------------------------+-------------------------------+
- | 2 | Bucket extensions array | n_buckets_ext (configurable) | 32 | This array is only created |
- | | | | | for extendable bucket tables. |
- | | | | | |
- +---+-------------------------+------------------------------+---------------------------+-------------------------------+
- | 3 | Key array | n_keys | key_size (configurable) | Keys added to the hash table. |
- | | | | | |
- +---+-------------------------+------------------------------+---------------------------+-------------------------------+
- | 4 | Data array | n_keys | entry_size (configurable) | Key values (key data) |
- | | | | | associated with the hash |
- | | | | | table keys. |
- | | | | | |
- +---+-------------------------+------------------------------+---------------------------+-------------------------------+
-
-.. _packet_framework_table_qos_26:
-
-.. table:: Field Description for Bucket Array Entry (Configurable Key Size Hash Tables)
-
- +---+------------------+--------------------+------------------------------------------------------------------+
- | # | Field name | Field size (bytes) | Description |
- | | | | |
- +===+==================+====================+==================================================================+
- | 1 | Next Ptr/LRU | 8 | For LRU tables, this fields represents the LRU list for the |
- | | | | current bucket stored as array of 4 entries of 2 bytes each. |
- | | | | Entry 0 stores the index (0 .. 3) of the MRU key, while entry 3 |
- | | | | stores the index of the LRU key. |
- | | | | |
- | | | | For extendable bucket tables, this field represents the next |
- | | | | pointer (i.e. the pointer to the next group of 4 keys linked to |
- | | | | the current bucket). The next pointer is not NULL if the bucket |
- | | | | is currently extended or NULL otherwise. |
- | | | | To help the branchless implementation, bit 0 (least significant |
- | | | | bit) of this field is set to 1 if the next pointer is not NULL |
- | | | | and to 0 otherwise. |
- | | | | |
- +---+------------------+--------------------+------------------------------------------------------------------+
- | 2 | Sig[0 .. 3] | 4 x 2 | If key X (X = 0 .. 3) is valid, then sig X bits 15 .. 1 store |
- | | | | the most significant 15 bits of key X signature and sig X bit 0 |
- | | | | is set to 1. |
- | | | | |
- | | | | If key X is not valid, then sig X is set to zero. |
- | | | | |
- +---+------------------+--------------------+------------------------------------------------------------------+
- | 3 | Key Pos [0 .. 3] | 4 x 4 | If key X is valid (X = 0 .. 3), then Key Pos X represents the |
- | | | | index into the key array where key X is stored, as well as the |
- | | | | index into the data array where the value associated with key X |
- | | | | is stored. |
- | | | | |
- | | | | If key X is not valid, then the value of Key Pos X is undefined. |
- | | | | |
- +---+------------------+--------------------+------------------------------------------------------------------+
-
-
-:numref:`packet_framework_figure_35` and :numref:`packet_framework_table_qos_27`
-detail the bucket search pipeline stages
-(either LRU or extendable bucket, either with pre-computed signature or "do-sig").
-For each pipeline stage, the described operations are applied to each of the two packets handled by that stage.
-
-.. _packet_framework_figure_35:
-
-.. figure:: img/figure35.*
-
- Bucket Search Pipeline for Key Lookup Operation (Configurable Key Size Hash
- Tables)
-
-
-.. _packet_framework_table_qos_27:
-
-.. table:: Description of the Bucket Search Pipeline Stages (Configurable Key Size Hash Tables)
-
- +---+---------------------------+------------------------------------------------------------------------------+
- | # | Stage name | Description |
- | | | |
- +===+===========================+==============================================================================+
- | 0 | Prefetch packet meta-data | Select next two packets from the burst of input packets. |
- | | | |
- | | | Prefetch packet meta-data containing the key and key signature. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 1 | Prefetch table bucket | Read the key signature from the packet meta-data (for extendable bucket hash |
- | | | tables) or read the key from the packet meta-data and compute key signature |
- | | | (for LRU tables). |
- | | | |
- | | | Identify the bucket ID using the key signature. |
- | | | |
- | | | Set bit 0 of the signature to 1 (to match only signatures of valid keys from |
- | | | the table). |
- | | | |
- | | | Prefetch the bucket. |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 2 | Prefetch table key | Read the key signatures from the bucket. |
- | | | |
- | | | Compare the signature of the input key against the 4 key signatures from the |
- | | | packet. As result, the following is obtained: |
- | | | |
- | | | *match* |
- | | | = equal to TRUE if there was at least one signature match and to FALSE in |
- | | | the case of no signature match; |
- | | | |
- | | | *match_many* |
- | | | = equal to TRUE is there were more than one signature matches (can be up to |
- | | | 4 signature matches in the worst case scenario) and to FALSE otherwise; |
- | | | |
- | | | *match_pos* |
- | | | = the index of the first key that produced signature match (only valid if |
- | | | match is true). |
- | | | |
- | | | For extendable bucket hash tables only, set |
- | | | *match_many* |
- | | | to TRUE if next pointer is valid. |
- | | | |
- | | | Prefetch the bucket key indicated by |
- | | | *match_pos* |
- | | | (even if |
- | | | *match_pos* |
- | | | does not point to valid key valid). |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
- | 3 | Prefetch table data | Read the bucket key indicated by |
- | | | *match_pos*. |
- | | | |
- | | | Compare the bucket key against the input key. As result, the following is |
- | | | obtained: |
- | | | *match_key* |
- | | | = equal to TRUE if the two keys match and to FALSE otherwise. |
- | | | |
- | | | Report input key as lookup hit only when both |
- | | | *match* |
- | | | and |
- | | | *match_key* |
- | | | are equal to TRUE and as lookup miss otherwise. |
- | | | |
- | | | For LRU tables only, use branchless logic to update the bucket LRU list |
- | | | (the current key becomes the new MRU) only on lookup hit. |
- | | | |
- | | | Prefetch the key value (key data) associated with the current key (to avoid |
- | | | branches, this is done on both lookup hit and miss). |
- | | | |
- +---+---------------------------+------------------------------------------------------------------------------+
-
-
-Additional notes:
-
-#. The pipelined version of the bucket search algorithm is executed only if there are at least 7 packets in the burst of input packets.
- If there are less than 7 packets in the burst of input packets,
- a non-optimized implementation of the bucket search algorithm is executed.
-
-#. Once the pipelined version of the bucket search algorithm has been executed for all the packets in the burst of input packets,
- the non-optimized implementation of the bucket search algorithm is also executed for any packets that did not produce a lookup hit,
- but have the *match_many* flag set.
- As result of executing the non-optimized version, some of these packets may produce a lookup hit or lookup miss.
- This does not impact the performance of the key lookup operation,
- as the probability of matching more than one signature in the same group of 4 keys or of having the bucket in extended state
- (for extendable bucket hash tables only) is relatively small.
-
-**Key Signature Comparison Logic**
-
-The key signature comparison logic is described in :numref:`packet_framework_table_qos_28`.
-
-.. _packet_framework_table_qos_28:
-
-.. table:: Lookup Tables for Match, Match_Many and Match_Pos
-
- +----+------+---------------+--------------------+--------------------+
- | # | mask | match (1 bit) | match_many (1 bit) | match_pos (2 bits) |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 0 | 0000 | 0 | 0 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 1 | 0001 | 1 | 0 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 2 | 0010 | 1 | 0 | 01 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 3 | 0011 | 1 | 1 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 4 | 0100 | 1 | 0 | 10 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 5 | 0101 | 1 | 1 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 6 | 0110 | 1 | 1 | 01 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 7 | 0111 | 1 | 1 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 8 | 1000 | 1 | 0 | 11 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 9 | 1001 | 1 | 1 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 10 | 1010 | 1 | 1 | 01 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 11 | 1011 | 1 | 1 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 12 | 1100 | 1 | 1 | 10 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 13 | 1101 | 1 | 1 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 14 | 1110 | 1 | 1 | 01 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
- | 15 | 1111 | 1 | 1 | 00 |
- | | | | | |
- +----+------+---------------+--------------------+--------------------+
-
-The input *mask* hash bit X (X = 0 .. 3) set to 1 if input signature is equal to bucket signature X and set to 0 otherwise.
-The outputs *match*, *match_many* and *match_pos* are 1 bit, 1 bit and 2 bits in size respectively and their meaning has been explained above.
-
-As displayed in :numref:`packet_framework_table_qos_29`,
-the lookup tables for *match* and *match_many* can be collapsed into a single 32-bit value
-and the lookup table for *match_pos* can be collapsed into a 64-bit value.
-Given the input *mask*, the values for *match*, *match_many* and *match_pos* can be obtained by indexing their respective bit array to extract 1 bit,
-1 bit and 2 bits respectively with branchless logic.
-
-.. _packet_framework_table_qos_29:
-
-.. table:: Collapsed Lookup Tables for Match, Match_Many and Match_Pos
-
- +------------+------------------------------------------+-------------------+
- | | Bit array | Hexadecimal value |
- | | | |
- +------------+------------------------------------------+-------------------+
- | match | 1111_1111_1111_1110 | 0xFFFELLU |
- | | | |
- +------------+------------------------------------------+-------------------+
- | match_many | 1111_1110_1110_1000 | 0xFEE8LLU |
- | | | |
- +------------+------------------------------------------+-------------------+
- | match_pos | 0001_0010_0001_0011__0001_0010_0001_0000 | 0x12131210LLU |
- | | | |
- +------------+------------------------------------------+-------------------+
-
-
-The pseudo-code for match, match_many and match_pos is::
-
- match = (0xFFFELLU >> mask) & 1;
-
- match_many = (0xFEE8LLU >> mask) & 1;
-
- match_pos = (0x12131210LLU >> (mask << 1)) & 3;
-
-Single Key Size Hash Tables
-"""""""""""""""""""""""""""
-
-:numref:`packet_framework_figure_37`, :numref:`packet_framework_figure_38`,
-:numref:`packet_framework_table_qos_30` and :numref:`packet_framework_table_qos_31`
-detail the main data structures used to implement 8-byte and 16-byte key hash tables
-(either LRU or extendable bucket, either with pre-computed signature or "do-sig").
-
-.. _packet_framework_figure_37:
-
-.. figure:: img/figure37.*
-
- Data Structures for 8-byte Key Hash Tables
-
-
-.. _packet_framework_figure_38:
-
-.. figure:: img/figure38.*
-
- Data Structures for 16-byte Key Hash Tables
-
-
-.. _packet_framework_table_qos_30:
-
-.. table:: Main Large Data Structures (Arrays) used for 8-byte and 16-byte Key Size Hash Tables
-
- +---+-------------------------+------------------------------+----------------------+------------------------------------+
- | # | Array name | Number of entries | Entry size (bytes) | Description |
- | | | | | |
- +===+=========================+==============================+======================+====================================+
- | 1 | Bucket array | n_buckets (configurable) | *8-byte key size:* | Buckets of the hash table. |
- | | | | | |
- | | | | 64 + 4 x entry_size | |
- | | | | | |
- | | | | | |
- | | | | *16-byte key size:* | |
- | | | | | |
- | | | | 128 + 4 x entry_size | |
- | | | | | |
- +---+-------------------------+------------------------------+----------------------+------------------------------------+
- | 2 | Bucket extensions array | n_buckets_ext (configurable) | *8-byte key size:* | This array is only created for |
- | | | | | extendable bucket tables. |
- | | | | | |
- | | | | 64 + 4 x entry_size | |
- | | | | | |
- | | | | | |
- | | | | *16-byte key size:* | |
- | | | | | |
- | | | | 128 + 4 x entry_size | |
- | | | | | |
- +---+-------------------------+------------------------------+----------------------+------------------------------------+
-
-.. _packet_framework_table_qos_31:
-
-.. table:: Field Description for Bucket Array Entry (8-byte and 16-byte Key Hash Tables)
-
- +---+---------------+--------------------+-------------------------------------------------------------------------------+
- | # | Field name | Field size (bytes) | Description |
- | | | | |
- +===+===============+====================+===============================================================================+
- | 1 | Valid | 8 | Bit X (X = 0 .. 3) is set to 1 if key X is valid or to 0 otherwise. |
- | | | | |
- | | | | Bit 4 is only used for extendable bucket tables to help with the |
- | | | | implementation of the branchless logic. In this case, bit 4 is set to 1 if |
- | | | | next pointer is valid (not NULL) or to 0 otherwise. |
- | | | | |
- +---+---------------+--------------------+-------------------------------------------------------------------------------+
- | 2 | Next Ptr/LRU | 8 | For LRU tables, this fields represents the LRU list for the current bucket |
- | | | | stored as array of 4 entries of 2 bytes each. Entry 0 stores the index |
- | | | | (0 .. 3) of the MRU key, while entry 3 stores the index of the LRU key. |
- | | | | |
- | | | | For extendable bucket tables, this field represents the next pointer (i.e. |
- | | | | the pointer to the next group of 4 keys linked to the current bucket). The |
- | | | | next pointer is not NULL if the bucket is currently extended or NULL |
- | | | | otherwise. |
- | | | | |
- +---+---------------+--------------------+-------------------------------------------------------------------------------+
- | 3 | Key [0 .. 3] | 4 x key_size | Full keys. |
- | | | | |
- +---+---------------+--------------------+-------------------------------------------------------------------------------+
- | 4 | Data [0 .. 3] | 4 x entry_size | Full key values (key data) associated with keys 0 .. 3. |
- | | | | |
- +---+---------------+--------------------+-------------------------------------------------------------------------------+
-
-and detail the bucket search pipeline used to implement 8-byte and 16-byte key hash tables (either LRU or extendable bucket,
-either with pre-computed signature or "do-sig").
-For each pipeline stage, the described operations are applied to each of the two packets handled by that stage.
-
-.. figure:: img/figure39.*
-
- Bucket Search Pipeline for Key Lookup Operation (Single Key Size Hash
- Tables)
-
-.. table:: Description of the Bucket Search Pipeline Stages (8-byte and 16-byte Key Hash Tables)
-
- +---+---------------------------+-----------------------------------------------------------------------------+
- | # | Stage name | Description |
- | | | |
- +===+===========================+=============================================================================+
- | 0 | Prefetch packet meta-data | #. Select next two packets from the burst of input packets. |
- | | | |
- | | | #. Prefetch packet meta-data containing the key and key signature. |
- | | | |
- +---+---------------------------+-----------------------------------------------------------------------------+
- | 1 | Prefetch table bucket | #. Read the key signature from the packet meta-data (for extendable bucket |
- | | | hash tables) or read the key from the packet meta-data and compute key |
- | | | signature (for LRU tables). |
- | | | |
- | | | #. Identify the bucket ID using the key signature. |
- | | | |
- | | | #. Prefetch the bucket. |
- | | | |
- +---+---------------------------+-----------------------------------------------------------------------------+
- | 2 | Prefetch table data | #. Read the bucket. |
- | | | |
- | | | #. Compare all 4 bucket keys against the input key. |
- | | | |
- | | | #. Report input key as lookup hit only when a match is identified (more |
- | | | than one key match is not possible) |
- | | | |
- | | | #. For LRU tables only, use branchless logic to update the bucket LRU list |
- | | | (the current key becomes the new MRU) only on lookup hit. |
- | | | |
- | | | #. Prefetch the key value (key data) associated with the matched key (to |
- | | | avoid branches, this is done on both lookup hit and miss). |
- | | | |
- +---+---------------------------+-----------------------------------------------------------------------------+
-
-Additional notes:
-
-#. The pipelined version of the bucket search algorithm is executed only if there are at least 5 packets in the burst of input packets.
- If there are less than 5 packets in the burst of input packets, a non-optimized implementation of the bucket search algorithm is executed.
-
-#. For extendable bucket hash tables only,
- once the pipelined version of the bucket search algorithm has been executed for all the packets in the burst of input packets,
- the non-optimized implementation of the bucket search algorithm is also executed for any packets that did not produce a lookup hit,
- but have the bucket in extended state.
- As result of executing the non-optimized version, some of these packets may produce a lookup hit or lookup miss.
- This does not impact the performance of the key lookup operation,
- as the probability of having the bucket in extended state is relatively small.
-
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 758652a492e600b267feba131ddcf943106c8c8b..9dcf86098f0d391a44ee1887ba823a1dd04ac295 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* table: The table library legacy API (functions rte_table_*)
- will be deprecated and subsequently removed in DPDK 24.11 release.
- Before this, the new table library API (functions rte_swx_table_*)
- will gradually transition from experimental to stable status.
-
* port: The port library legacy API (functions rte_port_*)
will be deprecated and subsequently removed in DPDK 24.11 release.
Before this, the new port library API (functions rte_swx_port_*)
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index f7d34aa1ee7fd363f456ecf27effdbfb65efbad5..50b0d3ac06e35b8fd5b86baafd85723d7539cb5d 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -88,6 +88,9 @@ Removed Items
``rte_port_in_action_*`` and ``rte_table_action_*`` functions.
The SWX pipeline API (``rte_swx_pipeline_*``) remains.
+* Removed the legacy table library API (``rte_table_*`` functions).
+ The SWX table API (``rte_swx_table_*``) remains.
+
API Changes
-----------
diff --git a/lib/table/meson.build b/lib/table/meson.build
index e27957fe8995a2ffb3aca4d2b514f0be6b8d6968..620c20e594bba4aea99a1f0115a874334ea701cc 100644
--- a/lib/table/meson.build
+++ b/lib/table/meson.build
@@ -9,42 +9,14 @@ sources = files(
'rte_swx_table_learner.c',
'rte_swx_table_selector.c',
'rte_swx_table_wm.c',
- 'rte_table_acl.c',
- 'rte_table_array.c',
- 'rte_table_hash_cuckoo.c',
- 'rte_table_hash_ext.c',
- 'rte_table_hash_key8.c',
- 'rte_table_hash_key16.c',
- 'rte_table_hash_key32.c',
- 'rte_table_hash_lru.c',
- 'rte_table_lpm.c',
- 'rte_table_lpm_ipv6.c',
- 'rte_table_stub.c',
- 'table_log.c',
)
headers = files(
- 'rte_lru.h',
'rte_swx_hash_func.h',
'rte_swx_table.h',
'rte_swx_table_em.h',
'rte_swx_table_learner.h',
'rte_swx_table_selector.h',
'rte_swx_table_wm.h',
- 'rte_table.h',
- 'rte_table_acl.h',
- 'rte_table_array.h',
- 'rte_table_hash.h',
- 'rte_table_hash_cuckoo.h',
- 'rte_table_hash_func.h',
- 'rte_table_lpm.h',
- 'rte_table_lpm_ipv6.h',
- 'rte_table_stub.h',
-)
-deps += ['mbuf', 'port', 'lpm', 'hash', 'acl']
-
-indirect_headers += files(
- 'rte_lru_arm64.h',
- 'rte_lru_x86.h',
- 'rte_table_hash_func_arm64.h',
)
+deps += ['mbuf', 'hash', 'acl']
diff --git a/lib/table/rte_lru.h b/lib/table/rte_lru.h
deleted file mode 100644
index 1436425e162b9212a1b192f13414d1b372a80413..0000000000000000000000000000000000000000
--- a/lib/table/rte_lru.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_LRU_H__
-#define __INCLUDE_RTE_LRU_H__
-
-#include <rte_config.h>
-#ifdef RTE_ARCH_X86_64
-#include "rte_lru_x86.h"
-#elif defined(RTE_ARCH_ARM64)
-#include "rte_lru_arm64.h"
-#else
-#undef RTE_TABLE_HASH_LRU_STRATEGY
-#define RTE_TABLE_HASH_LRU_STRATEGY 1
-#endif
-
-#if RTE_TABLE_HASH_LRU_STRATEGY == 0
-
-#define lru_init(bucket) \
-do \
- bucket = bucket; \
-while (0)
-
-#define lru_pos(bucket) (bucket->lru_list & 0xFFFFLLU)
-
-#define lru_update(bucket, mru_val) \
-do { \
- bucket = bucket; \
- mru_val = mru_val; \
-} while (0)
-
-#elif RTE_TABLE_HASH_LRU_STRATEGY == 1
-
-#define lru_init(bucket) \
-do \
- bucket->lru_list = 0x0000000100020003LLU; \
-while (0)
-
-#define lru_pos(bucket) (bucket->lru_list & 0xFFFFLLU)
-
-#define lru_update(bucket, mru_val) \
-do { \
- uint64_t _x, _pos, _x0, _x1, _x2, _mask; \
- \
- _x = bucket->lru_list; \
- \
- _pos = 4; \
- if ((_x >> 48) == ((uint64_t) mru_val)) \
- _pos = 3; \
- \
- if (((_x >> 32) & 0xFFFFLLU) == ((uint64_t) mru_val)) \
- _pos = 2; \
- \
- if (((_x >> 16) & 0xFFFFLLU) == ((uint64_t) mru_val)) \
- _pos = 1; \
- \
- if ((_x & 0xFFFFLLU) == ((uint64_t) mru_val)) \
- _pos = 0; \
- \
- \
- _pos <<= 4; \
- _mask = (~0LLU) << _pos; \
- _x0 = _x & (~_mask); \
- _x1 = (_x >> 16) & _mask; \
- _x2 = (_x << (48 - _pos)) & (0xFFFFLLU << 48); \
- _x = _x0 | _x1 | _x2; \
- \
- if (_pos != 64) \
- bucket->lru_list = _x; \
-} while (0)
-
-#elif (RTE_TABLE_HASH_LRU_STRATEGY == 2) || (RTE_TABLE_HASH_LRU_STRATEGY == 3)
-
-/**
- * These strategies are implemented in architecture specific header files.
- */
-
-#else
-
-#error "Incorrect value for RTE_TABLE_HASH_LRU_STRATEGY"
-
-#endif
-
-#endif
diff --git a/lib/table/rte_lru_arm64.h b/lib/table/rte_lru_arm64.h
deleted file mode 100644
index 817b791b6e47866c788b35ef66edb40df112796e..0000000000000000000000000000000000000000
--- a/lib/table/rte_lru_arm64.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017 Cavium, Inc
- */
-
-#ifndef __RTE_LRU_ARM64_H__
-#define __RTE_LRU_ARM64_H__
-
-#include <stdint.h>
-#include <rte_vect.h>
-#include <rte_bitops.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef RTE_TABLE_HASH_LRU_STRATEGY
-#ifdef __ARM_NEON
-#define RTE_TABLE_HASH_LRU_STRATEGY 3
-#else /* if no NEON, use simple scalar version */
-#define RTE_TABLE_HASH_LRU_STRATEGY 1
-#endif
-#endif
-
-#if RTE_TABLE_HASH_LRU_STRATEGY == 3
-
-#define lru_init(bucket) \
- { bucket->lru_list = ~0LLU; }
-
-static inline int
-f_lru_pos(uint64_t lru_list)
-{
- /* Compare the vector to zero vector */
- uint16x4_t lru_vec = vld1_u16((uint16_t *)&lru_list);
- uint16x4_t min_vec = vmov_n_u16(vminv_u16(lru_vec));
- uint64_t mask = vget_lane_u64(vreinterpret_u64_u16(
- vceq_u16(min_vec, lru_vec)), 0);
- return rte_clz64(mask) >> 4;
-}
-#define lru_pos(bucket) f_lru_pos(bucket->lru_list)
-
-#define lru_update(bucket, mru_val) \
-do { \
- const uint64_t _orvals[] = {0xFFFFLLU, 0xFFFFLLU << 16, \
- 0xFFFFLLU << 32, 0xFFFFLLU << 48, 0LLU}; \
- const uint64_t _decs[] = {0x1000100010001LLU, 0}; \
- uint64x1_t _lru = vdup_n_u64(bucket->lru_list); \
- uint64x1_t _vdec = vdup_n_u64(_decs[mru_val>>2]); \
- bucket->lru_list = vget_lane_u64(vreinterpret_u64_u16( \
- vsub_u16(vreinterpret_u16_u64(_lru), \
- vreinterpret_u16_u64(_vdec))), \
- 0); \
- bucket->lru_list |= _orvals[mru_val]; \
-} while (0)
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/rte_lru_x86.h b/lib/table/rte_lru_x86.h
deleted file mode 100644
index de7451365347b512e2c4e8506d698eb8ac138430..0000000000000000000000000000000000000000
--- a/lib/table/rte_lru_x86.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_LRU_X86_H__
-#define __INCLUDE_RTE_LRU_X86_H__
-
-#include <stdint.h>
-
-#include <rte_config.h>
-#include <rte_common.h>
-
-#ifndef RTE_TABLE_HASH_LRU_STRATEGY
-#define RTE_TABLE_HASH_LRU_STRATEGY 2
-#endif
-
-#if RTE_TABLE_HASH_LRU_STRATEGY == 2
-
-#if RTE_CC_IS_GNU
-#include <x86intrin.h>
-#else
-#include <emmintrin.h>
-#include <smmintrin.h>
-#include <xmmintrin.h>
-#endif
-
-#define lru_init(bucket) \
- { bucket->lru_list = 0x0000000100020003LLU; }
-
-#define lru_pos(bucket) (bucket->lru_list & 0xFFFFLLU)
-
-#define lru_update(bucket, mru_val) \
-do { \
- /* set up the masks for all possible shuffles, depends on pos */\
- static uint64_t masks[10] = { \
- /* Shuffle order; Make Zero (see _mm_shuffle_epi8 manual) */\
- 0x0100070605040302, 0x8080808080808080, \
- 0x0302070605040100, 0x8080808080808080, \
- 0x0504070603020100, 0x8080808080808080, \
- 0x0706050403020100, 0x8080808080808080, \
- 0x0706050403020100, 0x8080808080808080}; \
- /* load up one register with repeats of mru-val */ \
- uint64_t mru2 = mru_val; \
- uint64_t mru3 = mru2 | (mru2 << 16); \
- uint64_t lru = bucket->lru_list; \
- /* XOR to cause the word we're looking for to go to zero */ \
- uint64_t mru = lru ^ ((mru3 << 32) | mru3); \
- __m128i c = _mm_cvtsi64_si128(mru); \
- __m128i b = _mm_cvtsi64_si128(lru); \
- /* Find the minimum value (first zero word, if it's in there) */\
- __m128i d = _mm_minpos_epu16(c); \
- /* Second word is the index to found word (first word is the value) */\
- unsigned int _pos = _mm_extract_epi16(d, 1); \
- /* move the recently used location to top of list */ \
- __m128i k = _mm_shuffle_epi8(b, *((__m128i *) &masks[2 * _pos]));\
- /* Finally, update the original list with the reordered data */ \
- bucket->lru_list = _mm_extract_epi64(k, 0); \
- /* Phwew! */ \
-} while (0)
-
-#elif RTE_TABLE_HASH_LRU_STRATEGY == 3
-
-#if RTE_CC_IS_GNU
-#include <x86intrin.h>
-#else
-#include <emmintrin.h>
-#include <smmintrin.h>
-#include <xmmintrin.h>
-#endif
-
-#define lru_init(bucket) \
- { bucket->lru_list = ~0LLU; }
-
-static inline int
-f_lru_pos(uint64_t lru_list)
-{
- __m128i lst = _mm_set_epi64x((uint64_t)-1, lru_list);
- __m128i min = _mm_minpos_epu16(lst);
- return _mm_extract_epi16(min, 1);
-}
-#define lru_pos(bucket) f_lru_pos(bucket->lru_list)
-
-#define lru_update(bucket, mru_val) \
-do { \
- const uint64_t orvals[] = {0xFFFFLLU, 0xFFFFLLU << 16, \
- 0xFFFFLLU << 32, 0xFFFFLLU << 48, 0LLU}; \
- const uint64_t decs[] = {0x1000100010001LLU, 0}; \
- __m128i lru = _mm_cvtsi64_si128(bucket->lru_list); \
- __m128i vdec = _mm_cvtsi64_si128(decs[mru_val>>2]); \
- lru = _mm_subs_epu16(lru, vdec); \
- bucket->lru_list = _mm_extract_epi64(lru, 0) | orvals[mru_val]; \
-} while (0)
-
-#endif
-
-#endif
diff --git a/lib/table/rte_table.h b/lib/table/rte_table.h
deleted file mode 100644
index 2743070b3200ffff1f346bbc623648c6469e828e..0000000000000000000000000000000000000000
--- a/lib/table/rte_table.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_H__
-#define __INCLUDE_RTE_TABLE_H__
-
-/**
- * @file
- * RTE Table
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard interface to implement different types of lookup tables for data
- * plane processing.
- *
- * Virtually any search algorithm that can uniquely associate data to a lookup
- * key can be fitted under this lookup table abstraction. For the flow table
- * use-case, the lookup key is an n-tuple of packet fields that uniquely
- * identifies a traffic flow, while data represents actions and action
- * meta-data associated with the same traffic flow.
- */
-
-#include <stdint.h>
-#include <rte_port.h>
-
-struct rte_mbuf;
-
-/** Lookup table statistics */
-struct rte_table_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_lookup_miss;
-};
-
-/**
- * Lookup table create
- *
- * @param params
- * Parameters for lookup table creation. The underlying data structure is
- * different for each lookup table type.
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @param entry_size
- * Data size of each lookup table entry (measured in bytes)
- * @return
- * Handle to lookup table instance
- */
-typedef void* (*rte_table_op_create)(void *params, int socket_id,
- uint32_t entry_size);
-
-/**
- * Lookup table free
- *
- * @param table
- * Handle to lookup table instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_table_op_free)(void *table);
-
-/**
- * Lookup table entry add
- *
- * @param table
- * Handle to lookup table instance
- * @param key
- * Lookup key
- * @param entry
- * Data to be associated with the current key. This parameter has to point to
- * a valid memory buffer where the first entry_size bytes (table create
- * parameter) are populated with the data.
- * @param key_found
- * After successful invocation, *key_found is set to a value different than 0
- * if the current key is already present in the table and to 0 if not. This
- * pointer has to be set to a valid memory location before the table entry add
- * function is called.
- * @param entry_ptr
- * After successful invocation, *entry_ptr stores the handle to the table
- * entry containing the data associated with the current key. This handle can
- * be used to perform further read-write accesses to this entry. This handle
- * is valid until the key is deleted from the table or the same key is
- * re-added to the table, typically to associate it with different data. This
- * pointer has to be set to a valid memory location before the function is
- * called.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_table_op_entry_add)(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr);
-
-/**
- * Lookup table entry delete
- *
- * @param table
- * Handle to lookup table instance
- * @param key
- * Lookup key
- * @param key_found
- * After successful invocation, *key_found is set to a value different than 0
- * if the current key was present in the table before the delete operation
- * was performed and to 0 if not. This pointer has to be set to a valid
- * memory location before the table entry delete function is called.
- * @param entry
- * After successful invocation, if the key is found in the table (*key found
- * is different than 0 after function call is completed) and entry points to
- * a valid buffer (entry is set to a value different than NULL before the
- * function is called), then the first entry_size bytes (table create
- * parameter) in *entry store a copy of table entry that contained the data
- * associated with the current key before the key was deleted.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_table_op_entry_delete)(
- void *table,
- void *key,
- int *key_found,
- void *entry);
-
-/**
- * Lookup table entry add bulk
- *
- * @param table
- * Handle to lookup table instance
- * @param keys
- * Array containing lookup keys
- * @param entries
- * Array containing data to be associated with each key. Every item in the
- * array has to point to a valid memory buffer where the first entry_size
- * bytes (table create parameter) are populated with the data.
- * @param n_keys
- * Number of keys to add
- * @param key_found
- * After successful invocation, key_found for every item in the array is set
- * to a value different than 0 if the current key is already present in the
- * table and to 0 if not. This pointer has to be set to a valid memory
- * location before the table entry add function is called.
- * @param entries_ptr
- * After successful invocation, array *entries_ptr stores the handle to the
- * table entry containing the data associated with every key. This handle can
- * be used to perform further read-write accesses to this entry. This handle
- * is valid until the key is deleted from the table or the same key is
- * re-added to the table, typically to associate it with different data. This
- * pointer has to be set to a valid memory location before the function is
- * called.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_table_op_entry_add_bulk)(
- void *table,
- void **keys,
- void **entries,
- uint32_t n_keys,
- int *key_found,
- void **entries_ptr);
-
-/**
- * Lookup table entry delete bulk
- *
- * @param table
- * Handle to lookup table instance
- * @param keys
- * Array containing lookup keys
- * @param n_keys
- * Number of keys to delete
- * @param key_found
- * After successful invocation, key_found for every item in the array is set
- * to a value different than 0if the current key was present in the table
- * before the delete operation was performed and to 0 if not. This pointer
- * has to be set to a valid memory location before the table entry delete
- * function is called.
- * @param entries
- * If entries pointer is NULL, this pointer is ignored for every entry found.
- * Else, after successful invocation, if specific key is found in the table
- * (key_found is different than 0 for this item after function call is
- * completed) and item of entry array points to a valid buffer (entry is set
- * to a value different than NULL before the function is called), then the
- * first entry_size bytes (table create parameter) in *entry store a copy of
- * table entry that contained the data associated with the current key before
- * the key was deleted.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_table_op_entry_delete_bulk)(
- void *table,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- void **entries);
-
-/**
- * Lookup table lookup
- *
- * @param table
- * Handle to lookup table instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array does not point to a valid
- * packet, therefore it will not be accessed.
- * @param lookup_hit_mask
- * Once the table lookup operation is completed, this 64-bit bitmask
- * specifies which of the valid packets in the input burst resulted in lookup
- * hit. For each valid input packet (pkts_mask bit n is set), the following
- * are true on lookup hit: lookup_hit_mask bit n is set, element n of entries
- * array is valid and it points to the lookup table entry that was hit. For
- * each valid input packet (pkts_mask bit n is set), the following are true
- * on lookup miss: lookup_hit_mask bit n is not set and element n of entries
- * array is not valid.
- * @param entries
- * Once the table lookup operation is completed, this array provides the
- * lookup table entries that were hit, as described above. It is required
- * that this array is always pre-allocated by the caller of this function
- * with exactly 64 elements. The implementation is allowed to speculatively
- * modify the elements of this array, so elements marked as invalid in
- * lookup_hit_mask once the table lookup operation is completed might have
- * been modified by this function.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_table_op_lookup)(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries);
-
-/**
- * Lookup table stats read
- *
- * @param table
- * Handle to lookup table instance
- * @param stats
- * Handle to table stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_table_op_stats_read)(
- void *table,
- struct rte_table_stats *stats,
- int clear);
-
-/** Lookup table interface defining the lookup table operation */
-struct rte_table_ops {
- rte_table_op_create f_create; /**< Create */
- rte_table_op_free f_free; /**< Free */
- rte_table_op_entry_add f_add; /**< Entry add */
- rte_table_op_entry_delete f_delete; /**< Entry delete */
- rte_table_op_entry_add_bulk f_add_bulk; /**< Add entry bulk */
- rte_table_op_entry_delete_bulk f_delete_bulk; /**< Delete entry bulk */
- rte_table_op_lookup f_lookup; /**< Lookup */
- rte_table_op_stats_read f_stats; /**< Stats */
-};
-
-#endif
diff --git a/lib/table/rte_table_acl.c b/lib/table/rte_table_acl.c
deleted file mode 100644
index 74fa0145d890638e17fbb862e67245a3caf55416..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_acl.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_acl.h"
-
-#include "table_log.h"
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_ACL_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_ACL_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_ACL_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_ACL_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-struct rte_table_acl {
- struct rte_table_stats stats;
-
- /* Low-level ACL table */
- char name[2][RTE_ACL_NAMESIZE];
- struct rte_acl_param acl_params; /* for creating low level acl table */
- struct rte_acl_config cfg; /* Holds the field definitions (metadata) */
- struct rte_acl_ctx *ctx;
- uint32_t name_id;
-
- /* Input parameters */
- uint32_t n_rules;
- uint32_t entry_size;
-
- /* Internal tables */
- uint8_t *action_table;
- struct rte_acl_rule **acl_rule_list; /* Array of pointers to rules */
- uint8_t *acl_rule_memory; /* Memory to store the rules */
-
- /* Memory to store the action table and stack of free entries */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-
-static void *
-rte_table_acl_create(
- void *params,
- int socket_id,
- uint32_t entry_size)
-{
- struct rte_table_acl_params *p = params;
- struct rte_table_acl *acl;
- uint32_t action_table_size, acl_rule_list_size, acl_rule_memory_size;
- uint32_t total_size;
-
- RTE_BUILD_BUG_ON(((sizeof(struct rte_table_acl) % RTE_CACHE_LINE_SIZE)
- != 0));
-
- /* Check input parameters */
- if (p == NULL) {
- TABLE_LOG(ERR, "%s: Invalid value for params", __func__);
- return NULL;
- }
- if (p->name == NULL) {
- TABLE_LOG(ERR, "%s: Invalid value for name", __func__);
- return NULL;
- }
- if (p->n_rules == 0) {
- TABLE_LOG(ERR, "%s: Invalid value for n_rules",
- __func__);
- return NULL;
- }
- if ((p->n_rule_fields == 0) ||
- (p->n_rule_fields > RTE_ACL_MAX_FIELDS)) {
- TABLE_LOG(ERR, "%s: Invalid value for n_rule_fields",
- __func__);
- return NULL;
- }
-
- entry_size = RTE_ALIGN(entry_size, sizeof(uint64_t));
-
- /* Memory allocation */
- action_table_size = RTE_CACHE_LINE_ROUNDUP(p->n_rules * entry_size);
- acl_rule_list_size =
- RTE_CACHE_LINE_ROUNDUP(p->n_rules * sizeof(struct rte_acl_rule *));
- acl_rule_memory_size = RTE_CACHE_LINE_ROUNDUP(p->n_rules *
- RTE_ACL_RULE_SZ(p->n_rule_fields));
- total_size = sizeof(struct rte_table_acl) + action_table_size +
- acl_rule_list_size + acl_rule_memory_size;
-
- acl = rte_zmalloc_socket("TABLE", total_size, RTE_CACHE_LINE_SIZE,
- socket_id);
- if (acl == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %u bytes for ACL table",
- __func__, total_size);
- return NULL;
- }
-
- acl->action_table = &acl->memory[0];
- acl->acl_rule_list =
- (struct rte_acl_rule **) &acl->memory[action_table_size];
- acl->acl_rule_memory = (uint8_t *)
- &acl->memory[action_table_size + acl_rule_list_size];
-
- /* Initialization of internal fields */
- snprintf(acl->name[0], RTE_ACL_NAMESIZE, "%s_a", p->name);
- snprintf(acl->name[1], RTE_ACL_NAMESIZE, "%s_b", p->name);
- acl->name_id = 1;
-
- acl->acl_params.name = acl->name[acl->name_id];
- acl->acl_params.socket_id = socket_id;
- acl->acl_params.rule_size = RTE_ACL_RULE_SZ(p->n_rule_fields);
- acl->acl_params.max_rule_num = p->n_rules;
-
- acl->cfg.num_categories = 1;
- acl->cfg.num_fields = p->n_rule_fields;
- memcpy(&acl->cfg.defs[0], &p->field_format[0],
- p->n_rule_fields * sizeof(struct rte_acl_field_def));
-
- acl->ctx = NULL;
-
- acl->n_rules = p->n_rules;
- acl->entry_size = entry_size;
-
- return acl;
-}
-
-static int
-rte_table_acl_free(void *table)
-{
- struct rte_table_acl *acl = table;
-
- /* Check input parameters */
- if (table == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free previously allocated resources */
- rte_acl_free(acl->ctx);
-
- rte_free(acl);
-
- return 0;
-}
-
-RTE_ACL_RULE_DEF(rte_pipeline_acl_rule, RTE_ACL_MAX_FIELDS);
-
-static int
-rte_table_acl_build(struct rte_table_acl *acl, struct rte_acl_ctx **acl_ctx)
-{
- struct rte_acl_ctx *ctx = NULL;
- uint32_t n_rules, i;
- int status;
-
- /* Create low level ACL table */
- ctx = rte_acl_create(&acl->acl_params);
- if (ctx == NULL) {
- TABLE_LOG(ERR, "%s: Cannot create low level ACL table",
- __func__);
- return -1;
- }
-
- /* Add rules to low level ACL table */
- n_rules = 0;
- for (i = 1; i < acl->n_rules; i++) {
- if (acl->acl_rule_list[i] != NULL) {
- status = rte_acl_add_rules(ctx, acl->acl_rule_list[i],
- 1);
- if (status != 0) {
- TABLE_LOG(ERR,
- "%s: Cannot add rule to low level ACL table",
- __func__);
- rte_acl_free(ctx);
- return -1;
- }
-
- n_rules++;
- }
- }
-
- if (n_rules == 0) {
- rte_acl_free(ctx);
- *acl_ctx = NULL;
- return 0;
- }
-
- /* Build low level ACl table */
- status = rte_acl_build(ctx, &acl->cfg);
- if (status != 0) {
- TABLE_LOG(ERR,
- "%s: Cannot build the low level ACL table",
- __func__);
- rte_acl_free(ctx);
- return -1;
- }
-
- *acl_ctx = ctx;
- return 0;
-}
-
-static int
-rte_table_acl_entry_add(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_acl *acl = table;
- struct rte_table_acl_rule_add_params *rule =
- key;
- struct rte_pipeline_acl_rule acl_rule;
- struct rte_acl_rule *rule_location;
- struct rte_acl_ctx *ctx;
- uint32_t free_pos, free_pos_valid, i;
- int status;
-
- /* Check input parameters */
- if (table == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (key == NULL) {
- TABLE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
- if (entry == NULL) {
- TABLE_LOG(ERR, "%s: entry parameter is NULL", __func__);
- return -EINVAL;
- }
- if (key_found == NULL) {
- TABLE_LOG(ERR, "%s: key_found parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (entry_ptr == NULL) {
- TABLE_LOG(ERR, "%s: entry_ptr parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (rule->priority > RTE_ACL_MAX_PRIORITY) {
- TABLE_LOG(ERR, "%s: Priority is too high", __func__);
- return -EINVAL;
- }
-
- /* Setup rule data structure */
- memset(&acl_rule, 0, sizeof(acl_rule));
- acl_rule.data.category_mask = 1;
- acl_rule.data.priority = RTE_ACL_MAX_PRIORITY - rule->priority;
- acl_rule.data.userdata = 0; /* To be set up later */
- memcpy(&acl_rule.field[0],
- &rule->field_value[0],
- acl->cfg.num_fields * sizeof(struct rte_acl_field));
-
- /* Look to see if the rule exists already in the table */
- free_pos = 0;
- free_pos_valid = 0;
- for (i = 1; i < acl->n_rules; i++) {
- if (acl->acl_rule_list[i] == NULL) {
- if (free_pos_valid == 0) {
- free_pos = i;
- free_pos_valid = 1;
- }
-
- continue;
- }
-
- /* Compare the key fields */
- status = memcmp(&acl->acl_rule_list[i]->field[0],
- &rule->field_value[0],
- acl->cfg.num_fields * sizeof(struct rte_acl_field));
-
- /* Rule found: update data associated with the rule */
- if (status == 0) {
- *key_found = 1;
- *entry_ptr = &acl->memory[i * acl->entry_size];
- memcpy(*entry_ptr, entry, acl->entry_size);
-
- return 0;
- }
- }
-
- /* Return if max rules */
- if (free_pos_valid == 0) {
- TABLE_LOG(ERR, "%s: Max number of rules reached",
- __func__);
- return -ENOSPC;
- }
-
- /* Add the new rule to the rule set */
- acl_rule.data.userdata = free_pos;
- rule_location = (struct rte_acl_rule *)
- &acl->acl_rule_memory[free_pos * acl->acl_params.rule_size];
- memcpy(rule_location, &acl_rule, acl->acl_params.rule_size);
- acl->acl_rule_list[free_pos] = rule_location;
-
- /* Build low level ACL table */
- acl->name_id ^= 1;
- acl->acl_params.name = acl->name[acl->name_id];
- status = rte_table_acl_build(acl, &ctx);
- if (status != 0) {
- /* Roll back changes */
- acl->acl_rule_list[free_pos] = NULL;
- acl->name_id ^= 1;
-
- return -EINVAL;
- }
-
- /* Commit changes */
- rte_acl_free(acl->ctx);
- acl->ctx = ctx;
- *key_found = 0;
- *entry_ptr = &acl->memory[free_pos * acl->entry_size];
- memcpy(*entry_ptr, entry, acl->entry_size);
-
- return 0;
-}
-
-static int
-rte_table_acl_entry_delete(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_acl *acl = table;
- struct rte_table_acl_rule_delete_params *rule =
- key;
- struct rte_acl_rule *deleted_rule = NULL;
- struct rte_acl_ctx *ctx;
- uint32_t pos, pos_valid, i;
- int status;
-
- /* Check input parameters */
- if (table == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (key == NULL) {
- TABLE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
- if (key_found == NULL) {
- TABLE_LOG(ERR, "%s: key_found parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- /* Look for the rule in the table */
- pos = 0;
- pos_valid = 0;
- for (i = 1; i < acl->n_rules; i++) {
- if (acl->acl_rule_list[i] != NULL) {
- /* Compare the key fields */
- status = memcmp(&acl->acl_rule_list[i]->field[0],
- &rule->field_value[0], acl->cfg.num_fields *
- sizeof(struct rte_acl_field));
-
- /* Rule found: remove from table */
- if (status == 0) {
- pos = i;
- pos_valid = 1;
-
- deleted_rule = acl->acl_rule_list[i];
- acl->acl_rule_list[i] = NULL;
- }
- }
- }
-
- /* Return if rule not found */
- if (pos_valid == 0) {
- *key_found = 0;
- return 0;
- }
-
- /* Build low level ACL table */
- acl->name_id ^= 1;
- acl->acl_params.name = acl->name[acl->name_id];
- status = rte_table_acl_build(acl, &ctx);
- if (status != 0) {
- /* Roll back changes */
- acl->acl_rule_list[pos] = deleted_rule;
- acl->name_id ^= 1;
-
- return -EINVAL;
- }
-
- /* Commit changes */
- rte_acl_free(acl->ctx);
-
- acl->ctx = ctx;
- *key_found = 1;
- if (entry != NULL)
- memcpy(entry, &acl->memory[pos * acl->entry_size],
- acl->entry_size);
-
- return 0;
-}
-
-static int
-rte_table_acl_entry_add_bulk(
- void *table,
- void **keys,
- void **entries,
- uint32_t n_keys,
- int *key_found,
- void **entries_ptr)
-{
- struct rte_table_acl *acl = table;
- struct rte_acl_ctx *ctx;
- uint32_t rule_pos[n_keys];
- uint32_t i;
- int err = 0, build = 0;
- int status;
-
- /* Check input parameters */
- if (table == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (keys == NULL) {
- TABLE_LOG(ERR, "%s: keys parameter is NULL", __func__);
- return -EINVAL;
- }
- if (entries == NULL) {
- TABLE_LOG(ERR, "%s: entries parameter is NULL", __func__);
- return -EINVAL;
- }
- if (n_keys == 0) {
- TABLE_LOG(ERR, "%s: 0 rules to add", __func__);
- return -EINVAL;
- }
- if (key_found == NULL) {
- TABLE_LOG(ERR, "%s: key_found parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (entries_ptr == NULL) {
- TABLE_LOG(ERR, "%s: entries_ptr parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- /* Check input parameters in arrays */
- for (i = 0; i < n_keys; i++) {
- struct rte_table_acl_rule_add_params *rule;
-
- if (keys[i] == NULL) {
- TABLE_LOG(ERR, "%s: keys[%" PRIu32 "] parameter is NULL",
- __func__, i);
- return -EINVAL;
- }
-
- if (entries[i] == NULL) {
- TABLE_LOG(ERR, "%s: entries[%" PRIu32 "] parameter is NULL",
- __func__, i);
- return -EINVAL;
- }
-
- rule = keys[i];
- if (rule->priority > RTE_ACL_MAX_PRIORITY) {
- TABLE_LOG(ERR, "%s: Priority is too high", __func__);
- return -EINVAL;
- }
- }
-
- memset(rule_pos, 0, n_keys * sizeof(uint32_t));
- memset(key_found, 0, n_keys * sizeof(int));
- for (i = 0; i < n_keys; i++) {
- struct rte_table_acl_rule_add_params *rule =
- keys[i];
- struct rte_pipeline_acl_rule acl_rule;
- struct rte_acl_rule *rule_location;
- uint32_t free_pos, free_pos_valid, j;
-
- /* Setup rule data structure */
- memset(&acl_rule, 0, sizeof(acl_rule));
- acl_rule.data.category_mask = 1;
- acl_rule.data.priority = RTE_ACL_MAX_PRIORITY - rule->priority;
- acl_rule.data.userdata = 0; /* To be set up later */
- memcpy(&acl_rule.field[0],
- &rule->field_value[0],
- acl->cfg.num_fields * sizeof(struct rte_acl_field));
-
- /* Look to see if the rule exists already in the table */
- free_pos = 0;
- free_pos_valid = 0;
- for (j = 1; j < acl->n_rules; j++) {
- if (acl->acl_rule_list[j] == NULL) {
- if (free_pos_valid == 0) {
- free_pos = j;
- free_pos_valid = 1;
- }
-
- continue;
- }
-
- /* Compare the key fields */
- status = memcmp(&acl->acl_rule_list[j]->field[0],
- &rule->field_value[0],
- acl->cfg.num_fields * sizeof(struct rte_acl_field));
-
- /* Rule found: update data associated with the rule */
- if (status == 0) {
- key_found[i] = 1;
- entries_ptr[i] = &acl->memory[j * acl->entry_size];
- memcpy(entries_ptr[i], entries[i], acl->entry_size);
-
- break;
- }
- }
-
- /* Key already in the table */
- if (key_found[i] != 0)
- continue;
-
- /* Maximum number of rules reached */
- if (free_pos_valid == 0) {
- err = 1;
- break;
- }
-
- /* Add the new rule to the rule set */
- acl_rule.data.userdata = free_pos;
- rule_location = (struct rte_acl_rule *)
- &acl->acl_rule_memory[free_pos * acl->acl_params.rule_size];
- memcpy(rule_location, &acl_rule, acl->acl_params.rule_size);
- acl->acl_rule_list[free_pos] = rule_location;
- rule_pos[i] = free_pos;
- build = 1;
- }
-
- if (err != 0) {
- for (i = 0; i < n_keys; i++) {
- if (rule_pos[i] == 0)
- continue;
-
- acl->acl_rule_list[rule_pos[i]] = NULL;
- }
-
- return -ENOSPC;
- }
-
- if (build == 0)
- return 0;
-
- /* Build low level ACL table */
- acl->name_id ^= 1;
- acl->acl_params.name = acl->name[acl->name_id];
- status = rte_table_acl_build(acl, &ctx);
- if (status != 0) {
- /* Roll back changes */
- for (i = 0; i < n_keys; i++) {
- if (rule_pos[i] == 0)
- continue;
-
- acl->acl_rule_list[rule_pos[i]] = NULL;
- }
- acl->name_id ^= 1;
-
- return -EINVAL;
- }
-
- /* Commit changes */
- rte_acl_free(acl->ctx);
- acl->ctx = ctx;
-
- for (i = 0; i < n_keys; i++) {
- if (rule_pos[i] == 0)
- continue;
-
- key_found[i] = 0;
- entries_ptr[i] = &acl->memory[rule_pos[i] * acl->entry_size];
- memcpy(entries_ptr[i], entries[i], acl->entry_size);
- }
-
- return 0;
-}
-
-static int
-rte_table_acl_entry_delete_bulk(
- void *table,
- void **keys,
- uint32_t n_keys,
- int *key_found,
- void **entries)
-{
- struct rte_table_acl *acl = table;
- struct rte_acl_rule *deleted_rules[n_keys];
- uint32_t rule_pos[n_keys];
- struct rte_acl_ctx *ctx;
- uint32_t i;
- int status;
- int build = 0;
-
- /* Check input parameters */
- if (table == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (keys == NULL) {
- TABLE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
- if (n_keys == 0) {
- TABLE_LOG(ERR, "%s: 0 rules to delete", __func__);
- return -EINVAL;
- }
- if (key_found == NULL) {
- TABLE_LOG(ERR, "%s: key_found parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- for (i = 0; i < n_keys; i++) {
- if (keys[i] == NULL) {
- TABLE_LOG(ERR, "%s: keys[%" PRIu32 "] parameter is NULL",
- __func__, i);
- return -EINVAL;
- }
- }
-
- memset(deleted_rules, 0, n_keys * sizeof(struct rte_acl_rule *));
- memset(rule_pos, 0, n_keys * sizeof(uint32_t));
- for (i = 0; i < n_keys; i++) {
- struct rte_table_acl_rule_delete_params *rule =
- keys[i];
- uint32_t pos_valid, j;
-
- /* Look for the rule in the table */
- pos_valid = 0;
- for (j = 1; j < acl->n_rules; j++) {
- if (acl->acl_rule_list[j] == NULL)
- continue;
-
- /* Compare the key fields */
- status = memcmp(&acl->acl_rule_list[j]->field[0],
- &rule->field_value[0],
- acl->cfg.num_fields * sizeof(struct rte_acl_field));
-
- /* Rule found: remove from table */
- if (status == 0) {
- pos_valid = 1;
-
- deleted_rules[i] = acl->acl_rule_list[j];
- acl->acl_rule_list[j] = NULL;
- rule_pos[i] = j;
-
- build = 1;
- }
- }
-
- if (pos_valid == 0) {
- key_found[i] = 0;
- continue;
- }
- }
-
- /* Return if no changes to acl table */
- if (build == 0) {
- return 0;
- }
-
- /* Build low level ACL table */
- acl->name_id ^= 1;
- acl->acl_params.name = acl->name[acl->name_id];
- status = rte_table_acl_build(acl, &ctx);
- if (status != 0) {
- /* Roll back changes */
- for (i = 0; i < n_keys; i++) {
- if (rule_pos[i] == 0)
- continue;
-
- acl->acl_rule_list[rule_pos[i]] = deleted_rules[i];
- }
-
- acl->name_id ^= 1;
-
- return -EINVAL;
- }
-
- /* Commit changes */
- rte_acl_free(acl->ctx);
-
- acl->ctx = ctx;
- for (i = 0; i < n_keys; i++) {
- if (rule_pos[i] == 0)
- continue;
-
- key_found[i] = 1;
- if (entries != NULL && entries[i] != NULL)
- memcpy(entries[i], &acl->memory[rule_pos[i] * acl->entry_size],
- acl->entry_size);
- }
-
- return 0;
-}
-
-static int
-rte_table_acl_lookup(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_acl *acl = (struct rte_table_acl *) table;
- const uint8_t *pkts_data[RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t results[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t pkts_out_mask;
- uint32_t n_pkts, i, j;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_ACL_STATS_PKTS_IN_ADD(acl, n_pkts_in);
-
- /* Input conversion */
- for (i = 0, j = 0; i < (uint32_t)(RTE_PORT_IN_BURST_SIZE_MAX -
- rte_clz64(pkts_mask)); i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if (pkt_mask & pkts_mask) {
- pkts_data[j] = rte_pktmbuf_mtod(pkts[i], uint8_t *);
- j++;
- }
- }
- n_pkts = j;
-
- /* Low-level ACL table lookup */
- if (acl->ctx != NULL)
- rte_acl_classify(acl->ctx, pkts_data, results, n_pkts, 1);
- else
- n_pkts = 0;
-
- /* Output conversion */
- pkts_out_mask = 0;
- for (i = 0; i < n_pkts; i++) {
- uint32_t action_table_pos = results[i];
- uint32_t pkt_pos = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_pos;
-
- pkts_mask &= ~pkt_mask;
-
- if (action_table_pos != 0) {
- pkts_out_mask |= pkt_mask;
- entries[pkt_pos] = (void *)
- &acl->memory[action_table_pos *
- acl->entry_size];
- rte_prefetch0(entries[pkt_pos]);
- }
- }
-
- *lookup_hit_mask = pkts_out_mask;
- RTE_TABLE_ACL_STATS_PKTS_LOOKUP_MISS(acl, n_pkts_in - rte_popcount64(pkts_out_mask));
-
- return 0;
-}
-
-static int
-rte_table_acl_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_acl *acl = table;
-
- if (stats != NULL)
- memcpy(stats, &acl->stats, sizeof(acl->stats));
-
- if (clear)
- memset(&acl->stats, 0, sizeof(acl->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_acl_ops)
-struct rte_table_ops rte_table_acl_ops = {
- .f_create = rte_table_acl_create,
- .f_free = rte_table_acl_free,
- .f_add = rte_table_acl_entry_add,
- .f_delete = rte_table_acl_entry_delete,
- .f_add_bulk = rte_table_acl_entry_add_bulk,
- .f_delete_bulk = rte_table_acl_entry_delete_bulk,
- .f_lookup = rte_table_acl_lookup,
- .f_stats = rte_table_acl_stats_read,
-};
diff --git a/lib/table/rte_table_acl.h b/lib/table/rte_table_acl.h
deleted file mode 100644
index 61af7b88e4c3473ef6cdf1b0273e11af5628706d..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_acl.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_ACL_H__
-#define __INCLUDE_RTE_TABLE_ACL_H__
-
-/**
- * @file
- * RTE Table ACL
- *
- * This table uses the Access Control List (ACL) algorithm to uniquely
- * associate data to lookup keys.
- *
- * Use-cases: Firewall rule database, etc.
- */
-
-#include <stdint.h>
-
-#include "rte_acl.h"
-
-#include "rte_table.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ACL table parameters */
-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];
-};
-
-/** ACL rule specification for entry add operation */
-struct rte_table_acl_rule_add_params {
- /** ACL rule priority, with 0 as the highest priority */
- int32_t priority;
-
- /** Values for the fields of the ACL rule to be added to the table */
- struct rte_acl_field field_value[RTE_ACL_MAX_FIELDS];
-};
-
-/** ACL rule specification for entry delete operation */
-struct rte_table_acl_rule_delete_params {
- /** Values for the fields of the ACL rule to be deleted from table */
- struct rte_acl_field field_value[RTE_ACL_MAX_FIELDS];
-};
-
-/** ACL table operations */
-extern struct rte_table_ops rte_table_acl_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/rte_table_array.c b/lib/table/rte_table_array.c
deleted file mode 100644
index 55356e59998a547f0bd422bb248d3ac432b90881..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_array.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_array.h"
-
-#include "table_log.h"
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_ARRAY_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_ARRAY_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_ARRAY_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_ARRAY_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-struct __rte_cache_aligned rte_table_array {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t entry_size;
- uint32_t n_entries;
- uint32_t offset;
-
- /* Internal fields */
- uint32_t entry_pos_mask;
-
- /* Internal table */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t array[];
-};
-
-static void *
-rte_table_array_create(void *params, int socket_id, uint32_t entry_size)
-{
- struct rte_table_array_params *p = params;
- struct rte_table_array *t;
- uint32_t total_cl_size, total_size;
-
- /* Check input parameters */
- if ((p == NULL) ||
- (p->n_entries == 0) ||
- (!rte_is_power_of_2(p->n_entries)))
- return NULL;
-
- /* Memory allocation */
- total_cl_size = (sizeof(struct rte_table_array) +
- RTE_CACHE_LINE_SIZE) / RTE_CACHE_LINE_SIZE;
- total_cl_size += (p->n_entries * entry_size +
- RTE_CACHE_LINE_SIZE) / RTE_CACHE_LINE_SIZE;
- total_size = total_cl_size * RTE_CACHE_LINE_SIZE;
- t = rte_zmalloc_socket("TABLE", total_size, RTE_CACHE_LINE_SIZE, socket_id);
- if (t == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %u bytes for array table",
- __func__, total_size);
- return NULL;
- }
-
- /* Memory initialization */
- t->entry_size = entry_size;
- t->n_entries = p->n_entries;
- t->offset = p->offset;
- t->entry_pos_mask = t->n_entries - 1;
-
- return t;
-}
-
-static int
-rte_table_array_free(void *table)
-{
- struct rte_table_array *t = table;
-
- /* Check input parameters */
- if (t == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free previously allocated resources */
- rte_free(t);
-
- return 0;
-}
-
-static int
-rte_table_array_entry_add(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_array *t = table;
- struct rte_table_array_key *k = key;
- uint8_t *table_entry;
-
- /* Check input parameters */
- if (table == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (key == NULL) {
- TABLE_LOG(ERR, "%s: key parameter is NULL", __func__);
- return -EINVAL;
- }
- if (entry == NULL) {
- TABLE_LOG(ERR, "%s: entry parameter is NULL", __func__);
- return -EINVAL;
- }
- if (key_found == NULL) {
- TABLE_LOG(ERR, "%s: key_found parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (entry_ptr == NULL) {
- TABLE_LOG(ERR, "%s: entry_ptr parameter is NULL",
- __func__);
- return -EINVAL;
- }
-
- table_entry = &t->array[k->pos * t->entry_size];
- memcpy(table_entry, entry, t->entry_size);
- *key_found = 1;
- *entry_ptr = (void *) table_entry;
-
- return 0;
-}
-
-static int
-rte_table_array_lookup(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_array *t = (struct rte_table_array *) table;
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_ARRAY_STATS_PKTS_IN_ADD(t, n_pkts_in);
- *lookup_hit_mask = pkts_mask;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- uint32_t entry_pos = RTE_MBUF_METADATA_UINT32(pkt,
- t->offset) & t->entry_pos_mask;
-
- entries[i] = (void *) &t->array[entry_pos *
- t->entry_size];
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
- uint32_t entry_pos = RTE_MBUF_METADATA_UINT32(pkt,
- t->offset) & t->entry_pos_mask;
-
- entries[pkt_index] = (void *) &t->array[entry_pos *
- t->entry_size];
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_table_array_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_array *array = table;
-
- if (stats != NULL)
- memcpy(stats, &array->stats, sizeof(array->stats));
-
- if (clear)
- memset(&array->stats, 0, sizeof(array->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_array_ops)
-struct rte_table_ops rte_table_array_ops = {
- .f_create = rte_table_array_create,
- .f_free = rte_table_array_free,
- .f_add = rte_table_array_entry_add,
- .f_delete = NULL,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_array_lookup,
- .f_stats = rte_table_array_stats_read,
-};
diff --git a/lib/table/rte_table_array.h b/lib/table/rte_table_array.h
deleted file mode 100644
index b2a7b95d68b57399bacf229ea4972287c03c5102..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_array.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_ARRAY_H__
-#define __INCLUDE_RTE_TABLE_ARRAY_H__
-
-/**
- * @file
- * RTE Table Array
- *
- * Simple array indexing. Lookup key is the array entry index.
- */
-
-#include <stdint.h>
-
-#include "rte_table.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Array table parameters */
-struct rte_table_array_params {
- /** Number of array entries. Has to be a power of two. */
- uint32_t n_entries;
-
- /** Byte offset within input packet meta-data where lookup key (i.e. the
- array entry index) is located. */
- uint32_t offset;
-};
-
-/** Array table key format */
-struct rte_table_array_key {
- /** Array entry index */
- uint32_t pos;
-};
-
-/** Array table operations */
-extern struct rte_table_ops rte_table_array_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/rte_table_hash.h b/lib/table/rte_table_hash.h
deleted file mode 100644
index ff8fc9e9cef5fdd0cf9b9c10d800169ca83699d3..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2017 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_HASH_H__
-#define __INCLUDE_RTE_TABLE_HASH_H__
-
-/**
- * @file
- * RTE Table Hash
- *
- * These tables use the exact match criterion to uniquely associate data to
- * lookup keys.
- *
- * Hash table types:
- * 1. Entry add strategy on bucket full:
- * a. Least Recently Used (LRU): One of the existing keys in the bucket is
- * deleted and the new key is added in its place. The number of keys in
- * each bucket never grows bigger than 4. The logic to pick the key to
- * be dropped from the bucket is LRU. The hash table lookup operation
- * maintains the order in which the keys in the same bucket are hit, so
- * every time a key is hit, it becomes the new Most Recently Used (MRU)
- * key, i.e. the most unlikely candidate for drop. When a key is added
- * to the bucket, it also becomes the new MRU key. When a key needs to
- * be picked and dropped, the most likely candidate for drop, i.e. the
- * current LRU key, is always picked. The LRU logic requires maintaining
- * specific data structures per each bucket. Use-cases: flow cache, etc.
- * b. Extendable bucket (ext): The bucket is extended with space for 4 more
- * keys. This is done by allocating additional memory at table init time,
- * which is used to create a pool of free keys (the size of this pool is
- * configurable and always a multiple of 4). On key add operation, the
- * allocation of a group of 4 keys only happens successfully within the
- * limit of free keys, otherwise the key add operation fails. On key
- * delete operation, a group of 4 keys is freed back to the pool of free
- * keys when the key to be deleted is the only key that was used within
- * its group of 4 keys at that time. On key lookup operation, if the
- * current bucket is in extended state and a match is not found in the
- * first group of 4 keys, the search continues beyond the first group of
- * 4 keys, potentially until all keys in this bucket are examined. The
- * extendable bucket logic requires maintaining specific data structures
- * per table and per each bucket. Use-cases: flow table, etc.
- * 2. Key size:
- * a. Configurable key size
- * b. Single key size (8-byte, 16-byte or 32-byte key size)
- */
-
-#include <stdint.h>
-
-#include "rte_table.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Hash function */
-typedef uint64_t (*rte_table_hash_op_hash)(
- void *key,
- void *key_mask,
- uint32_t key_size,
- uint64_t seed);
-
-/** Hash table parameters */
-struct rte_table_hash_params {
- /** Name */
- const char *name;
-
- /** Key size (number of bytes) */
- uint32_t key_size;
-
- /** Byte offset within packet meta-data where the key is located */
- uint32_t key_offset;
-
- /** Key mask */
- uint8_t *key_mask;
-
- /** Number of keys */
- uint32_t n_keys;
-
- /** Number of buckets */
- uint32_t n_buckets;
-
- /** Hash function */
- rte_table_hash_op_hash f_hash;
-
- /** Seed value for the hash function */
- uint64_t seed;
-};
-
-/** Extendable bucket hash table operations */
-extern struct rte_table_ops rte_table_hash_ext_ops;
-extern struct rte_table_ops rte_table_hash_key8_ext_ops;
-extern struct rte_table_ops rte_table_hash_key16_ext_ops;
-extern struct rte_table_ops rte_table_hash_key32_ext_ops;
-
-/** LRU hash table operations */
-extern struct rte_table_ops rte_table_hash_lru_ops;
-
-extern struct rte_table_ops rte_table_hash_key8_lru_ops;
-extern struct rte_table_ops rte_table_hash_key16_lru_ops;
-extern struct rte_table_ops rte_table_hash_key32_lru_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/rte_table_hash_cuckoo.c b/lib/table/rte_table_hash_cuckoo.c
deleted file mode 100644
index a2b920fa92f77ed66fbedee1417090a56dbc8a2e..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_cuckoo.c
+++ /dev/null
@@ -1,327 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2017 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_hash_cuckoo.h"
-
-#include "table_log.h"
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_HASH_CUCKOO_STATS_PKTS_IN_ADD(table, val) \
- (table->stats.n_pkts_in += val)
-#define RTE_TABLE_HASH_CUCKOO_STATS_PKTS_LOOKUP_MISS(table, val) \
- (table->stats.n_pkts_lookup_miss += val)
-
-#else
-
-#define RTE_TABLE_HASH_CUCKOO_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_HASH_CUCKOO_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-
-struct rte_table_hash {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t key_size;
- uint32_t entry_size;
- uint32_t n_keys;
- rte_hash_function f_hash;
- uint32_t seed;
- uint32_t key_offset;
-
- /* cuckoo hash table object */
- struct rte_hash *h_table;
-
- /* Lookup table */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static int
-check_params_create_hash_cuckoo(struct rte_table_hash_cuckoo_params *params)
-{
- if (params == NULL) {
- TABLE_LOG(ERR, "NULL Input Parameters.");
- return -EINVAL;
- }
-
- if (params->name == NULL) {
- TABLE_LOG(ERR, "Table name is NULL.");
- return -EINVAL;
- }
-
- if (params->key_size == 0) {
- TABLE_LOG(ERR, "Invalid key_size.");
- return -EINVAL;
- }
-
- if (params->n_keys == 0) {
- TABLE_LOG(ERR, "Invalid n_keys.");
- return -EINVAL;
- }
-
- if (params->f_hash == NULL) {
- TABLE_LOG(ERR, "f_hash is NULL.");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void *
-rte_table_hash_cuckoo_create(void *params,
- int socket_id,
- uint32_t entry_size)
-{
- struct rte_table_hash_cuckoo_params *p = params;
- struct rte_hash *h_table;
- struct rte_table_hash *t;
- uint32_t total_size;
-
- /* Check input parameters */
- if (check_params_create_hash_cuckoo(params))
- return NULL;
-
- /* Memory allocation */
- total_size = sizeof(struct rte_table_hash) +
- RTE_CACHE_LINE_ROUNDUP(p->n_keys * entry_size);
-
- t = rte_zmalloc_socket(p->name, total_size, RTE_CACHE_LINE_SIZE, socket_id);
- if (t == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %u bytes for cuckoo hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- /* Create cuckoo hash table */
- struct rte_hash_parameters hash_cuckoo_params = {
- .entries = p->n_keys,
- .key_len = p->key_size,
- .hash_func = p->f_hash,
- .hash_func_init_val = p->seed,
- .socket_id = socket_id,
- .name = p->name
- };
-
- h_table = rte_hash_find_existing(p->name);
- if (h_table == NULL) {
- h_table = rte_hash_create(&hash_cuckoo_params);
- if (h_table == NULL) {
- TABLE_LOG(ERR,
- "%s: failed to create cuckoo hash table %s",
- __func__, p->name);
- rte_free(t);
- return NULL;
- }
- }
-
- /* initialize the cuckoo hash parameters */
- t->key_size = p->key_size;
- t->entry_size = entry_size;
- t->n_keys = p->n_keys;
- t->f_hash = p->f_hash;
- t->seed = p->seed;
- t->key_offset = p->key_offset;
- t->h_table = h_table;
-
- TABLE_LOG(INFO,
- "%s: Cuckoo hash table %s memory footprint is %u bytes",
- __func__, p->name, total_size);
- return t;
-}
-
-static int
-rte_table_hash_cuckoo_free(void *table) {
- struct rte_table_hash *t = table;
-
- if (table == NULL)
- return -EINVAL;
-
- rte_hash_free(t->h_table);
- rte_free(t);
-
- return 0;
-}
-
-static int
-rte_table_hash_cuckoo_entry_add(void *table, void *key, void *entry,
- int *key_found, void **entry_ptr)
-{
- struct rte_table_hash *t = table;
- int pos = 0;
-
- /* Check input parameters */
- if ((table == NULL) ||
- (key == NULL) ||
- (entry == NULL) ||
- (key_found == NULL) ||
- (entry_ptr == NULL))
- return -EINVAL;
-
- /* Find Existing entries */
- pos = rte_hash_lookup(t->h_table, key);
- if (pos >= 0) {
- uint8_t *existing_entry;
-
- *key_found = 1;
- existing_entry = &t->memory[pos * t->entry_size];
- memcpy(existing_entry, entry, t->entry_size);
- *entry_ptr = existing_entry;
-
- return 0;
- }
-
- if (pos == -ENOENT) {
- /* Entry not found. Adding new entry */
- uint8_t *new_entry;
-
- pos = rte_hash_add_key(t->h_table, key);
- if (pos < 0)
- return pos;
-
- new_entry = &t->memory[pos * t->entry_size];
- memcpy(new_entry, entry, t->entry_size);
-
- *key_found = 0;
- *entry_ptr = new_entry;
- return 0;
- }
-
- return pos;
-}
-
-static int
-rte_table_hash_cuckoo_entry_delete(void *table, void *key,
- int *key_found, void *entry)
-{
- struct rte_table_hash *t = table;
- int pos = 0;
-
- /* Check input parameters */
- if ((table == NULL) ||
- (key == NULL) ||
- (key_found == NULL))
- return -EINVAL;
-
- pos = rte_hash_del_key(t->h_table, key);
- if (pos >= 0) {
- *key_found = 1;
- uint8_t *entry_ptr = &t->memory[pos * t->entry_size];
-
- if (entry)
- memcpy(entry, entry_ptr, t->entry_size);
-
- memset(&t->memory[pos * t->entry_size], 0, t->entry_size);
- return 0;
- }
-
- *key_found = 0;
- return pos;
-}
-
-static int
-rte_table_hash_cuckoo_lookup(void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *t = table;
- uint64_t pkts_mask_out = 0;
- uint32_t i;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
-
- RTE_TABLE_HASH_CUCKOO_STATS_PKTS_IN_ADD(t, n_pkts_in);
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- const uint8_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];
- int32_t positions[RTE_PORT_IN_BURST_SIZE_MAX], status;
-
- /* Keys for bulk lookup */
- for (i = 0; i < n_pkts_in; i++)
- keys[i] = RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- t->key_offset);
-
- /* Bulk Lookup */
- status = rte_hash_lookup_bulk(t->h_table,
- (const void **) keys,
- n_pkts_in,
- positions);
- if (status == 0) {
- for (i = 0; i < n_pkts_in; i++) {
- if (likely(positions[i] >= 0)) {
- uint64_t pkt_mask = 1LLU << i;
-
- entries[i] = &t->memory[positions[i]
- * t->entry_size];
- pkts_mask_out |= pkt_mask;
- }
- }
- }
- } else
- for (i = 0; i < (uint32_t)(RTE_PORT_IN_BURST_SIZE_MAX
- - rte_clz64(pkts_mask)); i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if (pkt_mask & pkts_mask) {
- struct rte_mbuf *pkt = pkts[i];
- uint8_t *key = RTE_MBUF_METADATA_UINT8_PTR(pkt,
- t->key_offset);
- int pos;
-
- pos = rte_hash_lookup(t->h_table, key);
- if (likely(pos >= 0)) {
- entries[i] = &t->memory[pos
- * t->entry_size];
- pkts_mask_out |= pkt_mask;
- }
- }
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_CUCKOO_STATS_PKTS_LOOKUP_MISS(t,
- n_pkts_in - rte_popcount64(pkts_mask_out));
-
- return 0;
-
-}
-
-static int
-rte_table_hash_cuckoo_stats_read(void *table, struct rte_table_stats *stats,
- int clear)
-{
- struct rte_table_hash *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_hash_cuckoo_ops)
-struct rte_table_ops rte_table_hash_cuckoo_ops = {
- .f_create = rte_table_hash_cuckoo_create,
- .f_free = rte_table_hash_cuckoo_free,
- .f_add = rte_table_hash_cuckoo_entry_add,
- .f_delete = rte_table_hash_cuckoo_entry_delete,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_cuckoo_lookup,
- .f_stats = rte_table_hash_cuckoo_stats_read,
-};
diff --git a/lib/table/rte_table_hash_cuckoo.h b/lib/table/rte_table_hash_cuckoo.h
deleted file mode 100644
index 55aa12216aa7b8f38f7b04fabc40da0e57a0c284..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_cuckoo.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_HASH_CUCKOO_H__
-#define __INCLUDE_RTE_TABLE_HASH_CUCKOO_H__
-
-/**
- * @file
- * RTE Table Hash Cuckoo
- */
-
-#include <stdint.h>
-
-#include <rte_hash.h>
-
-#include "rte_table.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Hash table parameters */
-struct rte_table_hash_cuckoo_params {
- /** Name */
- const char *name;
-
- /** Key size (number of bytes) */
- uint32_t key_size;
-
- /** Byte offset within packet meta-data where the key is located */
- uint32_t key_offset;
-
- /** Key mask */
- uint8_t *key_mask;
-
- /** Number of keys */
- uint32_t n_keys;
-
- /** Number of buckets */
- uint32_t n_buckets;
-
- /** Hash function */
- rte_hash_function f_hash;
-
- /** Seed value for the hash function */
- uint32_t seed;
-};
-
-/** Cuckoo hash table operations */
-extern struct rte_table_ops rte_table_hash_cuckoo_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/rte_table_hash_ext.c b/lib/table/rte_table_hash_ext.c
deleted file mode 100644
index 86e8eeb4c82053841f653e78b31760af0fb64e34..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_ext.c
+++ /dev/null
@@ -1,1011 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2017 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_hash.h"
-
-#include "table_log.h"
-
-#define KEYS_PER_BUCKET 4
-
-struct bucket {
- union {
- uintptr_t next;
- uint64_t lru_list;
- };
- uint16_t sig[KEYS_PER_BUCKET];
- uint32_t key_pos[KEYS_PER_BUCKET];
-};
-
-#define BUCKET_NEXT(bucket) \
- ((void *) ((bucket)->next & (~1LU)))
-
-#define BUCKET_NEXT_VALID(bucket) \
- ((bucket)->next & 1LU)
-
-#define BUCKET_NEXT_SET(bucket, bucket_next) \
-do \
- (bucket)->next = (((uintptr_t) ((void *) (bucket_next))) | 1LU);\
-while (0)
-
-#define BUCKET_NEXT_SET_NULL(bucket) \
-do \
- (bucket)->next = 0; \
-while (0)
-
-#define BUCKET_NEXT_COPY(bucket, bucket2) \
-do \
- (bucket)->next = (bucket2)->next; \
-while (0)
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-struct grinder {
- struct bucket *bkt;
- uint64_t sig;
- uint64_t match;
- uint32_t key_index;
-};
-
-struct rte_table_hash {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t key_size;
- uint32_t entry_size;
- uint32_t n_keys;
- uint32_t n_buckets;
- uint32_t n_buckets_ext;
- rte_table_hash_op_hash f_hash;
- uint64_t seed;
- uint32_t key_offset;
-
- /* Internal */
- uint64_t bucket_mask;
- uint32_t key_size_shl;
- uint32_t data_size_shl;
- uint32_t key_stack_tos;
- uint32_t bkt_ext_stack_tos;
-
- /* Grinder */
- struct grinder grinders[RTE_PORT_IN_BURST_SIZE_MAX];
-
- /* Tables */
- uint64_t *key_mask;
- struct bucket *buckets;
- struct bucket *buckets_ext;
- uint8_t *key_mem;
- uint8_t *data_mem;
- uint32_t *key_stack;
- uint32_t *bkt_ext_stack;
-
- /* Table memory */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static int
-keycmp(void *a, void *b, void *b_mask, uint32_t n_bytes)
-{
- uint64_t *a64 = a, *b64 = b, *b_mask64 = b_mask;
- uint32_t i;
-
- for (i = 0; i < n_bytes / sizeof(uint64_t); i++)
- if (a64[i] != (b64[i] & b_mask64[i]))
- return 1;
-
- return 0;
-}
-
-static void
-keycpy(void *dst, void *src, void *src_mask, uint32_t n_bytes)
-{
- uint64_t *dst64 = dst, *src64 = src, *src_mask64 = src_mask;
- uint32_t i;
-
- for (i = 0; i < n_bytes / sizeof(uint64_t); i++)
- dst64[i] = src64[i] & src_mask64[i];
-}
-
-static int
-check_params_create(struct rte_table_hash_params *params)
-{
- /* name */
- if (params->name == NULL) {
- TABLE_LOG(ERR, "%s: name invalid value", __func__);
- return -EINVAL;
- }
-
- /* key_size */
- if ((params->key_size < sizeof(uint64_t)) ||
- (!rte_is_power_of_2(params->key_size))) {
- TABLE_LOG(ERR, "%s: key_size invalid value", __func__);
- return -EINVAL;
- }
-
- /* n_keys */
- if (params->n_keys == 0) {
- TABLE_LOG(ERR, "%s: n_keys invalid value", __func__);
- return -EINVAL;
- }
-
- /* n_buckets */
- if ((params->n_buckets == 0) ||
- (!rte_is_power_of_2(params->n_buckets))) {
- TABLE_LOG(ERR, "%s: n_buckets invalid value", __func__);
- return -EINVAL;
- }
-
- /* f_hash */
- if (params->f_hash == NULL) {
- TABLE_LOG(ERR, "%s: f_hash invalid value", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void *
-rte_table_hash_ext_create(void *params, int socket_id, uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *t;
- uint64_t table_meta_sz, key_mask_sz, bucket_sz, bucket_ext_sz, key_sz;
- uint64_t key_stack_sz, bkt_ext_stack_sz, data_sz, total_size;
- uint64_t key_mask_offset, bucket_offset, bucket_ext_offset, key_offset;
- uint64_t key_stack_offset, bkt_ext_stack_offset, data_offset;
- uint32_t n_buckets_ext, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- (!rte_is_power_of_2(entry_size)) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- (sizeof(struct bucket) != (RTE_CACHE_LINE_SIZE / 2)))
- return NULL;
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of bucket extensions (n_buckets_ext) so that
- * it is guaranteed that n_keys keys can be stored in the table at any time.
- *
- * The worst case scenario takes place when all the n_keys keys fall into
- * the same bucket. Actually, due to the KEYS_PER_BUCKET scheme, the worst
- * case takes place when (n_keys - KEYS_PER_BUCKET + 1) keys fall into the
- * same bucket, while the remaining (KEYS_PER_BUCKET - 1) keys each fall
- * into a different bucket. This case defeats the purpose of the hash table.
- * It indicates unsuitable f_hash or n_keys to n_buckets ratio.
- *
- * n_buckets_ext = n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1
- */
- n_buckets_ext = p->n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1;
-
- /* Memory allocation */
- table_meta_sz = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_table_hash));
- key_mask_sz = RTE_CACHE_LINE_ROUNDUP(p->key_size);
- bucket_sz = RTE_CACHE_LINE_ROUNDUP(p->n_buckets * sizeof(struct bucket));
- bucket_ext_sz =
- RTE_CACHE_LINE_ROUNDUP(n_buckets_ext * sizeof(struct bucket));
- key_sz = RTE_CACHE_LINE_ROUNDUP(p->n_keys * p->key_size);
- key_stack_sz = RTE_CACHE_LINE_ROUNDUP(p->n_keys * sizeof(uint32_t));
- bkt_ext_stack_sz =
- RTE_CACHE_LINE_ROUNDUP(n_buckets_ext * sizeof(uint32_t));
- data_sz = RTE_CACHE_LINE_ROUNDUP(p->n_keys * entry_size);
- total_size = table_meta_sz + key_mask_sz + bucket_sz + bucket_ext_sz +
- key_sz + key_stack_sz + bkt_ext_stack_sz + data_sz;
-
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes"
- " for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- t = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (t == NULL) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes"
- " for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
- TABLE_LOG(INFO, "%s (%u-byte key): Hash table %s memory "
- "footprint is %" PRIu64 " bytes",
- __func__, p->key_size, p->name, total_size);
-
- /* Memory initialization */
- t->key_size = p->key_size;
- t->entry_size = entry_size;
- t->n_keys = p->n_keys;
- t->n_buckets = p->n_buckets;
- t->n_buckets_ext = n_buckets_ext;
- t->f_hash = p->f_hash;
- t->seed = p->seed;
- t->key_offset = p->key_offset;
-
- /* Internal */
- t->bucket_mask = t->n_buckets - 1;
- t->key_size_shl = rte_ctz32(p->key_size);
- t->data_size_shl = rte_ctz32(entry_size);
-
- /* Tables */
- key_mask_offset = 0;
- bucket_offset = key_mask_offset + key_mask_sz;
- bucket_ext_offset = bucket_offset + bucket_sz;
- key_offset = bucket_ext_offset + bucket_ext_sz;
- key_stack_offset = key_offset + key_sz;
- bkt_ext_stack_offset = key_stack_offset + key_stack_sz;
- data_offset = bkt_ext_stack_offset + bkt_ext_stack_sz;
-
- t->key_mask = (uint64_t *) &t->memory[key_mask_offset];
- t->buckets = (struct bucket *) &t->memory[bucket_offset];
- t->buckets_ext = (struct bucket *) &t->memory[bucket_ext_offset];
- t->key_mem = &t->memory[key_offset];
- t->key_stack = (uint32_t *) &t->memory[key_stack_offset];
- t->bkt_ext_stack = (uint32_t *) &t->memory[bkt_ext_stack_offset];
- t->data_mem = &t->memory[data_offset];
-
- /* Key mask */
- if (p->key_mask == NULL)
- memset(t->key_mask, 0xFF, p->key_size);
- else
- memcpy(t->key_mask, p->key_mask, p->key_size);
-
- /* Key stack */
- for (i = 0; i < t->n_keys; i++)
- t->key_stack[i] = t->n_keys - 1 - i;
- t->key_stack_tos = t->n_keys;
-
- /* Bucket ext stack */
- for (i = 0; i < t->n_buckets_ext; i++)
- t->bkt_ext_stack[i] = t->n_buckets_ext - 1 - i;
- t->bkt_ext_stack_tos = t->n_buckets_ext;
-
- return t;
-}
-
-static int
-rte_table_hash_ext_free(void *table)
-{
- struct rte_table_hash *t = table;
-
- /* Check input parameters */
- if (t == NULL)
- return -EINVAL;
-
- rte_free(t);
- return 0;
-}
-
-static int
-rte_table_hash_ext_entry_add(void *table, void *key, void *entry,
- int *key_found, void **entry_ptr)
-{
- struct rte_table_hash *t = table;
- struct bucket *bkt0, *bkt, *bkt_prev;
- uint64_t sig;
- uint32_t bkt_index, i;
-
- sig = t->f_hash(key, t->key_mask, t->key_size, t->seed);
- bkt_index = sig & t->bucket_mask;
- bkt0 = &t->buckets[bkt_index];
- sig = (sig >> 16) | 1LLU;
-
- /* Key is present in the bucket */
- for (bkt = bkt0; bkt != NULL; bkt = BUCKET_NEXT(bkt))
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
- uint32_t bkt_key_index = bkt->key_pos[i];
- uint8_t *bkt_key =
- &t->key_mem[bkt_key_index << t->key_size_shl];
-
- if ((sig == bkt_sig) && (keycmp(bkt_key, key, t->key_mask,
- t->key_size) == 0)) {
- uint8_t *data = &t->data_mem[bkt_key_index <<
- t->data_size_shl];
-
- memcpy(data, entry, t->entry_size);
- *key_found = 1;
- *entry_ptr = (void *) data;
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- for (bkt_prev = NULL, bkt = bkt0; bkt != NULL; bkt_prev = bkt,
- bkt = BUCKET_NEXT(bkt))
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
-
- if (bkt_sig == 0) {
- uint32_t bkt_key_index;
- uint8_t *bkt_key, *data;
-
- /* Allocate new key */
- if (t->key_stack_tos == 0) /* No free keys */
- return -ENOSPC;
-
- bkt_key_index = t->key_stack[
- --t->key_stack_tos];
-
- /* Install new key */
- bkt_key = &t->key_mem[bkt_key_index <<
- t->key_size_shl];
- data = &t->data_mem[bkt_key_index <<
- t->data_size_shl];
-
- bkt->sig[i] = (uint16_t) sig;
- bkt->key_pos[i] = bkt_key_index;
- keycpy(bkt_key, key, t->key_mask, t->key_size);
- memcpy(data, entry, t->entry_size);
-
- *key_found = 0;
- *entry_ptr = (void *) data;
- return 0;
- }
- }
-
- /* Bucket full: extend bucket */
- if ((t->bkt_ext_stack_tos > 0) && (t->key_stack_tos > 0)) {
- uint32_t bkt_key_index;
- uint8_t *bkt_key, *data;
-
- /* Allocate new bucket ext */
- bkt_index = t->bkt_ext_stack[--t->bkt_ext_stack_tos];
- bkt = &t->buckets_ext[bkt_index];
-
- /* Chain the new bucket ext */
- BUCKET_NEXT_SET(bkt_prev, bkt);
- BUCKET_NEXT_SET_NULL(bkt);
-
- /* Allocate new key */
- bkt_key_index = t->key_stack[--t->key_stack_tos];
- bkt_key = &t->key_mem[bkt_key_index << t->key_size_shl];
-
- data = &t->data_mem[bkt_key_index << t->data_size_shl];
-
- /* Install new key into bucket */
- bkt->sig[0] = (uint16_t) sig;
- bkt->key_pos[0] = bkt_key_index;
- keycpy(bkt_key, key, t->key_mask, t->key_size);
- memcpy(data, entry, t->entry_size);
-
- *key_found = 0;
- *entry_ptr = (void *) data;
- return 0;
- }
-
- return -ENOSPC;
-}
-
-static int
-rte_table_hash_ext_entry_delete(void *table, void *key, int *key_found,
-void *entry)
-{
- struct rte_table_hash *t = table;
- struct bucket *bkt0, *bkt, *bkt_prev;
- uint64_t sig;
- uint32_t bkt_index, i;
-
- sig = t->f_hash(key, t->key_mask, t->key_size, t->seed);
- bkt_index = sig & t->bucket_mask;
- bkt0 = &t->buckets[bkt_index];
- sig = (sig >> 16) | 1LLU;
-
- /* Key is present in the bucket */
- for (bkt_prev = NULL, bkt = bkt0; bkt != NULL; bkt_prev = bkt,
- bkt = BUCKET_NEXT(bkt))
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
- uint32_t bkt_key_index = bkt->key_pos[i];
- uint8_t *bkt_key = &t->key_mem[bkt_key_index <<
- t->key_size_shl];
-
- if ((sig == bkt_sig) && (keycmp(bkt_key, key, t->key_mask,
- t->key_size) == 0)) {
- uint8_t *data = &t->data_mem[bkt_key_index <<
- t->data_size_shl];
-
- /* Uninstall key from bucket */
- bkt->sig[i] = 0;
- *key_found = 1;
- if (entry)
- memcpy(entry, data, t->entry_size);
-
- /* Free key */
- t->key_stack[t->key_stack_tos++] =
- bkt_key_index;
-
- /*Check if bucket is unused */
- if ((bkt_prev != NULL) &&
- (bkt->sig[0] == 0) && (bkt->sig[1] == 0) &&
- (bkt->sig[2] == 0) && (bkt->sig[3] == 0)) {
- /* Unchain bucket */
- BUCKET_NEXT_COPY(bkt_prev, bkt);
-
- /* Clear bucket */
- memset(bkt, 0, sizeof(struct bucket));
-
- /* Free bucket back to buckets ext */
- bkt_index = bkt - t->buckets_ext;
- t->bkt_ext_stack[t->bkt_ext_stack_tos++]
- = bkt_index;
- }
-
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-static int rte_table_hash_ext_lookup_unoptimized(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *t = (struct rte_table_hash *) table;
- uint64_t pkts_mask_out = 0;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
-
- for ( ; pkts_mask; ) {
- struct bucket *bkt0, *bkt;
- struct rte_mbuf *pkt;
- uint8_t *key;
- uint64_t pkt_mask, sig;
- uint32_t pkt_index, bkt_index, i;
-
- pkt_index = rte_ctz64(pkts_mask);
- pkt_mask = 1LLU << pkt_index;
- pkts_mask &= ~pkt_mask;
-
- pkt = pkts[pkt_index];
- key = RTE_MBUF_METADATA_UINT8_PTR(pkt, t->key_offset);
- sig = (uint64_t) t->f_hash(key, t->key_mask, t->key_size, t->seed);
-
- bkt_index = sig & t->bucket_mask;
- bkt0 = &t->buckets[bkt_index];
- sig = (sig >> 16) | 1LLU;
-
- /* Key is present in the bucket */
- for (bkt = bkt0; bkt != NULL; bkt = BUCKET_NEXT(bkt))
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
- uint32_t bkt_key_index = bkt->key_pos[i];
- uint8_t *bkt_key = &t->key_mem[bkt_key_index <<
- t->key_size_shl];
-
- if ((sig == bkt_sig) && (keycmp(bkt_key, key,
- t->key_mask, t->key_size) == 0)) {
- uint8_t *data = &t->data_mem[
- bkt_key_index << t->data_size_shl];
-
- pkts_mask_out |= pkt_mask;
- entries[pkt_index] = (void *) data;
- break;
- }
- }
- }
-
- *lookup_hit_mask = pkts_mask_out;
- return 0;
-}
-
-/*
- * mask = match bitmask
- * match = at least one match
- * match_many = more than one match
- * match_pos = position of first match
- *
- *----------------------------------------
- * mask match match_many match_pos
- *----------------------------------------
- * 0000 0 0 00
- * 0001 1 0 00
- * 0010 1 0 01
- * 0011 1 1 00
- *----------------------------------------
- * 0100 1 0 10
- * 0101 1 1 00
- * 0110 1 1 01
- * 0111 1 1 00
- *----------------------------------------
- * 1000 1 0 11
- * 1001 1 1 00
- * 1010 1 1 01
- * 1011 1 1 00
- *----------------------------------------
- * 1100 1 1 10
- * 1101 1 1 00
- * 1110 1 1 01
- * 1111 1 1 00
- *----------------------------------------
- *
- * match = 1111_1111_1111_1110
- * match_many = 1111_1110_1110_1000
- * match_pos = 0001_0010_0001_0011__0001_0010_0001_0000
- *
- * match = 0xFFFELLU
- * match_many = 0xFEE8LLU
- * match_pos = 0x12131210LLU
- */
-
-#define LUT_MATCH 0xFFFELLU
-#define LUT_MATCH_MANY 0xFEE8LLU
-#define LUT_MATCH_POS 0x12131210LLU
-
-#define lookup_cmp_sig(mbuf_sig, bucket, match, match_many, match_pos) \
-{ \
- uint64_t bucket_sig[4], mask[4], mask_all; \
- \
- bucket_sig[0] = bucket->sig[0]; \
- bucket_sig[1] = bucket->sig[1]; \
- bucket_sig[2] = bucket->sig[2]; \
- bucket_sig[3] = bucket->sig[3]; \
- \
- bucket_sig[0] ^= mbuf_sig; \
- bucket_sig[1] ^= mbuf_sig; \
- bucket_sig[2] ^= mbuf_sig; \
- bucket_sig[3] ^= mbuf_sig; \
- \
- mask[0] = 0; \
- mask[1] = 0; \
- mask[2] = 0; \
- mask[3] = 0; \
- \
- if (bucket_sig[0] == 0) \
- mask[0] = 1; \
- if (bucket_sig[1] == 0) \
- mask[1] = 2; \
- if (bucket_sig[2] == 0) \
- mask[2] = 4; \
- if (bucket_sig[3] == 0) \
- mask[3] = 8; \
- \
- mask_all = (mask[0] | mask[1]) | (mask[2] | mask[3]); \
- \
- match = (LUT_MATCH >> mask_all) & 1; \
- match_many = (LUT_MATCH_MANY >> mask_all) & 1; \
- match_pos = (LUT_MATCH_POS >> (mask_all << 1)) & 3; \
-}
-
-#define lookup_cmp_key(mbuf, key, match_key, f) \
-{ \
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(mbuf, f->key_offset);\
- uint64_t *bkt_key = (uint64_t *) key; \
- uint64_t *key_mask = f->key_mask; \
- \
- switch (f->key_size) { \
- case 8: \
- { \
- uint64_t xor = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- match_key = 0; \
- if (xor == 0) \
- match_key = 1; \
- } \
- break; \
- \
- case 16: \
- { \
- uint64_t xor[2], or; \
- \
- xor[0] = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- xor[1] = (pkt_key[1] & key_mask[1]) ^ bkt_key[1]; \
- or = xor[0] | xor[1]; \
- match_key = 0; \
- if (or == 0) \
- match_key = 1; \
- } \
- break; \
- \
- case 32: \
- { \
- uint64_t xor[4], or; \
- \
- xor[0] = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- xor[1] = (pkt_key[1] & key_mask[1]) ^ bkt_key[1]; \
- xor[2] = (pkt_key[2] & key_mask[2]) ^ bkt_key[2]; \
- xor[3] = (pkt_key[3] & key_mask[3]) ^ bkt_key[3]; \
- or = xor[0] | xor[1] | xor[2] | xor[3]; \
- match_key = 0; \
- if (or == 0) \
- match_key = 1; \
- } \
- break; \
- \
- case 64: \
- { \
- uint64_t xor[8], or; \
- \
- xor[0] = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- xor[1] = (pkt_key[1] & key_mask[1]) ^ bkt_key[1]; \
- xor[2] = (pkt_key[2] & key_mask[2]) ^ bkt_key[2]; \
- xor[3] = (pkt_key[3] & key_mask[3]) ^ bkt_key[3]; \
- xor[4] = (pkt_key[4] & key_mask[4]) ^ bkt_key[4]; \
- xor[5] = (pkt_key[5] & key_mask[5]) ^ bkt_key[5]; \
- xor[6] = (pkt_key[6] & key_mask[6]) ^ bkt_key[6]; \
- xor[7] = (pkt_key[7] & key_mask[7]) ^ bkt_key[7]; \
- or = xor[0] | xor[1] | xor[2] | xor[3] | \
- xor[4] | xor[5] | xor[6] | xor[7]; \
- match_key = 0; \
- if (or == 0) \
- match_key = 1; \
- } \
- break; \
- \
- default: \
- match_key = 0; \
- if (keycmp(bkt_key, pkt_key, key_mask, f->key_size) == 0) \
- match_key = 1; \
- } \
-}
-
-#define lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- struct rte_mbuf *mbuf00, *mbuf01; \
- uint32_t key_offset = t->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- mbuf00 = pkts[pkt00_index]; \
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- mbuf01 = pkts[pkt01_index]; \
- \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage0_with_odd_support(t, g, pkts, pkts_mask, pkt00_index, \
- pkt01_index) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- struct rte_mbuf *mbuf00, *mbuf01; \
- uint32_t key_offset = t->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- mbuf00 = pkts[pkt00_index]; \
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- if (pkts_mask == 0) \
- pkt01_index = pkt00_index; \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- mbuf01 = pkts[pkt01_index]; \
- \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index) \
-{ \
- struct grinder *g10, *g11; \
- uint64_t sig10, sig11, bkt10_index, bkt11_index; \
- struct rte_mbuf *mbuf10, *mbuf11; \
- struct bucket *bkt10, *bkt11, *buckets = t->buckets; \
- uint8_t *key10, *key11; \
- uint64_t bucket_mask = t->bucket_mask; \
- rte_table_hash_op_hash f_hash = t->f_hash; \
- uint64_t seed = t->seed; \
- uint32_t key_size = t->key_size; \
- uint32_t key_offset = t->key_offset; \
- \
- mbuf10 = pkts[pkt10_index]; \
- key10 = RTE_MBUF_METADATA_UINT8_PTR(mbuf10, key_offset); \
- sig10 = (uint64_t) f_hash(key10, t->key_mask, key_size, seed); \
- bkt10_index = sig10 & bucket_mask; \
- bkt10 = &buckets[bkt10_index]; \
- \
- mbuf11 = pkts[pkt11_index]; \
- key11 = RTE_MBUF_METADATA_UINT8_PTR(mbuf11, key_offset); \
- sig11 = (uint64_t) f_hash(key11, t->key_mask, key_size, seed); \
- bkt11_index = sig11 & bucket_mask; \
- bkt11 = &buckets[bkt11_index]; \
- \
- rte_prefetch0(bkt10); \
- rte_prefetch0(bkt11); \
- \
- g10 = &g[pkt10_index]; \
- g10->sig = sig10; \
- g10->bkt = bkt10; \
- \
- g11 = &g[pkt11_index]; \
- g11->sig = sig11; \
- g11->bkt = bkt11; \
-}
-
-#define lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many)\
-{ \
- struct grinder *g20, *g21; \
- uint64_t sig20, sig21; \
- struct bucket *bkt20, *bkt21; \
- uint8_t *key20, *key21, *key_mem = t->key_mem; \
- uint64_t match20, match21, match_many20, match_many21; \
- uint64_t match_pos20, match_pos21; \
- uint32_t key20_index, key21_index, key_size_shl = t->key_size_shl;\
- \
- g20 = &g[pkt20_index]; \
- sig20 = g20->sig; \
- bkt20 = g20->bkt; \
- sig20 = (sig20 >> 16) | 1LLU; \
- lookup_cmp_sig(sig20, bkt20, match20, match_many20, match_pos20);\
- match20 <<= pkt20_index; \
- match_many20 |= BUCKET_NEXT_VALID(bkt20); \
- match_many20 <<= pkt20_index; \
- key20_index = bkt20->key_pos[match_pos20]; \
- key20 = &key_mem[key20_index << key_size_shl]; \
- \
- g21 = &g[pkt21_index]; \
- sig21 = g21->sig; \
- bkt21 = g21->bkt; \
- sig21 = (sig21 >> 16) | 1LLU; \
- lookup_cmp_sig(sig21, bkt21, match21, match_many21, match_pos21);\
- match21 <<= pkt21_index; \
- match_many21 |= BUCKET_NEXT_VALID(bkt21); \
- match_many21 <<= pkt21_index; \
- key21_index = bkt21->key_pos[match_pos21]; \
- key21 = &key_mem[key21_index << key_size_shl]; \
- \
- rte_prefetch0(key20); \
- rte_prefetch0(key21); \
- \
- pkts_mask_match_many |= match_many20 | match_many21; \
- \
- g20->match = match20; \
- g20->key_index = key20_index; \
- \
- g21->match = match21; \
- g21->key_index = key21_index; \
-}
-
-#define lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out, \
- entries) \
-{ \
- struct grinder *g30, *g31; \
- struct rte_mbuf *mbuf30, *mbuf31; \
- uint8_t *key30, *key31, *key_mem = t->key_mem; \
- uint8_t *data30, *data31, *data_mem = t->data_mem; \
- uint64_t match30, match31, match_key30, match_key31, match_keys;\
- uint32_t key30_index, key31_index; \
- uint32_t key_size_shl = t->key_size_shl; \
- uint32_t data_size_shl = t->data_size_shl; \
- \
- mbuf30 = pkts[pkt30_index]; \
- g30 = &g[pkt30_index]; \
- match30 = g30->match; \
- key30_index = g30->key_index; \
- key30 = &key_mem[key30_index << key_size_shl]; \
- lookup_cmp_key(mbuf30, key30, match_key30, t); \
- match_key30 <<= pkt30_index; \
- match_key30 &= match30; \
- data30 = &data_mem[key30_index << data_size_shl]; \
- entries[pkt30_index] = data30; \
- \
- mbuf31 = pkts[pkt31_index]; \
- g31 = &g[pkt31_index]; \
- match31 = g31->match; \
- key31_index = g31->key_index; \
- key31 = &key_mem[key31_index << key_size_shl]; \
- lookup_cmp_key(mbuf31, key31, match_key31, t); \
- match_key31 <<= pkt31_index; \
- match_key31 &= match31; \
- data31 = &data_mem[key31_index << data_size_shl]; \
- entries[pkt31_index] = data31; \
- \
- rte_prefetch0(data30); \
- rte_prefetch0(data31); \
- \
- match_keys = match_key30 | match_key31; \
- pkts_mask_out |= match_keys; \
-}
-
-/*
- * The lookup function implements a 4-stage pipeline, with each stage processing
- * two different packets. The purpose of pipelined implementation is to hide the
- * latency of prefetching the data structures and loosen the data dependency
- * between instructions.
- *
- * p00 _______ p10 _______ p20 _______ p30 _______
- *----->| |----->| |----->| |----->| |----->
- * | 0 | | 1 | | 2 | | 3 |
- *----->|_______|----->|_______|----->|_______|----->|_______|----->
- * p01 p11 p21 p31
- *
- * The naming convention is:
- * pXY = packet Y of stage X, X = 0 .. 3, Y = 0 .. 1
- */
-static int rte_table_hash_ext_lookup(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *t = (struct rte_table_hash *) table;
- struct grinder *g = t->grinders;
- uint64_t pkt00_index, pkt01_index, pkt10_index, pkt11_index;
- uint64_t pkt20_index, pkt21_index, pkt30_index, pkt31_index;
- uint64_t pkts_mask_out = 0, pkts_mask_match_many = 0;
- int status = 0;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_HASH_EXT_STATS_PKTS_IN_ADD(t, n_pkts_in);
-
- /* Cannot run the pipeline with less than 7 packets */
- if (rte_popcount64(pkts_mask) < 7) {
- status = rte_table_hash_ext_lookup_unoptimized(table, pkts,
- pkts_mask, lookup_hit_mask, entries);
- RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in -
- rte_popcount64(*lookup_hit_mask));
- return status;
- }
-
- /* Pipeline stage 0 */
- lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index);
-
- /* Pipeline feed */
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index);
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline feed */
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index);
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(t, g, pkts, pkts_mask,
- pkt00_index, pkt01_index);
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index,
- pkts_mask_match_many);
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index,
- pkts_mask_out, entries);
- }
-
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many);
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out,
- entries);
-
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many);
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out,
- entries);
-
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out,
- entries);
-
- /* Slow path */
- pkts_mask_match_many &= ~pkts_mask_out;
- if (pkts_mask_match_many) {
- uint64_t pkts_mask_out_slow = 0;
-
- status = rte_table_hash_ext_lookup_unoptimized(table, pkts,
- pkts_mask_match_many, &pkts_mask_out_slow, entries);
- pkts_mask_out |= pkts_mask_out_slow;
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_EXT_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - rte_popcount64(pkts_mask_out));
- return status;
-}
-
-static int
-rte_table_hash_ext_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_hash *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_hash_ext_ops)
-struct rte_table_ops rte_table_hash_ext_ops = {
- .f_create = rte_table_hash_ext_create,
- .f_free = rte_table_hash_ext_free,
- .f_add = rte_table_hash_ext_entry_add,
- .f_delete = rte_table_hash_ext_entry_delete,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_ext_lookup,
- .f_stats = rte_table_hash_ext_stats_read,
-};
diff --git a/lib/table/rte_table_hash_func.h b/lib/table/rte_table_hash_func.h
deleted file mode 100644
index ca56e6c8850e4cf6cb920699becfef8dee98102a..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_func.h
+++ /dev/null
@@ -1,263 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_HASH_FUNC_H__
-#define __INCLUDE_RTE_TABLE_HASH_FUNC_H__
-
-#include <stdint.h>
-
-#include <rte_compat.h>
-#include <rte_common.h>
-
-#if defined(RTE_ARCH_X86_64)
-
-#include <x86intrin.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static inline uint64_t
-rte_crc32_u64(uint64_t crc, uint64_t v)
-{
- return _mm_crc32_u64(crc, v);
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#elif defined(RTE_ARCH_ARM64) && defined(__ARM_FEATURE_CRC32)
-#include "rte_table_hash_func_arm64.h"
-#else
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-static inline uint64_t
-rte_crc32_u64(uint64_t crc, uint64_t v)
-{
- int i;
-
- crc = (crc & 0xFFFFFFFFLLU) ^ v;
- for (i = 63; i >= 0; i--) {
- uint64_t mask;
-
- mask = -(crc & 1LLU);
- crc = (crc >> 1LLU) ^ (0x82F63B78LLU & mask);
- }
-
- return crc;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t crc0;
-
- crc0 = rte_crc32_u64(seed, k[0] & m[0]);
-
- return crc0;
-}
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key16(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t k0, crc0, crc1;
-
- k0 = k[0] & m[0];
-
- crc0 = rte_crc32_u64(k0, seed);
- crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
-
- crc0 ^= crc1;
-
- return crc0;
-}
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key24(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t k0, k2, crc0, crc1;
-
- k0 = k[0] & m[0];
- k2 = k[2] & m[2];
-
- crc0 = rte_crc32_u64(k0, seed);
- crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
-
- crc0 = rte_crc32_u64(crc0, k2);
-
- crc0 ^= crc1;
-
- return crc0;
-}
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key32(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t k0, k2, crc0, crc1, crc2, crc3;
-
- k0 = k[0] & m[0];
- k2 = k[2] & m[2];
-
- crc0 = rte_crc32_u64(k0, seed);
- crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
-
- crc2 = rte_crc32_u64(k2, k[3] & m[3]);
- crc3 = k2 >> 32;
-
- crc0 = rte_crc32_u64(crc0, crc1);
- crc1 = rte_crc32_u64(crc2, crc3);
-
- crc0 ^= crc1;
-
- return crc0;
-}
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key40(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t k0, k2, crc0, crc1, crc2, crc3;
-
- k0 = k[0] & m[0];
- k2 = k[2] & m[2];
-
- crc0 = rte_crc32_u64(k0, seed);
- crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
-
- crc2 = rte_crc32_u64(k2, k[3] & m[3]);
- crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
-
- crc0 = rte_crc32_u64(crc0, crc1);
- crc1 = rte_crc32_u64(crc2, crc3);
-
- crc0 ^= crc1;
-
- return crc0;
-}
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key48(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t k0, k2, k5, crc0, crc1, crc2, crc3;
-
- k0 = k[0] & m[0];
- k2 = k[2] & m[2];
- k5 = k[5] & m[5];
-
- crc0 = rte_crc32_u64(k0, seed);
- crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
-
- crc2 = rte_crc32_u64(k2, k[3] & m[3]);
- crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
-
- crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
- crc1 = rte_crc32_u64(crc3, k5);
-
- crc0 ^= crc1;
-
- return crc0;
-}
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key56(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5;
-
- k0 = k[0] & m[0];
- k2 = k[2] & m[2];
- k5 = k[5] & m[5];
-
- crc0 = rte_crc32_u64(k0, seed);
- crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
-
- crc2 = rte_crc32_u64(k2, k[3] & m[3]);
- crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
-
- crc4 = rte_crc32_u64(k5, k[6] & m[6]);
- crc5 = k5 >> 32;
-
- crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
- crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5);
-
- crc0 ^= crc1;
-
- return crc0;
-}
-
-__rte_experimental
-static inline uint64_t
-rte_table_hash_crc_key64(void *key, void *mask, __rte_unused uint32_t key_size,
- uint64_t seed)
-{
- uint64_t *k = (uint64_t *)key;
- uint64_t *m = (uint64_t *)mask;
- uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5;
-
- k0 = k[0] & m[0];
- k2 = k[2] & m[2];
- k5 = k[5] & m[5];
-
- crc0 = rte_crc32_u64(k0, seed);
- crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]);
-
- crc2 = rte_crc32_u64(k2, k[3] & m[3]);
- crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]);
-
- crc4 = rte_crc32_u64(k5, k[6] & m[6]);
- crc5 = rte_crc32_u64(k5 >> 32, k[7] & m[7]);
-
- crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2);
- crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5);
-
- crc0 ^= crc1;
-
- return crc0;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/rte_table_hash_func_arm64.h b/lib/table/rte_table_hash_func_arm64.h
deleted file mode 100644
index eb04c1ff54f7e930ef8b6e9028a51d5a4ecce6f6..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_func_arm64.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017-2018 Linaro Limited
- */
-
-#ifndef __INCLUDE_RTE_TABLE_HASH_FUNC_ARM64_H__
-#define __INCLUDE_RTE_TABLE_HASH_FUNC_ARM64_H__
-
-#define _CRC32CX(crc, val) \
- __asm__("crc32cx %w[c], %w[c], %x[v]":[c] "+r" (crc):[v] "r" (val))
-
-static inline uint64_t
-rte_crc32_u64(uint64_t crc, uint64_t v)
-{
- uint32_t crc32 = crc;
-
- _CRC32CX(crc32, v);
-
- return crc32;
-}
-
-#endif
diff --git a/lib/table/rte_table_hash_key16.c b/lib/table/rte_table_hash_key16.c
deleted file mode 100644
index 5b69106dd7e68fd519b0e9a420dcf8d4715d85b4..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_key16.c
+++ /dev/null
@@ -1,1190 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2017 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_hash.h"
-#include "rte_lru.h"
-
-#include "table_log.h"
-
-#define KEY_SIZE 16
-
-#define KEYS_PER_BUCKET 4
-
-#define RTE_BUCKET_ENTRY_VALID 0x1LLU
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-#ifdef RTE_ARCH_64
-struct rte_bucket_4_16 {
- /* Cache line 0 */
- uint64_t signature[4 + 1];
- uint64_t lru_list;
- struct rte_bucket_4_16 *next;
- uint64_t next_valid;
-
- /* Cache line 1 */
- uint64_t key[4][2];
-
- /* Cache line 2 */
- uint8_t data[];
-};
-#else
-struct rte_bucket_4_16 {
- /* Cache line 0 */
- uint64_t signature[4 + 1];
- uint64_t lru_list;
- struct rte_bucket_4_16 *next;
- uint32_t pad;
- uint64_t next_valid;
-
- /* Cache line 1 */
- uint64_t key[4][2];
-
- /* Cache line 2 */
- uint8_t data[];
-};
-#endif
-
-struct rte_table_hash {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t n_buckets;
- uint32_t key_size;
- uint32_t entry_size;
- uint32_t bucket_size;
- uint32_t key_offset;
- uint64_t key_mask[2];
- rte_table_hash_op_hash f_hash;
- uint64_t seed;
-
- /* Extendible buckets */
- uint32_t n_buckets_ext;
- uint32_t stack_pos;
- uint32_t *stack;
-
- /* Lookup table */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static int
-keycmp(void *a, void *b, void *b_mask)
-{
- uint64_t *a64 = a, *b64 = b, *b_mask64 = b_mask;
-
- return (a64[0] != (b64[0] & b_mask64[0])) ||
- (a64[1] != (b64[1] & b_mask64[1]));
-}
-
-static void
-keycpy(void *dst, void *src, void *src_mask)
-{
- uint64_t *dst64 = dst, *src64 = src, *src_mask64 = src_mask;
-
- dst64[0] = src64[0] & src_mask64[0];
- dst64[1] = src64[1] & src_mask64[1];
-}
-
-static int
-check_params_create(struct rte_table_hash_params *params)
-{
- /* name */
- if (params->name == NULL) {
- TABLE_LOG(ERR, "%s: name invalid value", __func__);
- return -EINVAL;
- }
-
- /* key_size */
- if (params->key_size != KEY_SIZE) {
- TABLE_LOG(ERR, "%s: key_size invalid value", __func__);
- return -EINVAL;
- }
-
- /* n_keys */
- if (params->n_keys == 0) {
- TABLE_LOG(ERR, "%s: n_keys is zero", __func__);
- return -EINVAL;
- }
-
- /* n_buckets */
- if ((params->n_buckets == 0) ||
- (!rte_is_power_of_2(params->n_buckets))) {
- TABLE_LOG(ERR, "%s: n_buckets invalid value", __func__);
- return -EINVAL;
- }
-
- /* f_hash */
- if (params->f_hash == NULL) {
- TABLE_LOG(ERR, "%s: f_hash function pointer is NULL",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void *
-rte_table_hash_create_key16_lru(void *params,
- int socket_id,
- uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *f;
- uint64_t bucket_size, total_size;
- uint32_t n_buckets, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_16) % 64) != 0))
- return NULL;
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of buckets (n_buckets) so that there a chance
- * to store n_keys keys in the table.
- *
- * Note: Since the buckets do not get extended, it is not possible to
- * guarantee that n_keys keys can be stored in the table at any time. In the
- * worst case scenario when all the n_keys fall into the same bucket, only
- * a maximum of KEYS_PER_BUCKET keys will be stored in the table. This case
- * defeats the purpose of the hash table. It indicates unsuitable f_hash or
- * n_keys to n_buckets ratio.
- *
- * MIN(n_buckets) = (n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET
- */
- n_buckets = rte_align32pow2(
- (p->n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET);
- n_buckets = RTE_MAX(n_buckets, p->n_buckets);
-
- /* Memory allocation */
- bucket_size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_bucket_4_16) +
- KEYS_PER_BUCKET * entry_size);
- total_size = sizeof(struct rte_table_hash) + n_buckets * bucket_size;
-
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- f = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
- TABLE_LOG(INFO, "%s: Hash table %s memory footprint "
- "is %" PRIu64 " bytes",
- __func__, p->name, total_size);
-
- /* Memory initialization */
- f->n_buckets = n_buckets;
- f->key_size = KEY_SIZE;
- f->entry_size = entry_size;
- f->bucket_size = bucket_size;
- f->key_offset = p->key_offset;
- f->f_hash = p->f_hash;
- f->seed = p->seed;
-
- if (p->key_mask != NULL) {
- f->key_mask[0] = ((uint64_t *)p->key_mask)[0];
- f->key_mask[1] = ((uint64_t *)p->key_mask)[1];
- } else {
- f->key_mask[0] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[1] = 0xFFFFFFFFFFFFFFFFLLU;
- }
-
- for (i = 0; i < n_buckets; i++) {
- struct rte_bucket_4_16 *bucket;
-
- bucket = (struct rte_bucket_4_16 *) &f->memory[i *
- f->bucket_size];
- lru_init(bucket);
- }
-
- return f;
-}
-
-static int
-rte_table_hash_free_key16_lru(void *table)
-{
- struct rte_table_hash *f = table;
-
- /* Check input parameters */
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(f);
- return 0;
-}
-
-static int
-rte_table_hash_entry_add_key16_lru(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_16 *bucket;
- uint64_t signature, pos;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket = (struct rte_bucket_4_16 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- memcpy(bucket_data, entry, f->entry_size);
- lru_update(bucket, i);
- *key_found = 1;
- *entry_ptr = (void *) bucket_data;
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if (bucket_signature == 0) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- bucket->signature[i] = signature;
- keycpy(bucket_key, key, f->key_mask);
- memcpy(bucket_data, entry, f->entry_size);
- lru_update(bucket, i);
- *key_found = 0;
- *entry_ptr = (void *) bucket_data;
-
- return 0;
- }
- }
-
- /* Bucket full: replace LRU entry */
- pos = lru_pos(bucket);
- bucket->signature[pos] = signature;
- keycpy(&bucket->key[pos], key, f->key_mask);
- memcpy(&bucket->data[pos * f->entry_size], entry, f->entry_size);
- lru_update(bucket, pos);
- *key_found = 0;
- *entry_ptr = (void *) &bucket->data[pos * f->entry_size];
-
- return 0;
-}
-
-static int
-rte_table_hash_entry_delete_key16_lru(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_16 *bucket;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket = (struct rte_bucket_4_16 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- bucket->signature[i] = 0;
- *key_found = 1;
- if (entry)
- memcpy(entry, bucket_data, f->entry_size);
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-static void *
-rte_table_hash_create_key16_ext(void *params,
- int socket_id,
- uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *f;
- uint64_t bucket_size, stack_size, total_size;
- uint32_t n_buckets_ext, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_16) % 64) != 0))
- return NULL;
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of bucket extensions (n_buckets_ext) so that
- * it is guaranteed that n_keys keys can be stored in the table at any time.
- *
- * The worst case scenario takes place when all the n_keys keys fall into
- * the same bucket. Actually, due to the KEYS_PER_BUCKET scheme, the worst
- * case takes place when (n_keys - KEYS_PER_BUCKET + 1) keys fall into the
- * same bucket, while the remaining (KEYS_PER_BUCKET - 1) keys each fall
- * into a different bucket. This case defeats the purpose of the hash table.
- * It indicates unsuitable f_hash or n_keys to n_buckets ratio.
- *
- * n_buckets_ext = n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1
- */
- n_buckets_ext = p->n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1;
-
- /* Memory allocation */
- bucket_size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_bucket_4_16) +
- KEYS_PER_BUCKET * entry_size);
- stack_size = RTE_CACHE_LINE_ROUNDUP(n_buckets_ext * sizeof(uint32_t));
- total_size = sizeof(struct rte_table_hash) +
- (p->n_buckets + n_buckets_ext) * bucket_size + stack_size;
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- f = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
- TABLE_LOG(INFO, "%s: Hash table %s memory footprint "
- "is %" PRIu64 " bytes",
- __func__, p->name, total_size);
-
- /* Memory initialization */
- f->n_buckets = p->n_buckets;
- f->key_size = KEY_SIZE;
- f->entry_size = entry_size;
- f->bucket_size = bucket_size;
- f->key_offset = p->key_offset;
- f->f_hash = p->f_hash;
- f->seed = p->seed;
-
- f->n_buckets_ext = n_buckets_ext;
- f->stack_pos = n_buckets_ext;
- f->stack = (uint32_t *)
- &f->memory[(p->n_buckets + n_buckets_ext) * f->bucket_size];
-
- if (p->key_mask != NULL) {
- f->key_mask[0] = (((uint64_t *)p->key_mask)[0]);
- f->key_mask[1] = (((uint64_t *)p->key_mask)[1]);
- } else {
- f->key_mask[0] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[1] = 0xFFFFFFFFFFFFFFFFLLU;
- }
-
- for (i = 0; i < n_buckets_ext; i++)
- f->stack[i] = i;
-
- return f;
-}
-
-static int
-rte_table_hash_free_key16_ext(void *table)
-{
- struct rte_table_hash *f = table;
-
- /* Check input parameters */
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(f);
- return 0;
-}
-
-static int
-rte_table_hash_entry_add_key16_ext(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_16 *bucket0, *bucket, *bucket_prev;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket0 = (struct rte_bucket_4_16 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (bucket = bucket0; bucket != NULL; bucket = bucket->next)
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- memcpy(bucket_data, entry, f->entry_size);
- *key_found = 1;
- *entry_ptr = (void *) bucket_data;
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- for (bucket_prev = NULL, bucket = bucket0; bucket != NULL;
- bucket_prev = bucket, bucket = bucket->next)
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if (bucket_signature == 0) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- bucket->signature[i] = signature;
- keycpy(bucket_key, key, f->key_mask);
- memcpy(bucket_data, entry, f->entry_size);
- *key_found = 0;
- *entry_ptr = (void *) bucket_data;
-
- return 0;
- }
- }
-
- /* Bucket full: extend bucket */
- if (f->stack_pos > 0) {
- bucket_index = f->stack[--f->stack_pos];
-
- bucket = (struct rte_bucket_4_16 *) &f->memory[(f->n_buckets +
- bucket_index) * f->bucket_size];
- bucket_prev->next = bucket;
- bucket_prev->next_valid = 1;
-
- bucket->signature[0] = signature;
- keycpy(&bucket->key[0], key, f->key_mask);
- memcpy(&bucket->data[0], entry, f->entry_size);
- *key_found = 0;
- *entry_ptr = (void *) &bucket->data[0];
- return 0;
- }
-
- return -ENOSPC;
-}
-
-static int
-rte_table_hash_entry_delete_key16_ext(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_16 *bucket0, *bucket, *bucket_prev;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket0 = (struct rte_bucket_4_16 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (bucket_prev = NULL, bucket = bucket0; bucket != NULL;
- bucket_prev = bucket, bucket = bucket->next)
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- bucket->signature[i] = 0;
- *key_found = 1;
- if (entry)
- memcpy(entry, bucket_data, f->entry_size);
-
- if ((bucket->signature[0] == 0) &&
- (bucket->signature[1] == 0) &&
- (bucket->signature[2] == 0) &&
- (bucket->signature[3] == 0) &&
- (bucket_prev != NULL)) {
- bucket_prev->next = bucket->next;
- bucket_prev->next_valid =
- bucket->next_valid;
-
- memset(bucket, 0,
- sizeof(struct rte_bucket_4_16));
- bucket_index = (((uint8_t *)bucket -
- (uint8_t *)f->memory)/f->bucket_size) - f->n_buckets;
- f->stack[f->stack_pos++] = bucket_index;
- }
-
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-#define lookup_key16_cmp(key_in, bucket, pos, f) \
-{ \
- uint64_t xor[4][2], or[4], signature[4], k[2]; \
- \
- k[0] = key_in[0] & f->key_mask[0]; \
- k[1] = key_in[1] & f->key_mask[1]; \
- signature[0] = (~bucket->signature[0]) & 1; \
- signature[1] = (~bucket->signature[1]) & 1; \
- signature[2] = (~bucket->signature[2]) & 1; \
- signature[3] = (~bucket->signature[3]) & 1; \
- \
- xor[0][0] = k[0] ^ bucket->key[0][0]; \
- xor[0][1] = k[1] ^ bucket->key[0][1]; \
- \
- xor[1][0] = k[0] ^ bucket->key[1][0]; \
- xor[1][1] = k[1] ^ bucket->key[1][1]; \
- \
- xor[2][0] = k[0] ^ bucket->key[2][0]; \
- xor[2][1] = k[1] ^ bucket->key[2][1]; \
- \
- xor[3][0] = k[0] ^ bucket->key[3][0]; \
- xor[3][1] = k[1] ^ bucket->key[3][1]; \
- \
- or[0] = xor[0][0] | xor[0][1] | signature[0]; \
- or[1] = xor[1][0] | xor[1][1] | signature[1]; \
- or[2] = xor[2][0] | xor[2][1] | signature[2]; \
- or[3] = xor[3][0] | xor[3][1] | signature[3]; \
- \
- pos = 4; \
- if (or[0] == 0) \
- pos = 0; \
- if (or[1] == 0) \
- pos = 1; \
- if (or[2] == 0) \
- pos = 2; \
- if (or[3] == 0) \
- pos = 3; \
-}
-
-#define lookup1_stage0(pkt0_index, mbuf0, pkts, pkts_mask, f) \
-{ \
- uint64_t pkt_mask; \
- uint32_t key_offset = f->key_offset;\
- \
- pkt0_index = rte_ctz64(pkts_mask); \
- pkt_mask = 1LLU << pkt0_index; \
- pkts_mask &= ~pkt_mask; \
- \
- mbuf0 = pkts[pkt0_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf0, key_offset));\
-}
-
-#define lookup1_stage1(mbuf1, bucket1, f) \
-{ \
- uint64_t *key; \
- uint64_t signature = 0; \
- uint32_t bucket_index; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf1, f->key_offset);\
- signature = f->f_hash(key, f->key_mask, KEY_SIZE, f->seed); \
- \
- bucket_index = signature & (f->n_buckets - 1); \
- bucket1 = (struct rte_bucket_4_16 *) \
- &f->memory[bucket_index * f->bucket_size]; \
- rte_prefetch0(bucket1); \
- rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
-}
-
-#define lookup1_stage2_lru(pkt2_index, mbuf2, bucket2, \
- pkts_mask_out, entries, f) \
-{ \
- void *a; \
- uint64_t pkt_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
- lookup_key16_cmp(key, bucket2, pos, f); \
- \
- pkt_mask = (bucket2->signature[pos] & 1LLU) << pkt2_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket2->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt2_index] = a; \
- lru_update(bucket2, pos); \
-}
-
-#define lookup1_stage2_ext(pkt2_index, mbuf2, bucket2, pkts_mask_out, entries, \
- buckets_mask, buckets, keys, f) \
-{ \
- struct rte_bucket_4_16 *bucket_next; \
- void *a; \
- uint64_t pkt_mask, bucket_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
- lookup_key16_cmp(key, bucket2, pos, f); \
- \
- pkt_mask = (bucket2->signature[pos] & 1LLU) << pkt2_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket2->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt2_index] = a; \
- \
- bucket_mask = (~pkt_mask) & (bucket2->next_valid << pkt2_index);\
- buckets_mask |= bucket_mask; \
- bucket_next = bucket2->next; \
- buckets[pkt2_index] = bucket_next; \
- keys[pkt2_index] = key; \
-}
-
-#define lookup_grinder(pkt_index, buckets, keys, pkts_mask_out, entries,\
- buckets_mask, f) \
-{ \
- struct rte_bucket_4_16 *bucket, *bucket_next; \
- void *a; \
- uint64_t pkt_mask, bucket_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- bucket = buckets[pkt_index]; \
- key = keys[pkt_index]; \
- lookup_key16_cmp(key, bucket, pos, f); \
- \
- pkt_mask = (bucket->signature[pos] & 1LLU) << pkt_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt_index] = a; \
- \
- bucket_mask = (~pkt_mask) & (bucket->next_valid << pkt_index);\
- buckets_mask |= bucket_mask; \
- bucket_next = bucket->next; \
- rte_prefetch0(bucket_next); \
- rte_prefetch0((void *)(((uintptr_t) bucket_next) + RTE_CACHE_LINE_SIZE));\
- buckets[pkt_index] = bucket_next; \
- keys[pkt_index] = key; \
-}
-
-#define lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01,\
- pkts, pkts_mask, f) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- uint32_t key_offset = f->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- \
- mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- \
- mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,\
- mbuf00, mbuf01, pkts, pkts_mask, f) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- uint32_t key_offset = f->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- \
- mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset)); \
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- if (pkts_mask == 0) \
- pkt01_index = pkt00_index; \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- \
- mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset)); \
-}
-
-#define lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f) \
-{ \
- uint64_t *key10, *key11; \
- uint64_t signature10, signature11; \
- uint32_t bucket10_index, bucket11_index; \
- \
- key10 = RTE_MBUF_METADATA_UINT64_PTR(mbuf10, f->key_offset);\
- signature10 = f->f_hash(key10, f->key_mask, KEY_SIZE, f->seed);\
- bucket10_index = signature10 & (f->n_buckets - 1); \
- bucket10 = (struct rte_bucket_4_16 *) \
- &f->memory[bucket10_index * f->bucket_size]; \
- rte_prefetch0(bucket10); \
- rte_prefetch0((void *)(((uintptr_t) bucket10) + RTE_CACHE_LINE_SIZE));\
- \
- key11 = RTE_MBUF_METADATA_UINT64_PTR(mbuf11, f->key_offset);\
- signature11 = f->f_hash(key11, f->key_mask, KEY_SIZE, f->seed);\
- bucket11_index = signature11 & (f->n_buckets - 1); \
- bucket11 = (struct rte_bucket_4_16 *) \
- &f->memory[bucket11_index * f->bucket_size]; \
- rte_prefetch0(bucket11); \
- rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
-}
-
-#define lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,\
- bucket20, bucket21, pkts_mask_out, entries, f) \
-{ \
- void *a20, *a21; \
- uint64_t pkt20_mask, pkt21_mask; \
- uint64_t *key20, *key21; \
- uint32_t pos20, pos21; \
- \
- key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
- key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
- \
- lookup_key16_cmp(key20, bucket20, pos20, f); \
- lookup_key16_cmp(key21, bucket21, pos21, f); \
- \
- pkt20_mask = (bucket20->signature[pos20] & 1LLU) << pkt20_index;\
- pkt21_mask = (bucket21->signature[pos21] & 1LLU) << pkt21_index;\
- pkts_mask_out |= pkt20_mask | pkt21_mask; \
- \
- a20 = (void *) &bucket20->data[pos20 * f->entry_size]; \
- a21 = (void *) &bucket21->data[pos21 * f->entry_size]; \
- rte_prefetch0(a20); \
- rte_prefetch0(a21); \
- entries[pkt20_index] = a20; \
- entries[pkt21_index] = a21; \
- lru_update(bucket20, pos20); \
- lru_update(bucket21, pos21); \
-}
-
-#define lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21, bucket20, \
- bucket21, pkts_mask_out, entries, buckets_mask, buckets, keys, f) \
-{ \
- struct rte_bucket_4_16 *bucket20_next, *bucket21_next; \
- void *a20, *a21; \
- uint64_t pkt20_mask, pkt21_mask, bucket20_mask, bucket21_mask;\
- uint64_t *key20, *key21; \
- uint32_t pos20, pos21; \
- \
- key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
- key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
- \
- lookup_key16_cmp(key20, bucket20, pos20, f); \
- lookup_key16_cmp(key21, bucket21, pos21, f); \
- \
- pkt20_mask = (bucket20->signature[pos20] & 1LLU) << pkt20_index;\
- pkt21_mask = (bucket21->signature[pos21] & 1LLU) << pkt21_index;\
- pkts_mask_out |= pkt20_mask | pkt21_mask; \
- \
- a20 = (void *) &bucket20->data[pos20 * f->entry_size]; \
- a21 = (void *) &bucket21->data[pos21 * f->entry_size]; \
- rte_prefetch0(a20); \
- rte_prefetch0(a21); \
- entries[pkt20_index] = a20; \
- entries[pkt21_index] = a21; \
- \
- bucket20_mask = (~pkt20_mask) & (bucket20->next_valid << pkt20_index);\
- bucket21_mask = (~pkt21_mask) & (bucket21->next_valid << pkt21_index);\
- buckets_mask |= bucket20_mask | bucket21_mask; \
- bucket20_next = bucket20->next; \
- bucket21_next = bucket21->next; \
- buckets[pkt20_index] = bucket20_next; \
- buckets[pkt21_index] = bucket21_next; \
- keys[pkt20_index] = key20; \
- keys[pkt21_index] = key21; \
-}
-
-static int
-rte_table_hash_lookup_key16_lru(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
- struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
- struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
- uint32_t pkt00_index, pkt01_index, pkt10_index;
- uint32_t pkt11_index, pkt20_index, pkt21_index;
- uint64_t pkts_mask_out = 0;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
-
- RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(f, n_pkts_in);
-
- /* Cannot run the pipeline with less than 5 packets */
- if (rte_popcount64(pkts_mask) < 5) {
- for ( ; pkts_mask; ) {
- struct rte_bucket_4_16 *bucket;
- struct rte_mbuf *mbuf;
- uint32_t pkt_index;
-
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
- lookup1_stage1(mbuf, bucket, f);
- lookup1_stage2_lru(pkt_index, mbuf, bucket,
- pkts_mask_out, entries, f);
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in -
- rte_popcount64(pkts_mask_out));
- return 0;
- }
-
- /*
- * Pipeline fill
- *
- */
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline feed */
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries, f);
- }
-
- /*
- * Pipeline flush
- *
- */
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries, f);
-
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries, f);
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in -
- rte_popcount64(pkts_mask_out));
- return 0;
-} /* lookup LRU */
-
-static int
-rte_table_hash_lookup_key16_ext(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
- struct rte_bucket_4_16 *bucket10, *bucket11, *bucket20, *bucket21;
- struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
- uint32_t pkt00_index, pkt01_index, pkt10_index;
- uint32_t pkt11_index, pkt20_index, pkt21_index;
- uint64_t pkts_mask_out = 0, buckets_mask = 0;
- struct rte_bucket_4_16 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
-
- RTE_TABLE_HASH_KEY16_STATS_PKTS_IN_ADD(f, n_pkts_in);
-
- /* Cannot run the pipeline with less than 5 packets */
- if (rte_popcount64(pkts_mask) < 5) {
- for ( ; pkts_mask; ) {
- struct rte_bucket_4_16 *bucket;
- struct rte_mbuf *mbuf;
- uint32_t pkt_index;
-
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
- lookup1_stage1(mbuf, bucket, f);
- lookup1_stage2_ext(pkt_index, mbuf, bucket,
- pkts_mask_out, entries, buckets_mask,
- buckets, keys, f);
- }
-
- goto grind_next_buckets;
- }
-
- /*
- * Pipeline fill
- *
- */
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline feed */
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
- }
-
- /*
- * Pipeline flush
- *
- */
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
-
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
-
-grind_next_buckets:
- /* Grind next buckets */
- for ( ; buckets_mask; ) {
- uint64_t buckets_mask_next = 0;
-
- for ( ; buckets_mask; ) {
- uint32_t pkt_index;
-
- pkt_index = rte_ctz64(buckets_mask);
- buckets_mask &= ~(1LLU << pkt_index);
-
- lookup_grinder(pkt_index, buckets, keys, pkts_mask_out,
- entries, buckets_mask_next, f);
- }
-
- buckets_mask = buckets_mask_next;
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY16_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in -
- rte_popcount64(pkts_mask_out));
- return 0;
-} /* lookup EXT */
-
-static int
-rte_table_hash_key16_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_hash *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_hash_key16_lru_ops)
-struct rte_table_ops rte_table_hash_key16_lru_ops = {
- .f_create = rte_table_hash_create_key16_lru,
- .f_free = rte_table_hash_free_key16_lru,
- .f_add = rte_table_hash_entry_add_key16_lru,
- .f_delete = rte_table_hash_entry_delete_key16_lru,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_lookup_key16_lru,
- .f_stats = rte_table_hash_key16_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_table_hash_key16_ext_ops)
-struct rte_table_ops rte_table_hash_key16_ext_ops = {
- .f_create = rte_table_hash_create_key16_ext,
- .f_free = rte_table_hash_free_key16_ext,
- .f_add = rte_table_hash_entry_add_key16_ext,
- .f_delete = rte_table_hash_entry_delete_key16_ext,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_lookup_key16_ext,
- .f_stats = rte_table_hash_key16_stats_read,
-};
diff --git a/lib/table/rte_table_hash_key32.c b/lib/table/rte_table_hash_key32.c
deleted file mode 100644
index 0963f57828dd3e4420c8134496bfa2aa2ec53065..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_key32.c
+++ /dev/null
@@ -1,1223 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2017 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_hash.h"
-#include "rte_lru.h"
-
-#include "table_log.h"
-
-#define KEY_SIZE 32
-
-#define KEYS_PER_BUCKET 4
-
-#define RTE_BUCKET_ENTRY_VALID 0x1LLU
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-#ifdef RTE_ARCH_64
-struct rte_bucket_4_32 {
- /* Cache line 0 */
- uint64_t signature[4 + 1];
- uint64_t lru_list;
- struct rte_bucket_4_32 *next;
- uint64_t next_valid;
-
- /* Cache lines 1 and 2 */
- uint64_t key[4][4];
-
- /* Cache line 3 */
- uint8_t data[];
-};
-#else
-struct rte_bucket_4_32 {
- /* Cache line 0 */
- uint64_t signature[4 + 1];
- uint64_t lru_list;
- struct rte_bucket_4_32 *next;
- uint32_t pad;
- uint64_t next_valid;
-
- /* Cache lines 1 and 2 */
- uint64_t key[4][4];
-
- /* Cache line 3 */
- uint8_t data[];
-};
-#endif
-
-struct rte_table_hash {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t n_buckets;
- uint32_t key_size;
- uint32_t entry_size;
- uint32_t bucket_size;
- uint32_t key_offset;
- uint64_t key_mask[4];
- rte_table_hash_op_hash f_hash;
- uint64_t seed;
-
- /* Extendible buckets */
- uint32_t n_buckets_ext;
- uint32_t stack_pos;
- uint32_t *stack;
-
- /* Lookup table */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static int
-keycmp(void *a, void *b, void *b_mask)
-{
- uint64_t *a64 = a, *b64 = b, *b_mask64 = b_mask;
-
- return (a64[0] != (b64[0] & b_mask64[0])) ||
- (a64[1] != (b64[1] & b_mask64[1])) ||
- (a64[2] != (b64[2] & b_mask64[2])) ||
- (a64[3] != (b64[3] & b_mask64[3]));
-}
-
-static void
-keycpy(void *dst, void *src, void *src_mask)
-{
- uint64_t *dst64 = dst, *src64 = src, *src_mask64 = src_mask;
-
- dst64[0] = src64[0] & src_mask64[0];
- dst64[1] = src64[1] & src_mask64[1];
- dst64[2] = src64[2] & src_mask64[2];
- dst64[3] = src64[3] & src_mask64[3];
-}
-
-static int
-check_params_create(struct rte_table_hash_params *params)
-{
- /* name */
- if (params->name == NULL) {
- TABLE_LOG(ERR, "%s: name invalid value", __func__);
- return -EINVAL;
- }
-
- /* key_size */
- if (params->key_size != KEY_SIZE) {
- TABLE_LOG(ERR, "%s: key_size invalid value", __func__);
- return -EINVAL;
- }
-
- /* n_keys */
- if (params->n_keys == 0) {
- TABLE_LOG(ERR, "%s: n_keys is zero", __func__);
- return -EINVAL;
- }
-
- /* n_buckets */
- if ((params->n_buckets == 0) ||
- (!rte_is_power_of_2(params->n_buckets))) {
- TABLE_LOG(ERR, "%s: n_buckets invalid value", __func__);
- return -EINVAL;
- }
-
- /* f_hash */
- if (params->f_hash == NULL) {
- TABLE_LOG(ERR, "%s: f_hash function pointer is NULL",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void *
-rte_table_hash_create_key32_lru(void *params,
- int socket_id,
- uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *f;
- uint64_t bucket_size, total_size;
- uint32_t n_buckets, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_32) % 64) != 0))
- return NULL;
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of buckets (n_buckets) so that there a chance
- * to store n_keys keys in the table.
- *
- * Note: Since the buckets do not get extended, it is not possible to
- * guarantee that n_keys keys can be stored in the table at any time. In the
- * worst case scenario when all the n_keys fall into the same bucket, only
- * a maximum of KEYS_PER_BUCKET keys will be stored in the table. This case
- * defeats the purpose of the hash table. It indicates unsuitable f_hash or
- * n_keys to n_buckets ratio.
- *
- * MIN(n_buckets) = (n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET
- */
- n_buckets = rte_align32pow2(
- (p->n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET);
- n_buckets = RTE_MAX(n_buckets, p->n_buckets);
-
- /* Memory allocation */
- bucket_size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_bucket_4_32) +
- KEYS_PER_BUCKET * entry_size);
- total_size = sizeof(struct rte_table_hash) + n_buckets * bucket_size;
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- f = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
- TABLE_LOG(INFO,
- "%s: Hash table %s memory footprint "
- "is %" PRIu64 " bytes",
- __func__, p->name, total_size);
-
- /* Memory initialization */
- f->n_buckets = n_buckets;
- f->key_size = KEY_SIZE;
- f->entry_size = entry_size;
- f->bucket_size = bucket_size;
- f->key_offset = p->key_offset;
- f->f_hash = p->f_hash;
- f->seed = p->seed;
-
- if (p->key_mask != NULL) {
- f->key_mask[0] = ((uint64_t *)p->key_mask)[0];
- f->key_mask[1] = ((uint64_t *)p->key_mask)[1];
- f->key_mask[2] = ((uint64_t *)p->key_mask)[2];
- f->key_mask[3] = ((uint64_t *)p->key_mask)[3];
- } else {
- f->key_mask[0] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[1] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[2] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[3] = 0xFFFFFFFFFFFFFFFFLLU;
- }
-
- for (i = 0; i < n_buckets; i++) {
- struct rte_bucket_4_32 *bucket;
-
- bucket = (struct rte_bucket_4_32 *) &f->memory[i *
- f->bucket_size];
- bucket->lru_list = 0x0000000100020003LLU;
- }
-
- return f;
-}
-
-static int
-rte_table_hash_free_key32_lru(void *table)
-{
- struct rte_table_hash *f = table;
-
- /* Check input parameters */
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(f);
- return 0;
-}
-
-static int
-rte_table_hash_entry_add_key32_lru(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_32 *bucket;
- uint64_t signature, pos;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket = (struct rte_bucket_4_32 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- memcpy(bucket_data, entry, f->entry_size);
- lru_update(bucket, i);
- *key_found = 1;
- *entry_ptr = (void *) bucket_data;
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if (bucket_signature == 0) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- bucket->signature[i] = signature;
- keycpy(bucket_key, key, f->key_mask);
- memcpy(bucket_data, entry, f->entry_size);
- lru_update(bucket, i);
- *key_found = 0;
- *entry_ptr = (void *) bucket_data;
-
- return 0;
- }
- }
-
- /* Bucket full: replace LRU entry */
- pos = lru_pos(bucket);
- bucket->signature[pos] = signature;
- keycpy(&bucket->key[pos], key, f->key_mask);
- memcpy(&bucket->data[pos * f->entry_size], entry, f->entry_size);
- lru_update(bucket, pos);
- *key_found = 0;
- *entry_ptr = (void *) &bucket->data[pos * f->entry_size];
-
- return 0;
-}
-
-static int
-rte_table_hash_entry_delete_key32_lru(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_32 *bucket;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket = (struct rte_bucket_4_32 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- bucket->signature[i] = 0;
- *key_found = 1;
- if (entry)
- memcpy(entry, bucket_data, f->entry_size);
-
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-static void *
-rte_table_hash_create_key32_ext(void *params,
- int socket_id,
- uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *f;
- uint64_t bucket_size, stack_size, total_size;
- uint32_t n_buckets_ext, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_32) % 64) != 0))
- return NULL;
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of bucket extensions (n_buckets_ext) so that
- * it is guaranteed that n_keys keys can be stored in the table at any time.
- *
- * The worst case scenario takes place when all the n_keys keys fall into
- * the same bucket. Actually, due to the KEYS_PER_BUCKET scheme, the worst
- * case takes place when (n_keys - KEYS_PER_BUCKET + 1) keys fall into the
- * same bucket, while the remaining (KEYS_PER_BUCKET - 1) keys each fall
- * into a different bucket. This case defeats the purpose of the hash table.
- * It indicates unsuitable f_hash or n_keys to n_buckets ratio.
- *
- * n_buckets_ext = n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1
- */
- n_buckets_ext = p->n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1;
-
- /* Memory allocation */
- bucket_size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_bucket_4_32) +
- KEYS_PER_BUCKET * entry_size);
- stack_size = RTE_CACHE_LINE_ROUNDUP(n_buckets_ext * sizeof(uint32_t));
- total_size = sizeof(struct rte_table_hash) +
- (p->n_buckets + n_buckets_ext) * bucket_size + stack_size;
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- f = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
- TABLE_LOG(INFO,
- "%s: Hash table %s memory footprint "
- "is %" PRIu64" bytes",
- __func__, p->name, total_size);
-
- /* Memory initialization */
- f->n_buckets = p->n_buckets;
- f->key_size = KEY_SIZE;
- f->entry_size = entry_size;
- f->bucket_size = bucket_size;
- f->key_offset = p->key_offset;
- f->f_hash = p->f_hash;
- f->seed = p->seed;
-
- f->n_buckets_ext = n_buckets_ext;
- f->stack_pos = n_buckets_ext;
- f->stack = (uint32_t *)
- &f->memory[(p->n_buckets + n_buckets_ext) * f->bucket_size];
-
- if (p->key_mask != NULL) {
- f->key_mask[0] = (((uint64_t *)p->key_mask)[0]);
- f->key_mask[1] = (((uint64_t *)p->key_mask)[1]);
- f->key_mask[2] = (((uint64_t *)p->key_mask)[2]);
- f->key_mask[3] = (((uint64_t *)p->key_mask)[3]);
- } else {
- f->key_mask[0] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[1] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[2] = 0xFFFFFFFFFFFFFFFFLLU;
- f->key_mask[3] = 0xFFFFFFFFFFFFFFFFLLU;
- }
-
- for (i = 0; i < n_buckets_ext; i++)
- f->stack[i] = i;
-
- return f;
-}
-
-static int
-rte_table_hash_free_key32_ext(void *table)
-{
- struct rte_table_hash *f = table;
-
- /* Check input parameters */
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(f);
- return 0;
-}
-
-static int
-rte_table_hash_entry_add_key32_ext(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_32 *bucket0, *bucket, *bucket_prev;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket0 = (struct rte_bucket_4_32 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (bucket = bucket0; bucket != NULL; bucket = bucket->next) {
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- memcpy(bucket_data, entry, f->entry_size);
- *key_found = 1;
- *entry_ptr = (void *) bucket_data;
-
- return 0;
- }
- }
- }
-
- /* Key is not present in the bucket */
- for (bucket_prev = NULL, bucket = bucket0; bucket != NULL;
- bucket_prev = bucket, bucket = bucket->next)
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if (bucket_signature == 0) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- bucket->signature[i] = signature;
- keycpy(bucket_key, key, f->key_mask);
- memcpy(bucket_data, entry, f->entry_size);
- *key_found = 0;
- *entry_ptr = (void *) bucket_data;
-
- return 0;
- }
- }
-
- /* Bucket full: extend bucket */
- if (f->stack_pos > 0) {
- bucket_index = f->stack[--f->stack_pos];
-
- bucket = (struct rte_bucket_4_32 *)
- &f->memory[(f->n_buckets + bucket_index) *
- f->bucket_size];
- bucket_prev->next = bucket;
- bucket_prev->next_valid = 1;
-
- bucket->signature[0] = signature;
- keycpy(&bucket->key[0], key, f->key_mask);
- memcpy(&bucket->data[0], entry, f->entry_size);
- *key_found = 0;
- *entry_ptr = (void *) &bucket->data[0];
- return 0;
- }
-
- return -ENOSPC;
-}
-
-static int
-rte_table_hash_entry_delete_key32_ext(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_32 *bucket0, *bucket, *bucket_prev;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket0 = (struct rte_bucket_4_32 *)
- &f->memory[bucket_index * f->bucket_size];
- signature |= RTE_BUCKET_ENTRY_VALID;
-
- /* Key is present in the bucket */
- for (bucket_prev = NULL, bucket = bucket0; bucket != NULL;
- bucket_prev = bucket, bucket = bucket->next)
- for (i = 0; i < 4; i++) {
- uint64_t bucket_signature = bucket->signature[i];
- uint8_t *bucket_key = (uint8_t *) &bucket->key[i];
-
- if ((bucket_signature == signature) &&
- (keycmp(bucket_key, key, f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- bucket->signature[i] = 0;
- *key_found = 1;
- if (entry)
- memcpy(entry, bucket_data, f->entry_size);
-
- if ((bucket->signature[0] == 0) &&
- (bucket->signature[1] == 0) &&
- (bucket->signature[2] == 0) &&
- (bucket->signature[3] == 0) &&
- (bucket_prev != NULL)) {
- bucket_prev->next = bucket->next;
- bucket_prev->next_valid =
- bucket->next_valid;
-
- memset(bucket, 0,
- sizeof(struct rte_bucket_4_32));
- bucket_index = (((uint8_t *)bucket -
- (uint8_t *)f->memory)/f->bucket_size) - f->n_buckets;
- f->stack[f->stack_pos++] = bucket_index;
- }
-
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-#define lookup_key32_cmp(key_in, bucket, pos, f) \
-{ \
- uint64_t xor[4][4], or[4], signature[4], k[4]; \
- \
- k[0] = key_in[0] & f->key_mask[0]; \
- k[1] = key_in[1] & f->key_mask[1]; \
- k[2] = key_in[2] & f->key_mask[2]; \
- k[3] = key_in[3] & f->key_mask[3]; \
- \
- signature[0] = ((~bucket->signature[0]) & 1); \
- signature[1] = ((~bucket->signature[1]) & 1); \
- signature[2] = ((~bucket->signature[2]) & 1); \
- signature[3] = ((~bucket->signature[3]) & 1); \
- \
- xor[0][0] = k[0] ^ bucket->key[0][0]; \
- xor[0][1] = k[1] ^ bucket->key[0][1]; \
- xor[0][2] = k[2] ^ bucket->key[0][2]; \
- xor[0][3] = k[3] ^ bucket->key[0][3]; \
- \
- xor[1][0] = k[0] ^ bucket->key[1][0]; \
- xor[1][1] = k[1] ^ bucket->key[1][1]; \
- xor[1][2] = k[2] ^ bucket->key[1][2]; \
- xor[1][3] = k[3] ^ bucket->key[1][3]; \
- \
- xor[2][0] = k[0] ^ bucket->key[2][0]; \
- xor[2][1] = k[1] ^ bucket->key[2][1]; \
- xor[2][2] = k[2] ^ bucket->key[2][2]; \
- xor[2][3] = k[3] ^ bucket->key[2][3]; \
- \
- xor[3][0] = k[0] ^ bucket->key[3][0]; \
- xor[3][1] = k[1] ^ bucket->key[3][1]; \
- xor[3][2] = k[2] ^ bucket->key[3][2]; \
- xor[3][3] = k[3] ^ bucket->key[3][3]; \
- \
- or[0] = xor[0][0] | xor[0][1] | xor[0][2] | xor[0][3] | signature[0];\
- or[1] = xor[1][0] | xor[1][1] | xor[1][2] | xor[1][3] | signature[1];\
- or[2] = xor[2][0] | xor[2][1] | xor[2][2] | xor[2][3] | signature[2];\
- or[3] = xor[3][0] | xor[3][1] | xor[3][2] | xor[3][3] | signature[3];\
- \
- pos = 4; \
- if (or[0] == 0) \
- pos = 0; \
- if (or[1] == 0) \
- pos = 1; \
- if (or[2] == 0) \
- pos = 2; \
- if (or[3] == 0) \
- pos = 3; \
-}
-
-#define lookup1_stage0(pkt0_index, mbuf0, pkts, pkts_mask, f) \
-{ \
- uint64_t pkt_mask; \
- uint32_t key_offset = f->key_offset; \
- \
- pkt0_index = rte_ctz64(pkts_mask); \
- pkt_mask = 1LLU << pkt0_index; \
- pkts_mask &= ~pkt_mask; \
- \
- mbuf0 = pkts[pkt0_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf0, key_offset));\
-}
-
-#define lookup1_stage1(mbuf1, bucket1, f) \
-{ \
- uint64_t *key; \
- uint64_t signature; \
- uint32_t bucket_index; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf1, f->key_offset); \
- signature = f->f_hash(key, f->key_mask, KEY_SIZE, f->seed); \
- \
- bucket_index = signature & (f->n_buckets - 1); \
- bucket1 = (struct rte_bucket_4_32 *) \
- &f->memory[bucket_index * f->bucket_size]; \
- rte_prefetch0(bucket1); \
- rte_prefetch0((void *)(((uintptr_t) bucket1) + RTE_CACHE_LINE_SIZE));\
- rte_prefetch0((void *)(((uintptr_t) bucket1) + 2 * RTE_CACHE_LINE_SIZE));\
-}
-
-#define lookup1_stage2_lru(pkt2_index, mbuf2, bucket2, \
- pkts_mask_out, entries, f) \
-{ \
- void *a; \
- uint64_t pkt_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
- lookup_key32_cmp(key, bucket2, pos, f); \
- \
- pkt_mask = (bucket2->signature[pos] & 1LLU) << pkt2_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket2->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt2_index] = a; \
- lru_update(bucket2, pos); \
-}
-
-#define lookup1_stage2_ext(pkt2_index, mbuf2, bucket2, pkts_mask_out,\
- entries, buckets_mask, buckets, keys, f) \
-{ \
- struct rte_bucket_4_32 *bucket_next; \
- void *a; \
- uint64_t pkt_mask, bucket_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
- lookup_key32_cmp(key, bucket2, pos, f); \
- \
- pkt_mask = (bucket2->signature[pos] & 1LLU) << pkt2_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket2->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt2_index] = a; \
- \
- bucket_mask = (~pkt_mask) & (bucket2->next_valid << pkt2_index);\
- buckets_mask |= bucket_mask; \
- bucket_next = bucket2->next; \
- buckets[pkt2_index] = bucket_next; \
- keys[pkt2_index] = key; \
-}
-
-#define lookup_grinder(pkt_index, buckets, keys, pkts_mask_out, \
- entries, buckets_mask, f) \
-{ \
- struct rte_bucket_4_32 *bucket, *bucket_next; \
- void *a; \
- uint64_t pkt_mask, bucket_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- bucket = buckets[pkt_index]; \
- key = keys[pkt_index]; \
- \
- lookup_key32_cmp(key, bucket, pos, f); \
- \
- pkt_mask = (bucket->signature[pos] & 1LLU) << pkt_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt_index] = a; \
- \
- bucket_mask = (~pkt_mask) & (bucket->next_valid << pkt_index);\
- buckets_mask |= bucket_mask; \
- bucket_next = bucket->next; \
- rte_prefetch0(bucket_next); \
- rte_prefetch0((void *)(((uintptr_t) bucket_next) + RTE_CACHE_LINE_SIZE));\
- rte_prefetch0((void *)(((uintptr_t) bucket_next) + \
- 2 * RTE_CACHE_LINE_SIZE)); \
- buckets[pkt_index] = bucket_next; \
- keys[pkt_index] = key; \
-}
-
-#define lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01,\
- pkts, pkts_mask, f) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- uint32_t key_offset = f->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- \
- mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- \
- mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,\
- mbuf00, mbuf01, pkts, pkts_mask, f) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- uint32_t key_offset = f->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- \
- mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset)); \
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- if (pkts_mask == 0) \
- pkt01_index = pkt00_index; \
- \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- \
- mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset)); \
-}
-
-#define lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f) \
-{ \
- uint64_t *key10, *key11; \
- uint64_t signature10, signature11; \
- uint32_t bucket10_index, bucket11_index; \
- \
- key10 = RTE_MBUF_METADATA_UINT64_PTR(mbuf10, f->key_offset); \
- signature10 = f->f_hash(key10, f->key_mask, KEY_SIZE, f->seed); \
- \
- bucket10_index = signature10 & (f->n_buckets - 1); \
- bucket10 = (struct rte_bucket_4_32 *) \
- &f->memory[bucket10_index * f->bucket_size]; \
- rte_prefetch0(bucket10); \
- rte_prefetch0((void *)(((uintptr_t) bucket10) + RTE_CACHE_LINE_SIZE));\
- rte_prefetch0((void *)(((uintptr_t) bucket10) + 2 * RTE_CACHE_LINE_SIZE));\
- \
- key11 = RTE_MBUF_METADATA_UINT64_PTR(mbuf11, f->key_offset); \
- signature11 = f->f_hash(key11, f->key_mask, KEY_SIZE, f->seed);\
- \
- bucket11_index = signature11 & (f->n_buckets - 1); \
- bucket11 = (struct rte_bucket_4_32 *) \
- &f->memory[bucket11_index * f->bucket_size]; \
- rte_prefetch0(bucket11); \
- rte_prefetch0((void *)(((uintptr_t) bucket11) + RTE_CACHE_LINE_SIZE));\
- rte_prefetch0((void *)(((uintptr_t) bucket11) + 2 * RTE_CACHE_LINE_SIZE));\
-}
-
-#define lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,\
- bucket20, bucket21, pkts_mask_out, entries, f) \
-{ \
- void *a20, *a21; \
- uint64_t pkt20_mask, pkt21_mask; \
- uint64_t *key20, *key21; \
- uint32_t pos20, pos21; \
- \
- key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
- key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
- \
- lookup_key32_cmp(key20, bucket20, pos20, f); \
- lookup_key32_cmp(key21, bucket21, pos21, f); \
- \
- pkt20_mask = (bucket20->signature[pos20] & 1LLU) << pkt20_index;\
- pkt21_mask = (bucket21->signature[pos21] & 1LLU) << pkt21_index;\
- pkts_mask_out |= pkt20_mask | pkt21_mask; \
- \
- a20 = (void *) &bucket20->data[pos20 * f->entry_size]; \
- a21 = (void *) &bucket21->data[pos21 * f->entry_size]; \
- rte_prefetch0(a20); \
- rte_prefetch0(a21); \
- entries[pkt20_index] = a20; \
- entries[pkt21_index] = a21; \
- lru_update(bucket20, pos20); \
- lru_update(bucket21, pos21); \
-}
-
-#define lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21, bucket20, \
- bucket21, pkts_mask_out, entries, buckets_mask, buckets, keys, f)\
-{ \
- struct rte_bucket_4_32 *bucket20_next, *bucket21_next; \
- void *a20, *a21; \
- uint64_t pkt20_mask, pkt21_mask, bucket20_mask, bucket21_mask;\
- uint64_t *key20, *key21; \
- uint32_t pos20, pos21; \
- \
- key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
- key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
- \
- lookup_key32_cmp(key20, bucket20, pos20, f); \
- lookup_key32_cmp(key21, bucket21, pos21, f); \
- \
- pkt20_mask = (bucket20->signature[pos20] & 1LLU) << pkt20_index;\
- pkt21_mask = (bucket21->signature[pos21] & 1LLU) << pkt21_index;\
- pkts_mask_out |= pkt20_mask | pkt21_mask; \
- \
- a20 = (void *) &bucket20->data[pos20 * f->entry_size]; \
- a21 = (void *) &bucket21->data[pos21 * f->entry_size]; \
- rte_prefetch0(a20); \
- rte_prefetch0(a21); \
- entries[pkt20_index] = a20; \
- entries[pkt21_index] = a21; \
- \
- bucket20_mask = (~pkt20_mask) & (bucket20->next_valid << pkt20_index);\
- bucket21_mask = (~pkt21_mask) & (bucket21->next_valid << pkt21_index);\
- buckets_mask |= bucket20_mask | bucket21_mask; \
- bucket20_next = bucket20->next; \
- bucket21_next = bucket21->next; \
- buckets[pkt20_index] = bucket20_next; \
- buckets[pkt21_index] = bucket21_next; \
- keys[pkt20_index] = key20; \
- keys[pkt21_index] = key21; \
-}
-
-static int
-rte_table_hash_lookup_key32_lru(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
- struct rte_bucket_4_32 *bucket10, *bucket11, *bucket20, *bucket21;
- struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
- uint32_t pkt00_index, pkt01_index, pkt10_index;
- uint32_t pkt11_index, pkt20_index, pkt21_index;
- uint64_t pkts_mask_out = 0;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(f, n_pkts_in);
-
- /* Cannot run the pipeline with less than 5 packets */
- if (rte_popcount64(pkts_mask) < 5) {
- for ( ; pkts_mask; ) {
- struct rte_bucket_4_32 *bucket;
- struct rte_mbuf *mbuf;
- uint32_t pkt_index;
-
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
- lookup1_stage1(mbuf, bucket, f);
- lookup1_stage2_lru(pkt_index, mbuf, bucket,
- pkts_mask_out, entries, f);
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - rte_popcount64(pkts_mask_out));
- return 0;
- }
-
- /*
- * Pipeline fill
- *
- */
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline feed */
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index,
- mbuf20, mbuf21, bucket20, bucket21, pkts_mask_out,
- entries, f);
- }
-
- /*
- * Pipeline flush
- *
- */
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index,
- mbuf20, mbuf21, bucket20, bucket21, pkts_mask_out, entries, f);
-
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index,
- mbuf20, mbuf21, bucket20, bucket21, pkts_mask_out, entries, f);
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - rte_popcount64(pkts_mask_out));
- return 0;
-} /* rte_table_hash_lookup_key32_lru() */
-
-static int
-rte_table_hash_lookup_key32_ext(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
- struct rte_bucket_4_32 *bucket10, *bucket11, *bucket20, *bucket21;
- struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
- uint32_t pkt00_index, pkt01_index, pkt10_index;
- uint32_t pkt11_index, pkt20_index, pkt21_index;
- uint64_t pkts_mask_out = 0, buckets_mask = 0;
- struct rte_bucket_4_32 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_HASH_KEY32_STATS_PKTS_IN_ADD(f, n_pkts_in);
-
- /* Cannot run the pipeline with less than 5 packets */
- if (rte_popcount64(pkts_mask) < 5) {
- for ( ; pkts_mask; ) {
- struct rte_bucket_4_32 *bucket;
- struct rte_mbuf *mbuf;
- uint32_t pkt_index;
-
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
- lookup1_stage1(mbuf, bucket, f);
- lookup1_stage2_ext(pkt_index, mbuf, bucket,
- pkts_mask_out, entries, buckets_mask, buckets,
- keys, f);
- }
-
- goto grind_next_buckets;
- }
-
- /*
- * Pipeline fill
- *
- */
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline feed */
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
- }
-
- /*
- * Pipeline flush
- *
- */
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
-
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
-
-grind_next_buckets:
- /* Grind next buckets */
- for ( ; buckets_mask; ) {
- uint64_t buckets_mask_next = 0;
-
- for ( ; buckets_mask; ) {
- uint32_t pkt_index;
-
- pkt_index = rte_ctz64(buckets_mask);
- buckets_mask &= ~(1LLU << pkt_index);
-
- lookup_grinder(pkt_index, buckets, keys, pkts_mask_out,
- entries, buckets_mask_next, f);
- }
-
- buckets_mask = buckets_mask_next;
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY32_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - rte_popcount64(pkts_mask_out));
- return 0;
-} /* rte_table_hash_lookup_key32_ext() */
-
-static int
-rte_table_hash_key32_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_hash *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_hash_key32_lru_ops)
-struct rte_table_ops rte_table_hash_key32_lru_ops = {
- .f_create = rte_table_hash_create_key32_lru,
- .f_free = rte_table_hash_free_key32_lru,
- .f_add = rte_table_hash_entry_add_key32_lru,
- .f_delete = rte_table_hash_entry_delete_key32_lru,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_lookup_key32_lru,
- .f_stats = rte_table_hash_key32_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_table_hash_key32_ext_ops)
-struct rte_table_ops rte_table_hash_key32_ext_ops = {
- .f_create = rte_table_hash_create_key32_ext,
- .f_free = rte_table_hash_free_key32_ext,
- .f_add = rte_table_hash_entry_add_key32_ext,
- .f_delete = rte_table_hash_entry_delete_key32_ext,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_lookup_key32_ext,
- .f_stats = rte_table_hash_key32_stats_read,
-};
diff --git a/lib/table/rte_table_hash_key8.c b/lib/table/rte_table_hash_key8.c
deleted file mode 100644
index 5e9dcf10ee3e6ce2c545a1a7dcf1d210f425f9b0..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_key8.c
+++ /dev/null
@@ -1,1157 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2017 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_hash.h"
-#include "rte_lru.h"
-
-#include "table_log.h"
-
-#define KEY_SIZE 8
-
-#define KEYS_PER_BUCKET 4
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-#ifdef RTE_ARCH_64
-struct rte_bucket_4_8 {
- /* Cache line 0 */
- uint64_t signature;
- uint64_t lru_list;
- struct rte_bucket_4_8 *next;
- uint64_t next_valid;
-
- uint64_t key[4];
-
- /* Cache line 1 */
- uint8_t data[];
-};
-#else
-struct rte_bucket_4_8 {
- /* Cache line 0 */
- uint64_t signature;
- uint64_t lru_list;
- struct rte_bucket_4_8 *next;
- uint32_t pad;
- uint64_t next_valid;
-
- uint64_t key[4];
-
- /* Cache line 1 */
- uint8_t data[];
-};
-#endif
-
-struct rte_table_hash {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t n_buckets;
- uint32_t key_size;
- uint32_t entry_size;
- uint32_t bucket_size;
- uint32_t key_offset;
- uint64_t key_mask;
- rte_table_hash_op_hash f_hash;
- uint64_t seed;
-
- /* Extendible buckets */
- uint32_t n_buckets_ext;
- uint32_t stack_pos;
- uint32_t *stack;
-
- /* Lookup table */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static int
-keycmp(void *a, void *b, void *b_mask)
-{
- uint64_t *a64 = a, *b64 = b, *b_mask64 = b_mask;
-
- return a64[0] != (b64[0] & b_mask64[0]);
-}
-
-static void
-keycpy(void *dst, void *src, void *src_mask)
-{
- uint64_t *dst64 = dst, *src64 = src, *src_mask64 = src_mask;
-
- dst64[0] = src64[0] & src_mask64[0];
-}
-
-static int
-check_params_create(struct rte_table_hash_params *params)
-{
- /* name */
- if (params->name == NULL) {
- TABLE_LOG(ERR, "%s: name invalid value", __func__);
- return -EINVAL;
- }
-
- /* key_size */
- if (params->key_size != KEY_SIZE) {
- TABLE_LOG(ERR, "%s: key_size invalid value", __func__);
- return -EINVAL;
- }
-
- /* n_keys */
- if (params->n_keys == 0) {
- TABLE_LOG(ERR, "%s: n_keys is zero", __func__);
- return -EINVAL;
- }
-
- /* n_buckets */
- if ((params->n_buckets == 0) ||
- (!rte_is_power_of_2(params->n_buckets))) {
- TABLE_LOG(ERR, "%s: n_buckets invalid value", __func__);
- return -EINVAL;
- }
-
- /* f_hash */
- if (params->f_hash == NULL) {
- TABLE_LOG(ERR, "%s: f_hash function pointer is NULL",
- __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void *
-rte_table_hash_create_key8_lru(void *params, int socket_id, uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *f;
- uint64_t bucket_size, total_size;
- uint32_t n_buckets, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_8) % 64) != 0))
- return NULL;
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of buckets (n_buckets) so that there a chance
- * to store n_keys keys in the table.
- *
- * Note: Since the buckets do not get extended, it is not possible to
- * guarantee that n_keys keys can be stored in the table at any time. In the
- * worst case scenario when all the n_keys fall into the same bucket, only
- * a maximum of KEYS_PER_BUCKET keys will be stored in the table. This case
- * defeats the purpose of the hash table. It indicates unsuitable f_hash or
- * n_keys to n_buckets ratio.
- *
- * MIN(n_buckets) = (n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET
- */
- n_buckets = rte_align32pow2(
- (p->n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET);
- n_buckets = RTE_MAX(n_buckets, p->n_buckets);
-
- /* Memory allocation */
- bucket_size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_bucket_4_8) +
- KEYS_PER_BUCKET * entry_size);
- total_size = sizeof(struct rte_table_hash) + n_buckets * bucket_size;
-
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes"
- " for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- f = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes"
- " for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- TABLE_LOG(INFO, "%s: Hash table %s memory footprint "
- "is %" PRIu64 " bytes",
- __func__, p->name, total_size);
-
- /* Memory initialization */
- f->n_buckets = n_buckets;
- f->key_size = KEY_SIZE;
- f->entry_size = entry_size;
- f->bucket_size = bucket_size;
- f->key_offset = p->key_offset;
- f->f_hash = p->f_hash;
- f->seed = p->seed;
-
- if (p->key_mask != NULL)
- f->key_mask = ((uint64_t *)p->key_mask)[0];
- else
- f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
-
- for (i = 0; i < n_buckets; i++) {
- struct rte_bucket_4_8 *bucket;
-
- bucket = (struct rte_bucket_4_8 *) &f->memory[i *
- f->bucket_size];
- bucket->lru_list = 0x0000000100020003LLU;
- }
-
- return f;
-}
-
-static int
-rte_table_hash_free_key8_lru(void *table)
-{
- struct rte_table_hash *f = table;
-
- /* Check input parameters */
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(f);
- return 0;
-}
-
-static int
-rte_table_hash_entry_add_key8_lru(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_8 *bucket;
- uint64_t signature, mask, pos;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, &f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket = (struct rte_bucket_4_8 *)
- &f->memory[bucket_index * f->bucket_size];
-
- /* Key is present in the bucket */
- for (i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
- uint64_t bucket_signature = bucket->signature;
- uint64_t *bucket_key = &bucket->key[i];
-
- if ((bucket_signature & mask) &&
- (keycmp(bucket_key, key, &f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- memcpy(bucket_data, entry, f->entry_size);
- lru_update(bucket, i);
- *key_found = 1;
- *entry_ptr = (void *) bucket_data;
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- for (i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
- uint64_t bucket_signature = bucket->signature;
-
- if ((bucket_signature & mask) == 0) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- bucket->signature |= mask;
- keycpy(&bucket->key[i], key, &f->key_mask);
- memcpy(bucket_data, entry, f->entry_size);
- lru_update(bucket, i);
- *key_found = 0;
- *entry_ptr = (void *) bucket_data;
-
- return 0;
- }
- }
-
- /* Bucket full: replace LRU entry */
- pos = lru_pos(bucket);
- keycpy(&bucket->key[pos], key, &f->key_mask);
- memcpy(&bucket->data[pos * f->entry_size], entry, f->entry_size);
- lru_update(bucket, pos);
- *key_found = 0;
- *entry_ptr = (void *) &bucket->data[pos * f->entry_size];
-
- return 0;
-}
-
-static int
-rte_table_hash_entry_delete_key8_lru(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_8 *bucket;
- uint64_t signature, mask;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, &f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket = (struct rte_bucket_4_8 *)
- &f->memory[bucket_index * f->bucket_size];
-
- /* Key is present in the bucket */
- for (i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
- uint64_t bucket_signature = bucket->signature;
- uint64_t *bucket_key = &bucket->key[i];
-
- if ((bucket_signature & mask) &&
- (keycmp(bucket_key, key, &f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i * f->entry_size];
-
- bucket->signature &= ~mask;
- *key_found = 1;
- if (entry)
- memcpy(entry, bucket_data, f->entry_size);
-
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-static void *
-rte_table_hash_create_key8_ext(void *params, int socket_id, uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *f;
- uint64_t bucket_size, stack_size, total_size;
- uint32_t n_buckets_ext, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- ((sizeof(struct rte_bucket_4_8) % 64) != 0))
- return NULL;
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of bucket extensions (n_buckets_ext) so that
- * it is guaranteed that n_keys keys can be stored in the table at any time.
- *
- * The worst case scenario takes place when all the n_keys keys fall into
- * the same bucket. Actually, due to the KEYS_PER_BUCKET scheme, the worst
- * case takes place when (n_keys - KEYS_PER_BUCKET + 1) keys fall into the
- * same bucket, while the remaining (KEYS_PER_BUCKET - 1) keys each fall
- * into a different bucket. This case defeats the purpose of the hash table.
- * It indicates unsuitable f_hash or n_keys to n_buckets ratio.
- *
- * n_buckets_ext = n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1
- */
- n_buckets_ext = p->n_keys / KEYS_PER_BUCKET + KEYS_PER_BUCKET - 1;
-
- /* Memory allocation */
- bucket_size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_bucket_4_8) +
- KEYS_PER_BUCKET * entry_size);
- stack_size = RTE_CACHE_LINE_ROUNDUP(n_buckets_ext * sizeof(uint32_t));
- total_size = sizeof(struct rte_table_hash) +
- (p->n_buckets + n_buckets_ext) * bucket_size + stack_size;
-
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR, "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- f = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (f == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %" PRIu64 " bytes "
- "for hash table %s",
- __func__, total_size, p->name);
- return NULL;
- }
- TABLE_LOG(INFO, "%s: Hash table %s memory footprint "
- "is %" PRIu64 " bytes",
- __func__, p->name, total_size);
-
- /* Memory initialization */
- f->n_buckets = p->n_buckets;
- f->key_size = KEY_SIZE;
- f->entry_size = entry_size;
- f->bucket_size = bucket_size;
- f->key_offset = p->key_offset;
- f->f_hash = p->f_hash;
- f->seed = p->seed;
-
- f->n_buckets_ext = n_buckets_ext;
- f->stack_pos = n_buckets_ext;
- f->stack = (uint32_t *)
- &f->memory[(p->n_buckets + n_buckets_ext) * f->bucket_size];
-
- if (p->key_mask != NULL)
- f->key_mask = ((uint64_t *)p->key_mask)[0];
- else
- f->key_mask = 0xFFFFFFFFFFFFFFFFLLU;
-
- for (i = 0; i < n_buckets_ext; i++)
- f->stack[i] = i;
-
- return f;
-}
-
-static int
-rte_table_hash_free_key8_ext(void *table)
-{
- struct rte_table_hash *f = table;
-
- /* Check input parameters */
- if (f == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(f);
- return 0;
-}
-
-static int
-rte_table_hash_entry_add_key8_ext(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_8 *bucket0, *bucket, *bucket_prev;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, &f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket0 = (struct rte_bucket_4_8 *)
- &f->memory[bucket_index * f->bucket_size];
-
- /* Key is present in the bucket */
- for (bucket = bucket0; bucket != NULL; bucket = bucket->next) {
- uint64_t mask;
-
- for (i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
- uint64_t bucket_signature = bucket->signature;
- uint64_t *bucket_key = &bucket->key[i];
-
- if ((bucket_signature & mask) &&
- (keycmp(bucket_key, key, &f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- memcpy(bucket_data, entry, f->entry_size);
- *key_found = 1;
- *entry_ptr = (void *) bucket_data;
- return 0;
- }
- }
- }
-
- /* Key is not present in the bucket */
- for (bucket_prev = NULL, bucket = bucket0;
- bucket != NULL; bucket_prev = bucket, bucket = bucket->next) {
- uint64_t mask;
-
- for (i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
- uint64_t bucket_signature = bucket->signature;
-
- if ((bucket_signature & mask) == 0) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- bucket->signature |= mask;
- keycpy(&bucket->key[i], key, &f->key_mask);
- memcpy(bucket_data, entry, f->entry_size);
- *key_found = 0;
- *entry_ptr = (void *) bucket_data;
-
- return 0;
- }
- }
- }
-
- /* Bucket full: extend bucket */
- if (f->stack_pos > 0) {
- bucket_index = f->stack[--f->stack_pos];
-
- bucket = (struct rte_bucket_4_8 *) &f->memory[(f->n_buckets +
- bucket_index) * f->bucket_size];
- bucket_prev->next = bucket;
- bucket_prev->next_valid = 1;
-
- bucket->signature = 1;
- keycpy(&bucket->key[0], key, &f->key_mask);
- memcpy(&bucket->data[0], entry, f->entry_size);
- *key_found = 0;
- *entry_ptr = (void *) &bucket->data[0];
- return 0;
- }
-
- return -ENOSPC;
-}
-
-static int
-rte_table_hash_entry_delete_key8_ext(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_hash *f = table;
- struct rte_bucket_4_8 *bucket0, *bucket, *bucket_prev;
- uint64_t signature;
- uint32_t bucket_index, i;
-
- signature = f->f_hash(key, &f->key_mask, f->key_size, f->seed);
- bucket_index = signature & (f->n_buckets - 1);
- bucket0 = (struct rte_bucket_4_8 *)
- &f->memory[bucket_index * f->bucket_size];
-
- /* Key is present in the bucket */
- for (bucket_prev = NULL, bucket = bucket0; bucket != NULL;
- bucket_prev = bucket, bucket = bucket->next) {
- uint64_t mask;
-
- for (i = 0, mask = 1LLU; i < 4; i++, mask <<= 1) {
- uint64_t bucket_signature = bucket->signature;
- uint64_t *bucket_key = &bucket->key[i];
-
- if ((bucket_signature & mask) &&
- (keycmp(bucket_key, key, &f->key_mask) == 0)) {
- uint8_t *bucket_data = &bucket->data[i *
- f->entry_size];
-
- bucket->signature &= ~mask;
- *key_found = 1;
- if (entry)
- memcpy(entry, bucket_data,
- f->entry_size);
-
- if ((bucket->signature == 0) &&
- (bucket_prev != NULL)) {
- bucket_prev->next = bucket->next;
- bucket_prev->next_valid =
- bucket->next_valid;
-
- memset(bucket, 0,
- sizeof(struct rte_bucket_4_8));
- bucket_index = (((uint8_t *)bucket -
- (uint8_t *)f->memory)/f->bucket_size) - f->n_buckets;
- f->stack[f->stack_pos++] = bucket_index;
- }
-
- return 0;
- }
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-#define lookup_key8_cmp(key_in, bucket, pos, f) \
-{ \
- uint64_t xor[4], signature, k; \
- \
- signature = ~bucket->signature; \
- \
- k = key_in[0] & f->key_mask; \
- xor[0] = (k ^ bucket->key[0]) | (signature & 1); \
- xor[1] = (k ^ bucket->key[1]) | (signature & 2); \
- xor[2] = (k ^ bucket->key[2]) | (signature & 4); \
- xor[3] = (k ^ bucket->key[3]) | (signature & 8); \
- \
- pos = 4; \
- if (xor[0] == 0) \
- pos = 0; \
- if (xor[1] == 0) \
- pos = 1; \
- if (xor[2] == 0) \
- pos = 2; \
- if (xor[3] == 0) \
- pos = 3; \
-}
-
-#define lookup1_stage0(pkt0_index, mbuf0, pkts, pkts_mask, f) \
-{ \
- uint64_t pkt_mask; \
- uint32_t key_offset = f->key_offset;\
- \
- pkt0_index = rte_ctz64(pkts_mask); \
- pkt_mask = 1LLU << pkt0_index; \
- pkts_mask &= ~pkt_mask; \
- \
- mbuf0 = pkts[pkt0_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf0, key_offset)); \
-}
-
-#define lookup1_stage1(mbuf1, bucket1, f) \
-{ \
- uint64_t *key; \
- uint64_t signature; \
- uint32_t bucket_index; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf1, f->key_offset);\
- signature = f->f_hash(key, &f->key_mask, KEY_SIZE, f->seed); \
- bucket_index = signature & (f->n_buckets - 1); \
- bucket1 = (struct rte_bucket_4_8 *) \
- &f->memory[bucket_index * f->bucket_size]; \
- rte_prefetch0(bucket1); \
-}
-
-#define lookup1_stage2_lru(pkt2_index, mbuf2, bucket2, \
- pkts_mask_out, entries, f) \
-{ \
- void *a; \
- uint64_t pkt_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
- lookup_key8_cmp(key, bucket2, pos, f); \
- \
- pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket2->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt2_index] = a; \
- lru_update(bucket2, pos); \
-}
-
-#define lookup1_stage2_ext(pkt2_index, mbuf2, bucket2, pkts_mask_out,\
- entries, buckets_mask, buckets, keys, f) \
-{ \
- struct rte_bucket_4_8 *bucket_next; \
- void *a; \
- uint64_t pkt_mask, bucket_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- key = RTE_MBUF_METADATA_UINT64_PTR(mbuf2, f->key_offset);\
- lookup_key8_cmp(key, bucket2, pos, f); \
- \
- pkt_mask = ((bucket2->signature >> pos) & 1LLU) << pkt2_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket2->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt2_index] = a; \
- \
- bucket_mask = (~pkt_mask) & (bucket2->next_valid << pkt2_index);\
- buckets_mask |= bucket_mask; \
- bucket_next = bucket2->next; \
- buckets[pkt2_index] = bucket_next; \
- keys[pkt2_index] = key; \
-}
-
-#define lookup_grinder(pkt_index, buckets, keys, pkts_mask_out, entries,\
- buckets_mask, f) \
-{ \
- struct rte_bucket_4_8 *bucket, *bucket_next; \
- void *a; \
- uint64_t pkt_mask, bucket_mask; \
- uint64_t *key; \
- uint32_t pos; \
- \
- bucket = buckets[pkt_index]; \
- key = keys[pkt_index]; \
- lookup_key8_cmp(key, bucket, pos, f); \
- \
- pkt_mask = ((bucket->signature >> pos) & 1LLU) << pkt_index;\
- pkts_mask_out |= pkt_mask; \
- \
- a = (void *) &bucket->data[pos * f->entry_size]; \
- rte_prefetch0(a); \
- entries[pkt_index] = a; \
- \
- bucket_mask = (~pkt_mask) & (bucket->next_valid << pkt_index);\
- buckets_mask |= bucket_mask; \
- bucket_next = bucket->next; \
- rte_prefetch0(bucket_next); \
- buckets[pkt_index] = bucket_next; \
- keys[pkt_index] = key; \
-}
-
-#define lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01,\
- pkts, pkts_mask, f) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- uint32_t key_offset = f->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- \
- mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- \
- mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,\
- mbuf00, mbuf01, pkts, pkts_mask, f) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- uint32_t key_offset = f->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- \
- mbuf00 = pkts[pkt00_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- if (pkts_mask == 0) \
- pkt01_index = pkt00_index; \
- \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- \
- mbuf01 = pkts[pkt01_index]; \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f)\
-{ \
- uint64_t *key10, *key11; \
- uint64_t signature10, signature11; \
- uint32_t bucket10_index, bucket11_index; \
- rte_table_hash_op_hash f_hash = f->f_hash; \
- uint64_t seed = f->seed; \
- uint32_t key_offset = f->key_offset; \
- \
- key10 = RTE_MBUF_METADATA_UINT64_PTR(mbuf10, key_offset);\
- key11 = RTE_MBUF_METADATA_UINT64_PTR(mbuf11, key_offset);\
- \
- signature10 = f_hash(key10, &f->key_mask, KEY_SIZE, seed); \
- bucket10_index = signature10 & (f->n_buckets - 1); \
- bucket10 = (struct rte_bucket_4_8 *) \
- &f->memory[bucket10_index * f->bucket_size]; \
- rte_prefetch0(bucket10); \
- \
- signature11 = f_hash(key11, &f->key_mask, KEY_SIZE, seed); \
- bucket11_index = signature11 & (f->n_buckets - 1); \
- bucket11 = (struct rte_bucket_4_8 *) \
- &f->memory[bucket11_index * f->bucket_size]; \
- rte_prefetch0(bucket11); \
-}
-
-#define lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,\
- bucket20, bucket21, pkts_mask_out, entries, f) \
-{ \
- void *a20, *a21; \
- uint64_t pkt20_mask, pkt21_mask; \
- uint64_t *key20, *key21; \
- uint32_t pos20, pos21; \
- \
- key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
- key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
- \
- lookup_key8_cmp(key20, bucket20, pos20, f); \
- lookup_key8_cmp(key21, bucket21, pos21, f); \
- \
- pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
- pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
- pkts_mask_out |= pkt20_mask | pkt21_mask; \
- \
- a20 = (void *) &bucket20->data[pos20 * f->entry_size]; \
- a21 = (void *) &bucket21->data[pos21 * f->entry_size]; \
- rte_prefetch0(a20); \
- rte_prefetch0(a21); \
- entries[pkt20_index] = a20; \
- entries[pkt21_index] = a21; \
- lru_update(bucket20, pos20); \
- lru_update(bucket21, pos21); \
-}
-
-#define lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21, bucket20, \
- bucket21, pkts_mask_out, entries, buckets_mask, buckets, keys, f)\
-{ \
- struct rte_bucket_4_8 *bucket20_next, *bucket21_next; \
- void *a20, *a21; \
- uint64_t pkt20_mask, pkt21_mask, bucket20_mask, bucket21_mask;\
- uint64_t *key20, *key21; \
- uint32_t pos20, pos21; \
- \
- key20 = RTE_MBUF_METADATA_UINT64_PTR(mbuf20, f->key_offset);\
- key21 = RTE_MBUF_METADATA_UINT64_PTR(mbuf21, f->key_offset);\
- \
- lookup_key8_cmp(key20, bucket20, pos20, f); \
- lookup_key8_cmp(key21, bucket21, pos21, f); \
- \
- pkt20_mask = ((bucket20->signature >> pos20) & 1LLU) << pkt20_index;\
- pkt21_mask = ((bucket21->signature >> pos21) & 1LLU) << pkt21_index;\
- pkts_mask_out |= pkt20_mask | pkt21_mask; \
- \
- a20 = (void *) &bucket20->data[pos20 * f->entry_size]; \
- a21 = (void *) &bucket21->data[pos21 * f->entry_size]; \
- rte_prefetch0(a20); \
- rte_prefetch0(a21); \
- entries[pkt20_index] = a20; \
- entries[pkt21_index] = a21; \
- \
- bucket20_mask = (~pkt20_mask) & (bucket20->next_valid << pkt20_index);\
- bucket21_mask = (~pkt21_mask) & (bucket21->next_valid << pkt21_index);\
- buckets_mask |= bucket20_mask | bucket21_mask; \
- bucket20_next = bucket20->next; \
- bucket21_next = bucket21->next; \
- buckets[pkt20_index] = bucket20_next; \
- buckets[pkt21_index] = bucket21_next; \
- keys[pkt20_index] = key20; \
- keys[pkt21_index] = key21; \
-}
-
-static int
-rte_table_hash_lookup_key8_lru(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
- struct rte_bucket_4_8 *bucket10, *bucket11, *bucket20, *bucket21;
- struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
- uint32_t pkt00_index, pkt01_index, pkt10_index;
- uint32_t pkt11_index, pkt20_index, pkt21_index;
- uint64_t pkts_mask_out = 0;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(f, n_pkts_in);
-
- /* Cannot run the pipeline with less than 5 packets */
- if (rte_popcount64(pkts_mask) < 5) {
- for ( ; pkts_mask; ) {
- struct rte_bucket_4_8 *bucket;
- struct rte_mbuf *mbuf;
- uint32_t pkt_index;
-
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
- lookup1_stage1(mbuf, bucket, f);
- lookup1_stage2_lru(pkt_index, mbuf, bucket,
- pkts_mask_out, entries, f);
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - rte_popcount64(pkts_mask_out));
- return 0;
- }
-
- /*
- * Pipeline fill
- *
- */
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline feed */
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries, f);
- }
-
- /*
- * Pipeline flush
- *
- */
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries, f);
-
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2_lru(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries, f);
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - rte_popcount64(pkts_mask_out));
- return 0;
-} /* lookup LRU */
-
-static int
-rte_table_hash_lookup_key8_ext(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *f = (struct rte_table_hash *) table;
- struct rte_bucket_4_8 *bucket10, *bucket11, *bucket20, *bucket21;
- struct rte_mbuf *mbuf00, *mbuf01, *mbuf10, *mbuf11, *mbuf20, *mbuf21;
- uint32_t pkt00_index, pkt01_index, pkt10_index;
- uint32_t pkt11_index, pkt20_index, pkt21_index;
- uint64_t pkts_mask_out = 0, buckets_mask = 0;
- struct rte_bucket_4_8 *buckets[RTE_PORT_IN_BURST_SIZE_MAX];
- uint64_t *keys[RTE_PORT_IN_BURST_SIZE_MAX];
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_HASH_KEY8_STATS_PKTS_IN_ADD(f, n_pkts_in);
-
- /* Cannot run the pipeline with less than 5 packets */
- if (rte_popcount64(pkts_mask) < 5) {
- for ( ; pkts_mask; ) {
- struct rte_bucket_4_8 *bucket;
- struct rte_mbuf *mbuf;
- uint32_t pkt_index;
-
- lookup1_stage0(pkt_index, mbuf, pkts, pkts_mask, f);
- lookup1_stage1(mbuf, bucket, f);
- lookup1_stage2_ext(pkt_index, mbuf, bucket,
- pkts_mask_out, entries, buckets_mask,
- buckets, keys, f);
- }
-
- goto grind_next_buckets;
- }
-
- /*
- * Pipeline fill
- *
- */
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline feed */
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(pkt00_index, pkt01_index, mbuf00, mbuf01, pkts,
- pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(pkt00_index, pkt01_index,
- mbuf00, mbuf01, pkts, pkts_mask, f);
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
- }
-
- /*
- * Pipeline flush
- *
- */
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- mbuf10 = mbuf00;
- mbuf11 = mbuf01;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(mbuf10, mbuf11, bucket10, bucket11, f);
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
-
- /* Pipeline feed */
- bucket20 = bucket10;
- bucket21 = bucket11;
- mbuf20 = mbuf10;
- mbuf21 = mbuf11;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2_ext(pkt20_index, pkt21_index, mbuf20, mbuf21,
- bucket20, bucket21, pkts_mask_out, entries,
- buckets_mask, buckets, keys, f);
-
-grind_next_buckets:
- /* Grind next buckets */
- for ( ; buckets_mask; ) {
- uint64_t buckets_mask_next = 0;
-
- for ( ; buckets_mask; ) {
- uint32_t pkt_index;
-
- pkt_index = rte_ctz64(buckets_mask);
- buckets_mask &= ~(1LLU << pkt_index);
-
- lookup_grinder(pkt_index, buckets, keys, pkts_mask_out,
- entries, buckets_mask_next, f);
- }
-
- buckets_mask = buckets_mask_next;
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_KEY8_STATS_PKTS_LOOKUP_MISS(f, n_pkts_in - rte_popcount64(pkts_mask_out));
- return 0;
-} /* lookup EXT */
-
-static int
-rte_table_hash_key8_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_hash *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_hash_key8_lru_ops)
-struct rte_table_ops rte_table_hash_key8_lru_ops = {
- .f_create = rte_table_hash_create_key8_lru,
- .f_free = rte_table_hash_free_key8_lru,
- .f_add = rte_table_hash_entry_add_key8_lru,
- .f_delete = rte_table_hash_entry_delete_key8_lru,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_lookup_key8_lru,
- .f_stats = rte_table_hash_key8_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_table_hash_key8_ext_ops)
-struct rte_table_ops rte_table_hash_key8_ext_ops = {
- .f_create = rte_table_hash_create_key8_ext,
- .f_free = rte_table_hash_free_key8_ext,
- .f_add = rte_table_hash_entry_add_key8_ext,
- .f_delete = rte_table_hash_entry_delete_key8_ext,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_lookup_key8_ext,
- .f_stats = rte_table_hash_key8_stats_read,
-};
diff --git a/lib/table/rte_table_hash_lru.c b/lib/table/rte_table_hash_lru.c
deleted file mode 100644
index 548f5eebf29cea7cf9767ae4345a3fda374ab4cd..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_hash_lru.c
+++ /dev/null
@@ -1,959 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2017 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-
-#include "rte_table_hash.h"
-#include "rte_lru.h"
-
-#include "table_log.h"
-
-#define KEYS_PER_BUCKET 4
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-struct bucket {
- union {
- struct bucket *next;
- uint64_t lru_list;
- };
- uint16_t sig[KEYS_PER_BUCKET];
- uint32_t key_pos[KEYS_PER_BUCKET];
-};
-
-struct grinder {
- struct bucket *bkt;
- uint64_t sig;
- uint64_t match;
- uint64_t match_pos;
- uint32_t key_index;
-};
-
-struct rte_table_hash {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t key_size;
- uint32_t entry_size;
- uint32_t n_keys;
- uint32_t n_buckets;
- rte_table_hash_op_hash f_hash;
- uint64_t seed;
- uint32_t key_offset;
-
- /* Internal */
- uint64_t bucket_mask;
- uint32_t key_size_shl;
- uint32_t data_size_shl;
- uint32_t key_stack_tos;
-
- /* Grinder */
- struct grinder grinders[RTE_PORT_IN_BURST_SIZE_MAX];
-
- /* Tables */
- uint64_t *key_mask;
- struct bucket *buckets;
- uint8_t *key_mem;
- uint8_t *data_mem;
- uint32_t *key_stack;
-
- /* Table memory */
- alignas(RTE_CACHE_LINE_SIZE) uint8_t memory[];
-};
-
-static int
-keycmp(void *a, void *b, void *b_mask, uint32_t n_bytes)
-{
- uint64_t *a64 = a, *b64 = b, *b_mask64 = b_mask;
- uint32_t i;
-
- for (i = 0; i < n_bytes / sizeof(uint64_t); i++)
- if (a64[i] != (b64[i] & b_mask64[i]))
- return 1;
-
- return 0;
-}
-
-static void
-keycpy(void *dst, void *src, void *src_mask, uint32_t n_bytes)
-{
- uint64_t *dst64 = dst, *src64 = src, *src_mask64 = src_mask;
- uint32_t i;
-
- for (i = 0; i < n_bytes / sizeof(uint64_t); i++)
- dst64[i] = src64[i] & src_mask64[i];
-}
-
-static int
-check_params_create(struct rte_table_hash_params *params)
-{
- /* name */
- if (params->name == NULL) {
- TABLE_LOG(ERR, "%s: name invalid value", __func__);
- return -EINVAL;
- }
-
- /* key_size */
- if ((params->key_size < sizeof(uint64_t)) ||
- (!rte_is_power_of_2(params->key_size))) {
- TABLE_LOG(ERR, "%s: key_size invalid value", __func__);
- return -EINVAL;
- }
-
- /* n_keys */
- if (params->n_keys == 0) {
- TABLE_LOG(ERR, "%s: n_keys invalid value", __func__);
- return -EINVAL;
- }
-
- /* n_buckets */
- if ((params->n_buckets == 0) ||
- (!rte_is_power_of_2(params->n_buckets))) {
- TABLE_LOG(ERR, "%s: n_buckets invalid value", __func__);
- return -EINVAL;
- }
-
- /* f_hash */
- if (params->f_hash == NULL) {
- TABLE_LOG(ERR, "%s: f_hash invalid value", __func__);
- return -EINVAL;
- }
-
- return 0;
-}
-
-static void *
-rte_table_hash_lru_create(void *params, int socket_id, uint32_t entry_size)
-{
- struct rte_table_hash_params *p = params;
- struct rte_table_hash *t;
- uint64_t table_meta_sz, key_mask_sz, bucket_sz, key_sz, key_stack_sz;
- uint64_t data_sz, total_size;
- uint64_t key_mask_offset, bucket_offset, key_offset, key_stack_offset;
- uint64_t data_offset;
- uint32_t n_buckets, i;
-
- /* Check input parameters */
- if ((check_params_create(p) != 0) ||
- (!rte_is_power_of_2(entry_size)) ||
- ((sizeof(struct rte_table_hash) % RTE_CACHE_LINE_SIZE) != 0) ||
- (sizeof(struct bucket) != (RTE_CACHE_LINE_SIZE / 2))) {
- return NULL;
- }
-
- /*
- * Table dimensioning
- *
- * Objective: Pick the number of buckets (n_buckets) so that there a chance
- * to store n_keys keys in the table.
- *
- * Note: Since the buckets do not get extended, it is not possible to
- * guarantee that n_keys keys can be stored in the table at any time. In the
- * worst case scenario when all the n_keys fall into the same bucket, only
- * a maximum of KEYS_PER_BUCKET keys will be stored in the table. This case
- * defeats the purpose of the hash table. It indicates unsuitable f_hash or
- * n_keys to n_buckets ratio.
- *
- * MIN(n_buckets) = (n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET
- */
- n_buckets = rte_align32pow2(
- (p->n_keys + KEYS_PER_BUCKET - 1) / KEYS_PER_BUCKET);
- n_buckets = RTE_MAX(n_buckets, p->n_buckets);
-
- /* Memory allocation */
- table_meta_sz = RTE_CACHE_LINE_ROUNDUP(sizeof(struct rte_table_hash));
- key_mask_sz = RTE_CACHE_LINE_ROUNDUP(p->key_size);
- bucket_sz = RTE_CACHE_LINE_ROUNDUP(n_buckets * sizeof(struct bucket));
- key_sz = RTE_CACHE_LINE_ROUNDUP(p->n_keys * p->key_size);
- key_stack_sz = RTE_CACHE_LINE_ROUNDUP(p->n_keys * sizeof(uint32_t));
- data_sz = RTE_CACHE_LINE_ROUNDUP(p->n_keys * entry_size);
- total_size = table_meta_sz + key_mask_sz + bucket_sz + key_sz +
- key_stack_sz + data_sz;
-
- if (total_size > SIZE_MAX) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %" PRIu64 " bytes for hash "
- "table %s",
- __func__, total_size, p->name);
- return NULL;
- }
-
- t = rte_zmalloc_socket(p->name,
- (size_t)total_size,
- RTE_CACHE_LINE_SIZE,
- socket_id);
- if (t == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %" PRIu64 " bytes for hash "
- "table %s",
- __func__, total_size, p->name);
- return NULL;
- }
- TABLE_LOG(INFO, "%s (%u-byte key): Hash table %s memory footprint"
- " is %" PRIu64 " bytes",
- __func__, p->key_size, p->name, total_size);
-
- /* Memory initialization */
- t->key_size = p->key_size;
- t->entry_size = entry_size;
- t->n_keys = p->n_keys;
- t->n_buckets = n_buckets;
- t->f_hash = p->f_hash;
- t->seed = p->seed;
- t->key_offset = p->key_offset;
-
- /* Internal */
- t->bucket_mask = t->n_buckets - 1;
- t->key_size_shl = rte_ctz32(p->key_size);
- t->data_size_shl = rte_ctz32(entry_size);
-
- /* Tables */
- key_mask_offset = 0;
- bucket_offset = key_mask_offset + key_mask_sz;
- key_offset = bucket_offset + bucket_sz;
- key_stack_offset = key_offset + key_sz;
- data_offset = key_stack_offset + key_stack_sz;
-
- t->key_mask = (uint64_t *) &t->memory[key_mask_offset];
- t->buckets = (struct bucket *) &t->memory[bucket_offset];
- t->key_mem = &t->memory[key_offset];
- t->key_stack = (uint32_t *) &t->memory[key_stack_offset];
- t->data_mem = &t->memory[data_offset];
-
- /* Key mask */
- if (p->key_mask == NULL)
- memset(t->key_mask, 0xFF, p->key_size);
- else
- memcpy(t->key_mask, p->key_mask, p->key_size);
-
- /* Key stack */
- for (i = 0; i < t->n_keys; i++)
- t->key_stack[i] = t->n_keys - 1 - i;
- t->key_stack_tos = t->n_keys;
-
- /* LRU */
- for (i = 0; i < t->n_buckets; i++) {
- struct bucket *bkt = &t->buckets[i];
-
- lru_init(bkt);
- }
-
- return t;
-}
-
-static int
-rte_table_hash_lru_free(void *table)
-{
- struct rte_table_hash *t = table;
-
- /* Check input parameters */
- if (t == NULL)
- return -EINVAL;
-
- rte_free(t);
- return 0;
-}
-
-static int
-rte_table_hash_lru_entry_add(void *table, void *key, void *entry,
- int *key_found, void **entry_ptr)
-{
- struct rte_table_hash *t = table;
- struct bucket *bkt;
- uint64_t sig;
- uint32_t bkt_index, i;
-
- sig = t->f_hash(key, t->key_mask, t->key_size, t->seed);
- bkt_index = sig & t->bucket_mask;
- bkt = &t->buckets[bkt_index];
- sig = (sig >> 16) | 1LLU;
-
- /* Key is present in the bucket */
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
- uint32_t bkt_key_index = bkt->key_pos[i];
- uint8_t *bkt_key = &t->key_mem[bkt_key_index <<
- t->key_size_shl];
-
- if ((sig == bkt_sig) && (keycmp(bkt_key, key, t->key_mask,
- t->key_size) == 0)) {
- uint8_t *data = &t->data_mem[bkt_key_index <<
- t->data_size_shl];
-
- memcpy(data, entry, t->entry_size);
- lru_update(bkt, i);
- *key_found = 1;
- *entry_ptr = (void *) data;
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
-
- if (bkt_sig == 0) {
- uint32_t bkt_key_index;
- uint8_t *bkt_key, *data;
-
- /* Allocate new key */
- if (t->key_stack_tos == 0) {
- /* No keys available */
- return -ENOSPC;
- }
- bkt_key_index = t->key_stack[--t->key_stack_tos];
-
- /* Install new key */
- bkt_key = &t->key_mem[bkt_key_index << t->key_size_shl];
- data = &t->data_mem[bkt_key_index << t->data_size_shl];
-
- bkt->sig[i] = (uint16_t) sig;
- bkt->key_pos[i] = bkt_key_index;
- keycpy(bkt_key, key, t->key_mask, t->key_size);
- memcpy(data, entry, t->entry_size);
- lru_update(bkt, i);
-
- *key_found = 0;
- *entry_ptr = (void *) data;
- return 0;
- }
- }
-
- /* Bucket full */
- {
- uint64_t pos = lru_pos(bkt);
- uint32_t bkt_key_index = bkt->key_pos[pos];
- uint8_t *bkt_key = &t->key_mem[bkt_key_index <<
- t->key_size_shl];
- uint8_t *data = &t->data_mem[bkt_key_index << t->data_size_shl];
-
- bkt->sig[pos] = (uint16_t) sig;
- keycpy(bkt_key, key, t->key_mask, t->key_size);
- memcpy(data, entry, t->entry_size);
- lru_update(bkt, pos);
-
- *key_found = 0;
- *entry_ptr = (void *) data;
- return 0;
- }
-}
-
-static int
-rte_table_hash_lru_entry_delete(void *table, void *key, int *key_found,
- void *entry)
-{
- struct rte_table_hash *t = table;
- struct bucket *bkt;
- uint64_t sig;
- uint32_t bkt_index, i;
-
- sig = t->f_hash(key, t->key_mask, t->key_size, t->seed);
- bkt_index = sig & t->bucket_mask;
- bkt = &t->buckets[bkt_index];
- sig = (sig >> 16) | 1LLU;
-
- /* Key is present in the bucket */
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
- uint32_t bkt_key_index = bkt->key_pos[i];
- uint8_t *bkt_key = &t->key_mem[bkt_key_index <<
- t->key_size_shl];
-
- if ((sig == bkt_sig) &&
- (keycmp(bkt_key, key, t->key_mask, t->key_size) == 0)) {
- uint8_t *data = &t->data_mem[bkt_key_index <<
- t->data_size_shl];
-
- bkt->sig[i] = 0;
- t->key_stack[t->key_stack_tos++] = bkt_key_index;
- *key_found = 1;
- if (entry)
- memcpy(entry, data, t->entry_size);
- return 0;
- }
- }
-
- /* Key is not present in the bucket */
- *key_found = 0;
- return 0;
-}
-
-static int rte_table_hash_lru_lookup_unoptimized(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *t = (struct rte_table_hash *) table;
- uint64_t pkts_mask_out = 0;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(t, n_pkts_in);
-
- for ( ; pkts_mask; ) {
- struct bucket *bkt;
- struct rte_mbuf *pkt;
- uint8_t *key;
- uint64_t pkt_mask, sig;
- uint32_t pkt_index, bkt_index, i;
-
- pkt_index = rte_ctz64(pkts_mask);
- pkt_mask = 1LLU << pkt_index;
- pkts_mask &= ~pkt_mask;
-
- pkt = pkts[pkt_index];
- key = RTE_MBUF_METADATA_UINT8_PTR(pkt, t->key_offset);
- sig = (uint64_t) t->f_hash(key, t->key_mask, t->key_size, t->seed);
-
- bkt_index = sig & t->bucket_mask;
- bkt = &t->buckets[bkt_index];
- sig = (sig >> 16) | 1LLU;
-
- /* Key is present in the bucket */
- for (i = 0; i < KEYS_PER_BUCKET; i++) {
- uint64_t bkt_sig = (uint64_t) bkt->sig[i];
- uint32_t bkt_key_index = bkt->key_pos[i];
- uint8_t *bkt_key = &t->key_mem[bkt_key_index <<
- t->key_size_shl];
-
- if ((sig == bkt_sig) && (keycmp(bkt_key, key, t->key_mask,
- t->key_size) == 0)) {
- uint8_t *data = &t->data_mem[bkt_key_index <<
- t->data_size_shl];
-
- lru_update(bkt, i);
- pkts_mask_out |= pkt_mask;
- entries[pkt_index] = (void *) data;
- break;
- }
- }
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - rte_popcount64(pkts_mask_out));
- return 0;
-}
-
-/*
- * mask = match bitmask
- * match = at least one match
- * match_many = more than one match
- * match_pos = position of first match
- *
- * ----------------------------------------
- * mask match match_many match_pos
- * ----------------------------------------
- * 0000 0 0 00
- * 0001 1 0 00
- * 0010 1 0 01
- * 0011 1 1 00
- * ----------------------------------------
- * 0100 1 0 10
- * 0101 1 1 00
- * 0110 1 1 01
- * 0111 1 1 00
- * ----------------------------------------
- * 1000 1 0 11
- * 1001 1 1 00
- * 1010 1 1 01
- * 1011 1 1 00
- * ----------------------------------------
- * 1100 1 1 10
- * 1101 1 1 00
- * 1110 1 1 01
- * 1111 1 1 00
- * ----------------------------------------
- *
- * match = 1111_1111_1111_1110
- * match_many = 1111_1110_1110_1000
- * match_pos = 0001_0010_0001_0011__0001_0010_0001_0000
- *
- * match = 0xFFFELLU
- * match_many = 0xFEE8LLU
- * match_pos = 0x12131210LLU
- */
-
-#define LUT_MATCH 0xFFFELLU
-#define LUT_MATCH_MANY 0xFEE8LLU
-#define LUT_MATCH_POS 0x12131210LLU
-
-#define lookup_cmp_sig(mbuf_sig, bucket, match, match_many, match_pos)\
-{ \
- uint64_t bucket_sig[4], mask[4], mask_all; \
- \
- bucket_sig[0] = bucket->sig[0]; \
- bucket_sig[1] = bucket->sig[1]; \
- bucket_sig[2] = bucket->sig[2]; \
- bucket_sig[3] = bucket->sig[3]; \
- \
- bucket_sig[0] ^= mbuf_sig; \
- bucket_sig[1] ^= mbuf_sig; \
- bucket_sig[2] ^= mbuf_sig; \
- bucket_sig[3] ^= mbuf_sig; \
- \
- mask[0] = 0; \
- mask[1] = 0; \
- mask[2] = 0; \
- mask[3] = 0; \
- \
- if (bucket_sig[0] == 0) \
- mask[0] = 1; \
- if (bucket_sig[1] == 0) \
- mask[1] = 2; \
- if (bucket_sig[2] == 0) \
- mask[2] = 4; \
- if (bucket_sig[3] == 0) \
- mask[3] = 8; \
- \
- mask_all = (mask[0] | mask[1]) | (mask[2] | mask[3]); \
- \
- match = (LUT_MATCH >> mask_all) & 1; \
- match_many = (LUT_MATCH_MANY >> mask_all) & 1; \
- match_pos = (LUT_MATCH_POS >> (mask_all << 1)) & 3; \
-}
-
-#define lookup_cmp_key(mbuf, key, match_key, f) \
-{ \
- uint64_t *pkt_key = RTE_MBUF_METADATA_UINT64_PTR(mbuf, f->key_offset);\
- uint64_t *bkt_key = (uint64_t *) key; \
- uint64_t *key_mask = f->key_mask; \
- \
- switch (f->key_size) { \
- case 8: \
- { \
- uint64_t xor = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- match_key = 0; \
- if (xor == 0) \
- match_key = 1; \
- } \
- break; \
- \
- case 16: \
- { \
- uint64_t xor[2], or; \
- \
- xor[0] = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- xor[1] = (pkt_key[1] & key_mask[1]) ^ bkt_key[1]; \
- or = xor[0] | xor[1]; \
- match_key = 0; \
- if (or == 0) \
- match_key = 1; \
- } \
- break; \
- \
- case 32: \
- { \
- uint64_t xor[4], or; \
- \
- xor[0] = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- xor[1] = (pkt_key[1] & key_mask[1]) ^ bkt_key[1]; \
- xor[2] = (pkt_key[2] & key_mask[2]) ^ bkt_key[2]; \
- xor[3] = (pkt_key[3] & key_mask[3]) ^ bkt_key[3]; \
- or = xor[0] | xor[1] | xor[2] | xor[3]; \
- match_key = 0; \
- if (or == 0) \
- match_key = 1; \
- } \
- break; \
- \
- case 64: \
- { \
- uint64_t xor[8], or; \
- \
- xor[0] = (pkt_key[0] & key_mask[0]) ^ bkt_key[0]; \
- xor[1] = (pkt_key[1] & key_mask[1]) ^ bkt_key[1]; \
- xor[2] = (pkt_key[2] & key_mask[2]) ^ bkt_key[2]; \
- xor[3] = (pkt_key[3] & key_mask[3]) ^ bkt_key[3]; \
- xor[4] = (pkt_key[4] & key_mask[4]) ^ bkt_key[4]; \
- xor[5] = (pkt_key[5] & key_mask[5]) ^ bkt_key[5]; \
- xor[6] = (pkt_key[6] & key_mask[6]) ^ bkt_key[6]; \
- xor[7] = (pkt_key[7] & key_mask[7]) ^ bkt_key[7]; \
- or = xor[0] | xor[1] | xor[2] | xor[3] | \
- xor[4] | xor[5] | xor[6] | xor[7]; \
- match_key = 0; \
- if (or == 0) \
- match_key = 1; \
- } \
- break; \
- \
- default: \
- match_key = 0; \
- if (keycmp(bkt_key, pkt_key, key_mask, f->key_size) == 0) \
- match_key = 1; \
- } \
-}
-
-#define lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index)\
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- struct rte_mbuf *mbuf00, *mbuf01; \
- uint32_t key_offset = t->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- mbuf00 = pkts[pkt00_index]; \
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- mbuf01 = pkts[pkt01_index]; \
- \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage0_with_odd_support(t, g, pkts, pkts_mask, pkt00_index, \
- pkt01_index) \
-{ \
- uint64_t pkt00_mask, pkt01_mask; \
- struct rte_mbuf *mbuf00, *mbuf01; \
- uint32_t key_offset = t->key_offset; \
- \
- pkt00_index = rte_ctz64(pkts_mask); \
- pkt00_mask = 1LLU << pkt00_index; \
- pkts_mask &= ~pkt00_mask; \
- mbuf00 = pkts[pkt00_index]; \
- \
- pkt01_index = rte_ctz64(pkts_mask); \
- if (pkts_mask == 0) \
- pkt01_index = pkt00_index; \
- \
- pkt01_mask = 1LLU << pkt01_index; \
- pkts_mask &= ~pkt01_mask; \
- mbuf01 = pkts[pkt01_index]; \
- \
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf00, key_offset));\
- rte_prefetch0(RTE_MBUF_METADATA_UINT8_PTR(mbuf01, key_offset));\
-}
-
-#define lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index)\
-{ \
- struct grinder *g10, *g11; \
- uint64_t sig10, sig11, bkt10_index, bkt11_index; \
- struct rte_mbuf *mbuf10, *mbuf11; \
- struct bucket *bkt10, *bkt11, *buckets = t->buckets; \
- uint8_t *key10, *key11; \
- uint64_t bucket_mask = t->bucket_mask; \
- rte_table_hash_op_hash f_hash = t->f_hash; \
- uint64_t seed = t->seed; \
- uint32_t key_size = t->key_size; \
- uint32_t key_offset = t->key_offset; \
- \
- mbuf10 = pkts[pkt10_index]; \
- key10 = RTE_MBUF_METADATA_UINT8_PTR(mbuf10, key_offset);\
- sig10 = (uint64_t) f_hash(key10, t->key_mask, key_size, seed);\
- bkt10_index = sig10 & bucket_mask; \
- bkt10 = &buckets[bkt10_index]; \
- \
- mbuf11 = pkts[pkt11_index]; \
- key11 = RTE_MBUF_METADATA_UINT8_PTR(mbuf11, key_offset);\
- sig11 = (uint64_t) f_hash(key11, t->key_mask, key_size, seed);\
- bkt11_index = sig11 & bucket_mask; \
- bkt11 = &buckets[bkt11_index]; \
- \
- rte_prefetch0(bkt10); \
- rte_prefetch0(bkt11); \
- \
- g10 = &g[pkt10_index]; \
- g10->sig = sig10; \
- g10->bkt = bkt10; \
- \
- g11 = &g[pkt11_index]; \
- g11->sig = sig11; \
- g11->bkt = bkt11; \
-}
-
-#define lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many)\
-{ \
- struct grinder *g20, *g21; \
- uint64_t sig20, sig21; \
- struct bucket *bkt20, *bkt21; \
- uint8_t *key20, *key21, *key_mem = t->key_mem; \
- uint64_t match20, match21, match_many20, match_many21; \
- uint64_t match_pos20, match_pos21; \
- uint32_t key20_index, key21_index, key_size_shl = t->key_size_shl;\
- \
- g20 = &g[pkt20_index]; \
- sig20 = g20->sig; \
- bkt20 = g20->bkt; \
- sig20 = (sig20 >> 16) | 1LLU; \
- lookup_cmp_sig(sig20, bkt20, match20, match_many20, match_pos20);\
- match20 <<= pkt20_index; \
- match_many20 <<= pkt20_index; \
- key20_index = bkt20->key_pos[match_pos20]; \
- key20 = &key_mem[key20_index << key_size_shl]; \
- \
- g21 = &g[pkt21_index]; \
- sig21 = g21->sig; \
- bkt21 = g21->bkt; \
- sig21 = (sig21 >> 16) | 1LLU; \
- lookup_cmp_sig(sig21, bkt21, match21, match_many21, match_pos21);\
- match21 <<= pkt21_index; \
- match_many21 <<= pkt21_index; \
- key21_index = bkt21->key_pos[match_pos21]; \
- key21 = &key_mem[key21_index << key_size_shl]; \
- \
- rte_prefetch0(key20); \
- rte_prefetch0(key21); \
- \
- pkts_mask_match_many |= match_many20 | match_many21; \
- \
- g20->match = match20; \
- g20->match_pos = match_pos20; \
- g20->key_index = key20_index; \
- \
- g21->match = match21; \
- g21->match_pos = match_pos21; \
- g21->key_index = key21_index; \
-}
-
-#define lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out, \
- entries) \
-{ \
- struct grinder *g30, *g31; \
- struct rte_mbuf *mbuf30, *mbuf31; \
- struct bucket *bkt30, *bkt31; \
- uint8_t *key30, *key31, *key_mem = t->key_mem; \
- uint8_t *data30, *data31, *data_mem = t->data_mem; \
- uint64_t match30, match31, match_pos30, match_pos31; \
- uint64_t match_key30, match_key31, match_keys; \
- uint32_t key30_index, key31_index; \
- uint32_t key_size_shl = t->key_size_shl; \
- uint32_t data_size_shl = t->data_size_shl; \
- \
- mbuf30 = pkts[pkt30_index]; \
- g30 = &g[pkt30_index]; \
- bkt30 = g30->bkt; \
- match30 = g30->match; \
- match_pos30 = g30->match_pos; \
- key30_index = g30->key_index; \
- key30 = &key_mem[key30_index << key_size_shl]; \
- lookup_cmp_key(mbuf30, key30, match_key30, t); \
- match_key30 <<= pkt30_index; \
- match_key30 &= match30; \
- data30 = &data_mem[key30_index << data_size_shl]; \
- entries[pkt30_index] = data30; \
- \
- mbuf31 = pkts[pkt31_index]; \
- g31 = &g[pkt31_index]; \
- bkt31 = g31->bkt; \
- match31 = g31->match; \
- match_pos31 = g31->match_pos; \
- key31_index = g31->key_index; \
- key31 = &key_mem[key31_index << key_size_shl]; \
- lookup_cmp_key(mbuf31, key31, match_key31, t); \
- match_key31 <<= pkt31_index; \
- match_key31 &= match31; \
- data31 = &data_mem[key31_index << data_size_shl]; \
- entries[pkt31_index] = data31; \
- \
- rte_prefetch0(data30); \
- rte_prefetch0(data31); \
- \
- match_keys = match_key30 | match_key31; \
- pkts_mask_out |= match_keys; \
- \
- if (match_key30 == 0) \
- match_pos30 = 4; \
- lru_update(bkt30, match_pos30); \
- \
- if (match_key31 == 0) \
- match_pos31 = 4; \
- lru_update(bkt31, match_pos31); \
-}
-
-/*
- * The lookup function implements a 4-stage pipeline, with each stage processing
- * two different packets. The purpose of pipelined implementation is to hide the
- * latency of prefetching the data structures and loosen the data dependency
- * between instructions.
- *
- * p00 _______ p10 _______ p20 _______ p30 _______
- * ----->| |----->| |----->| |----->| |----->
- * | 0 | | 1 | | 2 | | 3 |
- * ----->|_______|----->|_______|----->|_______|----->|_______|----->
- * p01 p11 p21 p31
- *
- * The naming convention is:
- * pXY = packet Y of stage X, X = 0 .. 3, Y = 0 .. 1
- */
-static int rte_table_hash_lru_lookup(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_hash *t = (struct rte_table_hash *) table;
- struct grinder *g = t->grinders;
- uint64_t pkt00_index, pkt01_index, pkt10_index, pkt11_index;
- uint64_t pkt20_index, pkt21_index, pkt30_index, pkt31_index;
- uint64_t pkts_mask_out = 0, pkts_mask_match_many = 0;
- int status = 0;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_HASH_LRU_STATS_PKTS_IN_ADD(t, n_pkts_in);
-
- /* Cannot run the pipeline with less than 7 packets */
- if (rte_popcount64(pkts_mask) < 7)
- return rte_table_hash_lru_lookup_unoptimized(table, pkts,
- pkts_mask, lookup_hit_mask, entries);
-
- /* Pipeline stage 0 */
- lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index);
-
- /* Pipeline feed */
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index);
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline feed */
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0(t, g, pkts, pkts_mask, pkt00_index, pkt01_index);
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many);
-
- /*
- * Pipeline run
- *
- */
- for ( ; pkts_mask; ) {
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 0 */
- lookup2_stage0_with_odd_support(t, g, pkts, pkts_mask,
- pkt00_index, pkt01_index);
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index,
- pkts_mask_match_many);
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index,
- pkts_mask_out, entries);
- }
-
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
- pkt10_index = pkt00_index;
- pkt11_index = pkt01_index;
-
- /* Pipeline stage 1 */
- lookup2_stage1(t, g, pkts, pkt10_index, pkt11_index);
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many);
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out,
- entries);
-
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
- pkt20_index = pkt10_index;
- pkt21_index = pkt11_index;
-
- /* Pipeline stage 2 */
- lookup2_stage2(t, g, pkt20_index, pkt21_index, pkts_mask_match_many);
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out,
- entries);
-
- /* Pipeline feed */
- pkt30_index = pkt20_index;
- pkt31_index = pkt21_index;
-
- /* Pipeline stage 3 */
- lookup2_stage3(t, g, pkts, pkt30_index, pkt31_index, pkts_mask_out,
- entries);
-
- /* Slow path */
- pkts_mask_match_many &= ~pkts_mask_out;
- if (pkts_mask_match_many) {
- uint64_t pkts_mask_out_slow = 0;
-
- status = rte_table_hash_lru_lookup_unoptimized(table, pkts,
- pkts_mask_match_many, &pkts_mask_out_slow, entries);
- pkts_mask_out |= pkts_mask_out_slow;
- }
-
- *lookup_hit_mask = pkts_mask_out;
- RTE_TABLE_HASH_LRU_STATS_PKTS_LOOKUP_MISS(t, n_pkts_in - rte_popcount64(pkts_mask_out));
- return status;
-}
-
-static int
-rte_table_hash_lru_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_hash *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_hash_lru_ops)
-struct rte_table_ops rte_table_hash_lru_ops = {
- .f_create = rte_table_hash_lru_create,
- .f_free = rte_table_hash_lru_free,
- .f_add = rte_table_hash_lru_entry_add,
- .f_delete = rte_table_hash_lru_entry_delete,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_hash_lru_lookup,
- .f_stats = rte_table_hash_lru_stats_read,
-};
diff --git a/lib/table/rte_table_lpm.c b/lib/table/rte_table_lpm.c
deleted file mode 100644
index 6fd0c30f85af6e398ee25257e016262815a94a28..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_lpm.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_byteorder.h>
-#include <rte_log.h>
-#include <rte_lpm.h>
-
-#include "rte_table_lpm.h"
-
-#include "table_log.h"
-
-#ifndef RTE_TABLE_LPM_MAX_NEXT_HOPS
-#define RTE_TABLE_LPM_MAX_NEXT_HOPS 65536
-#endif
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_LPM_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_LPM_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-struct rte_table_lpm {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t entry_size;
- uint32_t entry_unique_size;
- uint32_t n_rules;
- uint32_t offset;
-
- /* Handle to low-level LPM table */
- struct rte_lpm *lpm;
-
- /* Next Hop Table (NHT) */
- uint32_t nht_users[RTE_TABLE_LPM_MAX_NEXT_HOPS];
- alignas(RTE_CACHE_LINE_SIZE) uint8_t nht[];
-};
-
-static void *
-rte_table_lpm_create(void *params, int socket_id, uint32_t entry_size)
-{
- struct rte_table_lpm_params *p = params;
- struct rte_table_lpm *lpm;
- struct rte_lpm_config lpm_config;
-
- uint32_t total_size, nht_size;
-
- /* Check input parameters */
- if (p == NULL) {
- TABLE_LOG(ERR, "%s: NULL input parameters", __func__);
- return NULL;
- }
- if (p->n_rules == 0) {
- TABLE_LOG(ERR, "%s: Invalid n_rules", __func__);
- return NULL;
- }
- if (p->number_tbl8s == 0) {
- TABLE_LOG(ERR, "%s: Invalid number_tbl8s", __func__);
- return NULL;
- }
- if (p->entry_unique_size == 0) {
- TABLE_LOG(ERR, "%s: Invalid entry_unique_size",
- __func__);
- return NULL;
- }
- if (p->entry_unique_size > entry_size) {
- TABLE_LOG(ERR, "%s: Invalid entry_unique_size",
- __func__);
- return NULL;
- }
- if (p->name == NULL) {
- TABLE_LOG(ERR, "%s: Table name is NULL",
- __func__);
- return NULL;
- }
- entry_size = RTE_ALIGN(entry_size, sizeof(uint64_t));
-
- /* Memory allocation */
- nht_size = RTE_TABLE_LPM_MAX_NEXT_HOPS * entry_size;
- total_size = sizeof(struct rte_table_lpm) + nht_size;
- lpm = rte_zmalloc_socket("TABLE", total_size, RTE_CACHE_LINE_SIZE,
- socket_id);
- if (lpm == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %u bytes for LPM table",
- __func__, total_size);
- return NULL;
- }
-
- /* LPM low-level table creation */
- lpm_config.max_rules = p->n_rules;
- lpm_config.number_tbl8s = p->number_tbl8s;
- lpm_config.flags = p->flags;
- lpm->lpm = rte_lpm_create(p->name, socket_id, &lpm_config);
-
- if (lpm->lpm == NULL) {
- rte_free(lpm);
- TABLE_LOG(ERR, "Unable to create low-level LPM table");
- return NULL;
- }
-
- /* Memory initialization */
- lpm->entry_size = entry_size;
- lpm->entry_unique_size = p->entry_unique_size;
- lpm->n_rules = p->n_rules;
- lpm->offset = p->offset;
-
- return lpm;
-}
-
-static int
-rte_table_lpm_free(void *table)
-{
- struct rte_table_lpm *lpm = table;
-
- /* Check input parameters */
- if (lpm == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free previously allocated resources */
- rte_lpm_free(lpm->lpm);
- rte_free(lpm);
-
- return 0;
-}
-
-static int
-nht_find_free(struct rte_table_lpm *lpm, uint32_t *pos)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_TABLE_LPM_MAX_NEXT_HOPS; i++) {
- if (lpm->nht_users[i] == 0) {
- *pos = i;
- return 1;
- }
- }
-
- return 0;
-}
-
-static int
-nht_find_existing(struct rte_table_lpm *lpm, void *entry, uint32_t *pos)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_TABLE_LPM_MAX_NEXT_HOPS; i++) {
- uint8_t *nht_entry = &lpm->nht[i * lpm->entry_size];
-
- if ((lpm->nht_users[i] > 0) && (memcmp(nht_entry, entry,
- lpm->entry_unique_size) == 0)) {
- *pos = i;
- return 1;
- }
- }
-
- return 0;
-}
-
-static int
-rte_table_lpm_entry_add(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_lpm *lpm = table;
- struct rte_table_lpm_key *ip_prefix = key;
- uint32_t nht_pos, nht_pos0_valid;
- int status;
- uint32_t nht_pos0 = 0;
-
- /* Check input parameters */
- if (lpm == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (ip_prefix == NULL) {
- TABLE_LOG(ERR, "%s: ip_prefix parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (entry == NULL) {
- TABLE_LOG(ERR, "%s: entry parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if ((ip_prefix->depth == 0) || (ip_prefix->depth > 32)) {
- TABLE_LOG(ERR, "%s: invalid depth (%d)",
- __func__, ip_prefix->depth);
- return -EINVAL;
- }
-
- /* Check if rule is already present in the table */
- status = rte_lpm_is_rule_present(lpm->lpm, ip_prefix->ip,
- ip_prefix->depth, &nht_pos0);
- nht_pos0_valid = status > 0;
-
- /* Find existing or free NHT entry */
- if (nht_find_existing(lpm, entry, &nht_pos) == 0) {
- uint8_t *nht_entry;
-
- if (nht_find_free(lpm, &nht_pos) == 0) {
- TABLE_LOG(ERR, "%s: NHT full", __func__);
- return -1;
- }
-
- nht_entry = &lpm->nht[nht_pos * lpm->entry_size];
- memcpy(nht_entry, entry, lpm->entry_size);
- }
-
- /* Add rule to low level LPM table */
- if (rte_lpm_add(lpm->lpm, ip_prefix->ip, ip_prefix->depth, nht_pos) < 0) {
- TABLE_LOG(ERR, "%s: LPM rule add failed", __func__);
- return -1;
- }
-
- /* Commit NHT changes */
- lpm->nht_users[nht_pos]++;
- lpm->nht_users[nht_pos0] -= nht_pos0_valid;
-
- *key_found = nht_pos0_valid;
- *entry_ptr = (void *) &lpm->nht[nht_pos * lpm->entry_size];
- return 0;
-}
-
-static int
-rte_table_lpm_entry_delete(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_lpm *lpm = table;
- struct rte_table_lpm_key *ip_prefix = key;
- uint32_t nht_pos;
- int status;
-
- /* Check input parameters */
- if (lpm == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (ip_prefix == NULL) {
- TABLE_LOG(ERR, "%s: ip_prefix parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if ((ip_prefix->depth == 0) || (ip_prefix->depth > 32)) {
- TABLE_LOG(ERR, "%s: invalid depth (%d)", __func__,
- ip_prefix->depth);
- return -EINVAL;
- }
-
- /* Return if rule is not present in the table */
- status = rte_lpm_is_rule_present(lpm->lpm, ip_prefix->ip,
- ip_prefix->depth, &nht_pos);
- if (status < 0) {
- TABLE_LOG(ERR, "%s: LPM algorithmic error", __func__);
- return -1;
- }
- if (status == 0) {
- *key_found = 0;
- return 0;
- }
-
- /* Delete rule from the low-level LPM table */
- status = rte_lpm_delete(lpm->lpm, ip_prefix->ip, ip_prefix->depth);
- if (status) {
- TABLE_LOG(ERR, "%s: LPM rule delete failed", __func__);
- return -1;
- }
-
- /* Commit NHT changes */
- lpm->nht_users[nht_pos]--;
-
- *key_found = 1;
- if (entry)
- memcpy(entry, &lpm->nht[nht_pos * lpm->entry_size],
- lpm->entry_size);
-
- return 0;
-}
-
-static int
-rte_table_lpm_lookup(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_lpm *lpm = (struct rte_table_lpm *) table;
- uint64_t pkts_out_mask = 0;
- uint32_t i;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_LPM_STATS_PKTS_IN_ADD(lpm, n_pkts_in);
-
- pkts_out_mask = 0;
- for (i = 0; i < (uint32_t)(RTE_PORT_IN_BURST_SIZE_MAX -
- rte_clz64(pkts_mask)); i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if (pkt_mask & pkts_mask) {
- struct rte_mbuf *pkt = pkts[i];
- uint32_t ip = rte_bswap32(
- RTE_MBUF_METADATA_UINT32(pkt, lpm->offset));
- int status;
- uint32_t nht_pos;
-
- status = rte_lpm_lookup(lpm->lpm, ip, &nht_pos);
- if (status == 0) {
- pkts_out_mask |= pkt_mask;
- entries[i] = (void *) &lpm->nht[nht_pos *
- lpm->entry_size];
- }
- }
- }
-
- *lookup_hit_mask = pkts_out_mask;
- RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(lpm, n_pkts_in - rte_popcount64(pkts_out_mask));
- return 0;
-}
-
-static int
-rte_table_lpm_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_lpm *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_lpm_ops)
-struct rte_table_ops rte_table_lpm_ops = {
- .f_create = rte_table_lpm_create,
- .f_free = rte_table_lpm_free,
- .f_add = rte_table_lpm_entry_add,
- .f_delete = rte_table_lpm_entry_delete,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_lpm_lookup,
- .f_stats = rte_table_lpm_stats_read,
-};
diff --git a/lib/table/rte_table_lpm.h b/lib/table/rte_table_lpm.h
deleted file mode 100644
index 59b9bdee89087e5ddfa8c7138dc89c1008f72d10..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_lpm.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_LPM_H__
-#define __INCLUDE_RTE_TABLE_LPM_H__
-
-/**
- * @file
- * RTE Table LPM for IPv4
- *
- * This table uses the Longest Prefix Match (LPM) algorithm to uniquely
- * associate data to lookup keys.
- *
- * Use-case: IP routing table. Routes that are added to the table associate a
- * next hop to an IP prefix. The IP prefix is specified as IP address and depth
- * and cover for a multitude of lookup keys (i.e. destination IP addresses)
- * that all share the same data (i.e. next hop). The next hop information
- * typically contains the output interface ID, the IP address of the next hop
- * station (which is part of the same IP network the output interface is
- * connected to) and other flags and counters.
- *
- * The LPM primitive only allows associating an 8-bit number (next hop ID) to
- * an IP prefix, while a routing table can potentially contain thousands of
- * routes or even more. This means that the same next hop ID (and next hop
- * information) has to be shared by multiple routes, which makes sense, as
- * multiple remote networks could be reached through the same next hop.
- * Therefore, when a route is added or updated, the LPM table has to check
- * whether the same next hop is already in use before using a new next hop ID
- * for this route.
- *
- * The comparison between different next hops is done for the first
- * “entry_unique_size” bytes of the next hop information (configurable
- * parameter), which have to uniquely identify the next hop, therefore the user
- * has to carefully manage the format of the LPM table entry (i.e. the next
- * hop information) so that any next hop data that changes value during
- * run-time (e.g. counters) is placed outside of this area.
- */
-
-#include <stdint.h>
-
-#include "rte_table.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** LPM table parameters */
-struct rte_table_lpm_params {
- /** Table name */
- const char *name;
-
- /** Maximum number of LPM rules (i.e. IP routes) */
- uint32_t n_rules;
-
- /**< Number of tbl8s to allocate. */
- uint32_t number_tbl8s;
-
- /**< This field is currently unused. */
- int flags;
-
- /** Number of bytes at the start of the table entry that uniquely
- identify the entry. Cannot be bigger than table entry size. */
- uint32_t entry_unique_size;
-
- /** Byte offset within input packet meta-data where lookup key (i.e.
- the destination IP address) is located. */
- uint32_t offset;
-};
-
-/** LPM table rule (i.e. route), specified as IP prefix. While the key used by
-the lookup operation is the destination IP address (read from the input packet
-meta-data), the entry add and entry delete operations work with LPM rules, with
-each rule covering for a multitude of lookup keys (destination IP addresses)
-that share the same data (next hop). */
-struct rte_table_lpm_key {
- /** IP address */
- uint32_t ip;
-
- /** IP address depth. The most significant "depth" bits of the IP
- address specify the network part of the IP address, while the rest of
- the bits specify the host part of the address and are ignored for the
- purpose of route specification. */
- uint8_t depth;
-};
-
-/** LPM table operations */
-extern struct rte_table_ops rte_table_lpm_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/rte_table_lpm_ipv6.c b/lib/table/rte_table_lpm_ipv6.c
deleted file mode 100644
index 9159784dfa3cba76aeea159866607fde833f9c24..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_lpm_ipv6.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdalign.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_log.h>
-#include <rte_lpm6.h>
-
-#include "rte_table_lpm_ipv6.h"
-
-#include "table_log.h"
-
-#define RTE_TABLE_LPM_MAX_NEXT_HOPS 256
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_LPM_IPV6_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_LPM_IPV6_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_LPM_IPV6_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_LPM_IPV6_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-struct rte_table_lpm_ipv6 {
- struct rte_table_stats stats;
-
- /* Input parameters */
- uint32_t entry_size;
- uint32_t entry_unique_size;
- uint32_t n_rules;
- uint32_t offset;
-
- /* Handle to low-level LPM table */
- struct rte_lpm6 *lpm;
-
- /* Next Hop Table (NHT) */
- uint32_t nht_users[RTE_TABLE_LPM_MAX_NEXT_HOPS];
- alignas(RTE_CACHE_LINE_SIZE) uint8_t nht[];
-};
-
-static void *
-rte_table_lpm_ipv6_create(void *params, int socket_id, uint32_t entry_size)
-{
- struct rte_table_lpm_ipv6_params *p =
- params;
- struct rte_table_lpm_ipv6 *lpm;
- struct rte_lpm6_config lpm6_config;
- uint32_t total_size, nht_size;
-
- /* Check input parameters */
- if (p == NULL) {
- TABLE_LOG(ERR, "%s: NULL input parameters", __func__);
- return NULL;
- }
- if (p->n_rules == 0) {
- TABLE_LOG(ERR, "%s: Invalid n_rules", __func__);
- return NULL;
- }
- if (p->number_tbl8s == 0) {
- TABLE_LOG(ERR, "%s: Invalid n_rules", __func__);
- return NULL;
- }
- if (p->entry_unique_size == 0) {
- TABLE_LOG(ERR, "%s: Invalid entry_unique_size",
- __func__);
- return NULL;
- }
- if (p->entry_unique_size > entry_size) {
- TABLE_LOG(ERR, "%s: Invalid entry_unique_size",
- __func__);
- return NULL;
- }
- if (p->name == NULL) {
- TABLE_LOG(ERR, "%s: Table name is NULL",
- __func__);
- return NULL;
- }
- entry_size = RTE_ALIGN(entry_size, sizeof(uint64_t));
-
- /* Memory allocation */
- nht_size = RTE_TABLE_LPM_MAX_NEXT_HOPS * entry_size;
- total_size = sizeof(struct rte_table_lpm_ipv6) + nht_size;
- lpm = rte_zmalloc_socket("TABLE", total_size, RTE_CACHE_LINE_SIZE,
- socket_id);
- if (lpm == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %u bytes for LPM IPv6 table",
- __func__, total_size);
- return NULL;
- }
-
- /* LPM low-level table creation */
- lpm6_config.max_rules = p->n_rules;
- lpm6_config.number_tbl8s = p->number_tbl8s;
- lpm6_config.flags = 0;
- lpm->lpm = rte_lpm6_create(p->name, socket_id, &lpm6_config);
- if (lpm->lpm == NULL) {
- rte_free(lpm);
- TABLE_LOG(ERR,
- "Unable to create low-level LPM IPv6 table");
- return NULL;
- }
-
- /* Memory initialization */
- lpm->entry_size = entry_size;
- lpm->entry_unique_size = p->entry_unique_size;
- lpm->n_rules = p->n_rules;
- lpm->offset = p->offset;
-
- return lpm;
-}
-
-static int
-rte_table_lpm_ipv6_free(void *table)
-{
- struct rte_table_lpm_ipv6 *lpm = table;
-
- /* Check input parameters */
- if (lpm == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
-
- /* Free previously allocated resources */
- rte_lpm6_free(lpm->lpm);
- rte_free(lpm);
-
- return 0;
-}
-
-static int
-nht_find_free(struct rte_table_lpm_ipv6 *lpm, uint32_t *pos)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_TABLE_LPM_MAX_NEXT_HOPS; i++) {
- if (lpm->nht_users[i] == 0) {
- *pos = i;
- return 1;
- }
- }
-
- return 0;
-}
-
-static int
-nht_find_existing(struct rte_table_lpm_ipv6 *lpm, void *entry, uint32_t *pos)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_TABLE_LPM_MAX_NEXT_HOPS; i++) {
- uint8_t *nht_entry = &lpm->nht[i * lpm->entry_size];
-
- if ((lpm->nht_users[i] > 0) && (memcmp(nht_entry, entry,
- lpm->entry_unique_size) == 0)) {
- *pos = i;
- return 1;
- }
- }
-
- return 0;
-}
-
-static int
-rte_table_lpm_ipv6_entry_add(
- void *table,
- void *key,
- void *entry,
- int *key_found,
- void **entry_ptr)
-{
- struct rte_table_lpm_ipv6 *lpm = table;
- struct rte_table_lpm_ipv6_key *ip_prefix =
- key;
- uint32_t nht_pos = 0, nht_pos0 = 0, nht_pos0_valid = 0;
- int status;
-
- /* Check input parameters */
- if (lpm == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (ip_prefix == NULL) {
- TABLE_LOG(ERR, "%s: ip_prefix parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if (entry == NULL) {
- TABLE_LOG(ERR, "%s: entry parameter is NULL", __func__);
- return -EINVAL;
- }
-
- if ((ip_prefix->depth == 0) || (ip_prefix->depth > 128)) {
- TABLE_LOG(ERR, "%s: invalid depth (%d)", __func__,
- ip_prefix->depth);
- return -EINVAL;
- }
-
- /* Check if rule is already present in the table */
- status = rte_lpm6_is_rule_present(lpm->lpm, &ip_prefix->ip,
- ip_prefix->depth, &nht_pos0);
- nht_pos0_valid = status > 0;
-
- /* Find existing or free NHT entry */
- if (nht_find_existing(lpm, entry, &nht_pos) == 0) {
- uint8_t *nht_entry;
-
- if (nht_find_free(lpm, &nht_pos) == 0) {
- TABLE_LOG(ERR, "%s: NHT full", __func__);
- return -1;
- }
-
- nht_entry = &lpm->nht[nht_pos * lpm->entry_size];
- memcpy(nht_entry, entry, lpm->entry_size);
- }
-
- /* Add rule to low level LPM table */
- if (rte_lpm6_add(lpm->lpm, &ip_prefix->ip, ip_prefix->depth,
- nht_pos) < 0) {
- TABLE_LOG(ERR, "%s: LPM IPv6 rule add failed", __func__);
- return -1;
- }
-
- /* Commit NHT changes */
- lpm->nht_users[nht_pos]++;
- lpm->nht_users[nht_pos0] -= nht_pos0_valid;
-
- *key_found = nht_pos0_valid;
- *entry_ptr = (void *) &lpm->nht[nht_pos * lpm->entry_size];
- return 0;
-}
-
-static int
-rte_table_lpm_ipv6_entry_delete(
- void *table,
- void *key,
- int *key_found,
- void *entry)
-{
- struct rte_table_lpm_ipv6 *lpm = table;
- struct rte_table_lpm_ipv6_key *ip_prefix =
- key;
- uint32_t nht_pos;
- int status;
-
- /* Check input parameters */
- if (lpm == NULL) {
- TABLE_LOG(ERR, "%s: table parameter is NULL", __func__);
- return -EINVAL;
- }
- if (ip_prefix == NULL) {
- TABLE_LOG(ERR, "%s: ip_prefix parameter is NULL",
- __func__);
- return -EINVAL;
- }
- if ((ip_prefix->depth == 0) || (ip_prefix->depth > 128)) {
- TABLE_LOG(ERR, "%s: invalid depth (%d)", __func__,
- ip_prefix->depth);
- return -EINVAL;
- }
-
- /* Return if rule is not present in the table */
- status = rte_lpm6_is_rule_present(lpm->lpm, &ip_prefix->ip,
- ip_prefix->depth, &nht_pos);
- if (status < 0) {
- TABLE_LOG(ERR, "%s: LPM IPv6 algorithmic error",
- __func__);
- return -1;
- }
- if (status == 0) {
- *key_found = 0;
- return 0;
- }
-
- /* Delete rule from the low-level LPM table */
- status = rte_lpm6_delete(lpm->lpm, &ip_prefix->ip, ip_prefix->depth);
- if (status) {
- TABLE_LOG(ERR, "%s: LPM IPv6 rule delete failed",
- __func__);
- return -1;
- }
-
- /* Commit NHT changes */
- lpm->nht_users[nht_pos]--;
-
- *key_found = 1;
- if (entry)
- memcpy(entry, &lpm->nht[nht_pos * lpm->entry_size],
- lpm->entry_size);
-
- return 0;
-}
-
-static int
-rte_table_lpm_ipv6_lookup(
- void *table,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- void **entries)
-{
- struct rte_table_lpm_ipv6 *lpm = (struct rte_table_lpm_ipv6 *) table;
- uint64_t pkts_out_mask = 0;
- uint32_t i;
-
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
- RTE_TABLE_LPM_IPV6_STATS_PKTS_IN_ADD(lpm, n_pkts_in);
-
- pkts_out_mask = 0;
- for (i = 0; i < (uint32_t)(RTE_PORT_IN_BURST_SIZE_MAX -
- rte_clz64(pkts_mask)); i++) {
- uint64_t pkt_mask = 1LLU << i;
-
- if (pkt_mask & pkts_mask) {
- struct rte_mbuf *pkt = pkts[i];
- const struct rte_ipv6_addr *ip;
- int status;
- uint32_t nht_pos;
-
- ip = (struct rte_ipv6_addr *)RTE_MBUF_METADATA_UINT8_PTR(pkt, lpm->offset);
- status = rte_lpm6_lookup(lpm->lpm, ip, &nht_pos);
- if (status == 0) {
- pkts_out_mask |= pkt_mask;
- entries[i] = (void *) &lpm->nht[nht_pos *
- lpm->entry_size];
- }
- }
- }
-
- *lookup_hit_mask = pkts_out_mask;
- RTE_TABLE_LPM_IPV6_STATS_PKTS_LOOKUP_MISS(lpm, n_pkts_in - rte_popcount64(pkts_out_mask));
- return 0;
-}
-
-static int
-rte_table_lpm_ipv6_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_lpm_ipv6 *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_lpm_ipv6_ops)
-struct rte_table_ops rte_table_lpm_ipv6_ops = {
- .f_create = rte_table_lpm_ipv6_create,
- .f_free = rte_table_lpm_ipv6_free,
- .f_add = rte_table_lpm_ipv6_entry_add,
- .f_delete = rte_table_lpm_ipv6_entry_delete,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_lpm_ipv6_lookup,
- .f_stats = rte_table_lpm_ipv6_stats_read,
-};
diff --git a/lib/table/rte_table_stub.c b/lib/table/rte_table_stub.c
deleted file mode 100644
index 3d2ac55c49daea8585c488d94d21960a51049e24..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_stub.c
+++ /dev/null
@@ -1,95 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_malloc.h>
-
-#include "rte_table_stub.h"
-
-#include "table_log.h"
-
-#ifdef RTE_TABLE_STATS_COLLECT
-
-#define RTE_TABLE_LPM_STATS_PKTS_IN_ADD(table, val) \
- table->stats.n_pkts_in += val
-#define RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(table, val) \
- table->stats.n_pkts_lookup_miss += val
-
-#else
-
-#define RTE_TABLE_LPM_STATS_PKTS_IN_ADD(table, val)
-#define RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(table, val)
-
-#endif
-
-struct rte_table_stub {
- struct rte_table_stats stats;
-};
-
-static void *
-rte_table_stub_create(__rte_unused void *params,
- __rte_unused int socket_id,
- __rte_unused uint32_t entry_size)
-{
- struct rte_table_stub *stub;
- uint32_t size;
-
- size = sizeof(struct rte_table_stub);
- stub = rte_zmalloc_socket("TABLE", size, RTE_CACHE_LINE_SIZE,
- socket_id);
- if (stub == NULL) {
- TABLE_LOG(ERR,
- "%s: Cannot allocate %u bytes for stub table",
- __func__, size);
- return NULL;
- }
-
- return stub;
-}
-
-static int
-rte_table_stub_lookup(
- __rte_unused void *table,
- __rte_unused struct rte_mbuf **pkts,
- __rte_unused uint64_t pkts_mask,
- uint64_t *lookup_hit_mask,
- __rte_unused void **entries)
-{
- __rte_unused struct rte_table_stub *stub = (struct rte_table_stub *) table;
- __rte_unused uint32_t n_pkts_in = rte_popcount64(pkts_mask);
-
- RTE_TABLE_LPM_STATS_PKTS_IN_ADD(stub, n_pkts_in);
- *lookup_hit_mask = 0;
- RTE_TABLE_LPM_STATS_PKTS_LOOKUP_MISS(stub, n_pkts_in);
-
- return 0;
-}
-
-static int
-rte_table_stub_stats_read(void *table, struct rte_table_stats *stats, int clear)
-{
- struct rte_table_stub *t = table;
-
- if (stats != NULL)
- memcpy(stats, &t->stats, sizeof(t->stats));
-
- if (clear)
- memset(&t->stats, 0, sizeof(t->stats));
-
- return 0;
-}
-
-RTE_EXPORT_SYMBOL(rte_table_stub_ops)
-struct rte_table_ops rte_table_stub_ops = {
- .f_create = rte_table_stub_create,
- .f_free = NULL,
- .f_add = NULL,
- .f_delete = NULL,
- .f_add_bulk = NULL,
- .f_delete_bulk = NULL,
- .f_lookup = rte_table_stub_lookup,
- .f_stats = rte_table_stub_stats_read,
-};
diff --git a/lib/table/rte_table_stub.h b/lib/table/rte_table_stub.h
deleted file mode 100644
index f7e589df16f77f0aca839232b32747b4856936f6..0000000000000000000000000000000000000000
--- a/lib/table/rte_table_stub.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_TABLE_STUB_H__
-#define __INCLUDE_RTE_TABLE_STUB_H__
-
-/**
- * @file
- * RTE Table Stub
- *
- * The stub table lookup operation produces lookup miss for all input packets.
- */
-
-#include "rte_table.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Stub table parameters: NONE */
-
-/** Stub table operations */
-extern struct rte_table_ops rte_table_stub_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/table/table_log.c b/lib/table/table_log.c
deleted file mode 100644
index b329edd2e69f8035d25c05582aeeb97d210a2f9c..0000000000000000000000000000000000000000
--- a/lib/table/table_log.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2024 Stephen Hemminger <stephen@networkplumber.org>
- */
-
-#include <rte_log.h>
-
-RTE_LOG_REGISTER_DEFAULT(table_logtype, INFO);
diff --git a/lib/table/table_log.h b/lib/table/table_log.h
deleted file mode 100644
index b24b8614c227be014cd8f3139da712570957ff7d..0000000000000000000000000000000000000000
--- a/lib/table/table_log.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2023 Red Hat, Inc.
- */
-
-#include <rte_log.h>
-
-extern int table_logtype;
-#define RTE_LOGTYPE_TABLE table_logtype
-
-#define TABLE_LOG(level, ...) \
- RTE_LOG_LINE(level, TABLE, "" __VA_ARGS__)
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 6/7] port: remove legacy API
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (13 preceding siblings ...)
2026-07-28 16:35 ` [PATCH v4 5/7] table: " Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
2026-07-28 16:35 ` [PATCH v4 7/7] doc: remove packet framework images Stephen Hemminger
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Cristian Dumitrescu
Remove the legacy port library API (rte_port_*) as announced for
removal in the 24.11 release. The SWX port API remains.
The sched, ip_frag, cryptodev and eventdev dependencies were only
used by the legacy port types, so drop them. The pcap dependency
is kept for the SWX source/sink port.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/api/doxy-api-index.md | 7 -
doc/guides/prog_guide/packet_framework.rst | 132 +---
doc/guides/rel_notes/deprecation.rst | 5 -
doc/guides/rel_notes/release_26_11.rst | 3 +
lib/port/meson.build | 22 +-
lib/port/port_log.c | 7 -
lib/port/port_log.h | 11 -
lib/port/rte_port.h | 223 ------
lib/port/rte_port_ethdev.c | 530 --------------
lib/port/rte_port_ethdev.h | 75 --
lib/port/rte_port_eventdev.c | 590 ---------------
lib/port/rte_port_eventdev.h | 94 ---
lib/port/rte_port_fd.c | 524 --------------
lib/port/rte_port_fd.h | 74 --
lib/port/rte_port_frag.c | 280 --------
lib/port/rte_port_frag.h | 70 --
lib/port/rte_port_ras.c | 336 ---------
lib/port/rte_port_ras.h | 58 --
lib/port/rte_port_ring.c | 796 ---------------------
lib/port/rte_port_ring.h | 91 ---
lib/port/rte_port_sched.c | 298 --------
lib/port/rte_port_sched.h | 52 --
lib/port/rte_port_source_sink.c | 616 ----------------
lib/port/rte_port_source_sink.h | 57 --
lib/port/rte_port_sym_crypto.c | 558 ---------------
lib/port/rte_port_sym_crypto.h | 92 ---
26 files changed, 10 insertions(+), 5591 deletions(-)
delete mode 100644 lib/port/port_log.c
delete mode 100644 lib/port/port_log.h
delete mode 100644 lib/port/rte_port.h
delete mode 100644 lib/port/rte_port_ethdev.c
delete mode 100644 lib/port/rte_port_ethdev.h
delete mode 100644 lib/port/rte_port_eventdev.c
delete mode 100644 lib/port/rte_port_eventdev.h
delete mode 100644 lib/port/rte_port_fd.c
delete mode 100644 lib/port/rte_port_fd.h
delete mode 100644 lib/port/rte_port_frag.c
delete mode 100644 lib/port/rte_port_frag.h
delete mode 100644 lib/port/rte_port_ras.c
delete mode 100644 lib/port/rte_port_ras.h
delete mode 100644 lib/port/rte_port_ring.c
delete mode 100644 lib/port/rte_port_ring.h
delete mode 100644 lib/port/rte_port_sched.c
delete mode 100644 lib/port/rte_port_sched.h
delete mode 100644 lib/port/rte_port_source_sink.c
delete mode 100644 lib/port/rte_port_source_sink.h
delete mode 100644 lib/port/rte_port_sym_crypto.c
delete mode 100644 lib/port/rte_port_sym_crypto.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 760b770d6f8ac636e56541b4db609768e6558e11..16827a602b501491948e583c08bc49c55de44bf1 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -182,13 +182,6 @@ The public API headers are grouped by topics:
[bitmap](@ref rte_bitmap.h)
- **packet framework**:
- * [port](@ref rte_port.h):
- [ethdev](@ref rte_port_ethdev.h),
- [ring](@ref rte_port_ring.h),
- [frag](@ref rte_port_frag.h),
- [reass](@ref rte_port_ras.h),
- [sched](@ref rte_port_sched.h),
- [src/sink](@ref rte_port_source_sink.h)
* SWX pipeline:
[control](@ref rte_swx_ctl.h),
[extern](@ref rte_swx_extern.h),
diff --git a/doc/guides/prog_guide/packet_framework.rst b/doc/guides/prog_guide/packet_framework.rst
index 98cf3be1099d88f78665b207beb982bd5c534c86..3b5ede7dc2792cc5eeeed93c6968ccb234564876 100644
--- a/doc/guides/prog_guide/packet_framework.rst
+++ b/doc/guides/prog_guide/packet_framework.rst
@@ -4,132 +4,12 @@
Packet Framework Library
========================
-Design Objectives
------------------
-
-The main design objectives for the DPDK Packet Framework are:
-
-* Provide standard methodology to build complex packet processing pipelines.
- Provide reusable and extensible templates for the commonly used pipeline functional blocks;
-
-* Provide capability to switch between pure software and hardware-accelerated implementations for the same pipeline functional block;
-
-* Provide the best trade-off between flexibility and performance.
- Hardcoded pipelines usually provide the best performance, but are not flexible,
- while developing flexible frameworks is never a problem, but performance is usually low;
-
-* Provide a framework that is logically similar to Open Flow.
-
-Overview
---------
-
-Packet processing applications are frequently structured as pipelines of multiple stages,
-with the logic of each stage glued around a lookup table.
-For each incoming packet, the table defines the set of actions to be applied to the packet,
-as well as the next stage to send the packet to.
-
-The DPDK Packet Framework minimizes the development effort required to build packet processing pipelines
-by defining a standard methodology for pipeline development,
-as well as providing libraries of reusable templates for the commonly used pipeline blocks.
-
-The pipeline is constructed by connecting the set of input ports with the set of output ports
-through the set of tables in a tree-like topology.
-As a result of lookup operation for the current packet in the current table,
-one of the table entries (on lookup hit) or the default table entry (on lookup miss)
-provides the set of actions to be applied on the current packet,
-as well as the next hop for the packet, which can be either another table, an output port or packet drop.
-
-An example of packet processing pipeline is presented in :numref:`packet_framework_figure_32`:
-
-.. _packet_framework_figure_32:
-
-.. figure:: img/figure32.*
-
- Example of Packet Processing Pipeline where Input Ports 0 and 1
- are Connected with Output Ports 0, 1 and 2 through Tables 0 and 1
-
-
-Port Library Design
--------------------
-
-Port Types
-~~~~~~~~~~
-
-:numref:`packet_framework_table_qos_19` is a non-exhaustive list of ports
-that can be implemented with the Packet Framework.
-
-.. _packet_framework_table_qos_19:
-
-.. table:: Port Types
-
- +---+------------------+---------------------------------------------------------------------------------------+
- | # | Port type | Description |
- | | | |
- +===+==================+=======================================================================================+
- | 1 | SW ring | SW circular buffer used for message passing between the application threads. Uses |
- | | | the DPDK rte_ring primitive. Expected to be the most commonly used type of |
- | | | port. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 2 | HW ring | Queue of buffer descriptors used to interact with NIC, switch or accelerator ports. |
- | | | For NIC ports, it uses the DPDK rte_eth_rx_queue or rte_eth_tx_queue |
- | | | primitives. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 3 | IP reassembly | Input packets are either IP fragments or complete IP datagrams. Output packets are |
- | | | complete IP datagrams. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 4 | IP fragmentation | Input packets are jumbo (IP datagrams with length bigger than MTU) or non-jumbo |
- | | | packets. Output packets are non-jumbo packets. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 5 | Traffic manager | Traffic manager attached to a specific NIC output port, performing congestion |
- | | | management and hierarchical scheduling according to pre-defined SLAs. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 6 | Source | Input port used as packet generator. Similar to Linux kernel /dev/zero character |
- | | | device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 7 | Sink | Output port used to drop all input packets. Similar to Linux kernel /dev/null |
- | | | character device. |
- | | | |
- +---+------------------+---------------------------------------------------------------------------------------+
- | 8 | Sym_crypto | Output port used to extract DPDK Cryptodev operations from a fixed offset of the |
- | | | packet and then enqueue to the Cryptodev PMD. Input port used to dequeue the |
- | | | Cryptodev operations from the Cryptodev PMD and then retrieve the packets from them. |
- +---+------------------+---------------------------------------------------------------------------------------+
-
-Port Interface
-~~~~~~~~~~~~~~
-
-Each port is unidirectional, i.e. either input port or output port.
-Each input/output port is required to implement an abstract interface that
-defines the initialization and run-time operation of the port.
-The port abstract interface is described below.
-
-.. table:: 20 Port Abstract Interface
-
- +---+----------------+-----------------------------------------------------------------------------------------+
- | # | Port Operation | Description |
- | | | |
- +===+================+=========================================================================================+
- | 1 | Create | Create the low-level port object (e.g. queue). Can internally allocate memory. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 2 | Free | Free the resources (e.g. memory) used by the low-level port object. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 3 | RX | Read a burst of input packets. Non-blocking operation. Only defined for input ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 4 | TX | Write a burst of input packets. Non-blocking operation. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
- | 5 | Flush | Flush the output buffer. Only defined for output ports. |
- | | | |
- +---+----------------+-----------------------------------------------------------------------------------------+
+The Packet Framework is a set of libraries (port, table and pipeline)
+for building flexible packet processing pipelines:
+the pipeline is constructed by connecting a set of input ports
+with a set of output ports through a set of match-action tables.
+The current framework API is the Software Switch (SWX) pipeline
+described below.
The Software Switch (SWX) Pipeline
----------------------------------
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 9dcf86098f0d391a44ee1887ba823a1dd04ac295..75b56b0e104d95a0d6a4c049bbcec561272104ea 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -148,11 +148,6 @@ Deprecation Notices
The graph walk functions will process nodes in topological order
using bitmap scanning instead of the circular buffer.
-* port: The port library legacy API (functions rte_port_*)
- will be deprecated and subsequently removed in DPDK 24.11 release.
- Before this, the new port library API (functions rte_swx_port_*)
- will gradually transition from experimental to stable status.
-
* bus/vmbus: Starting DPDK 25.11, all the vmbus API defined in
``drivers/bus/vmbus/rte_bus_vmbus.h`` will become internal to DPDK.
Those API functions are used internally by DPDK core and netvsc PMD.
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 50b0d3ac06e35b8fd5b86baafd85723d7539cb5d..31b075b3ccf203b45706b6cb39d5a38f4c20a05b 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -91,6 +91,9 @@ Removed Items
* Removed the legacy table library API (``rte_table_*`` functions).
The SWX table API (``rte_swx_table_*``) remains.
+* Removed the legacy port library API (``rte_port_*`` functions).
+ The SWX port API (``rte_swx_port_*``) remains.
+
API Changes
-----------
diff --git a/lib/port/meson.build b/lib/port/meson.build
index b5977728723a9ef9e21a23ae3a1eca7342b93dc5..ef88b917a3293fbdc51ea22ef862a8e9f432cae8 100644
--- a/lib/port/meson.build
+++ b/lib/port/meson.build
@@ -8,39 +8,19 @@ if is_windows
endif
sources = files(
- 'port_log.c',
- 'rte_port_ethdev.c',
- 'rte_port_fd.c',
- 'rte_port_frag.c',
- 'rte_port_ras.c',
- 'rte_port_ring.c',
- 'rte_port_sched.c',
- 'rte_port_source_sink.c',
- 'rte_port_sym_crypto.c',
- 'rte_port_eventdev.c',
'rte_swx_port_ethdev.c',
'rte_swx_port_fd.c',
'rte_swx_port_ring.c',
'rte_swx_port_source_sink.c',
)
headers = files(
- 'rte_port_ethdev.h',
- 'rte_port_fd.h',
- 'rte_port_frag.h',
- 'rte_port_ras.h',
- 'rte_port.h',
- 'rte_port_ring.h',
- 'rte_port_sched.h',
- 'rte_port_source_sink.h',
- 'rte_port_sym_crypto.h',
- 'rte_port_eventdev.h',
'rte_swx_port.h',
'rte_swx_port_ethdev.h',
'rte_swx_port_fd.h',
'rte_swx_port_ring.h',
'rte_swx_port_source_sink.h',
)
-deps += ['ethdev', 'sched', 'ip_frag', 'cryptodev', 'eventdev']
+deps += ['ethdev']
if dpdk_conf.has('RTE_HAS_LIBPCAP')
dpdk_conf.set('RTE_PORT_PCAP', 1)
diff --git a/lib/port/port_log.c b/lib/port/port_log.c
deleted file mode 100644
index e7a10d80ef8ca58aec03e4764517cc5d8b8dfe79..0000000000000000000000000000000000000000
--- a/lib/port/port_log.c
+++ /dev/null
@@ -1,7 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2024 Stephen Hemminger <stephen@networkplumber.org>
- */
-
-#include <rte_log.h>
-
-RTE_LOG_REGISTER_DEFAULT(port_logtype, INFO);
diff --git a/lib/port/port_log.h b/lib/port/port_log.h
deleted file mode 100644
index 28d75ee48b3be232751ac60f8eefc3d4d03850bb..0000000000000000000000000000000000000000
--- a/lib/port/port_log.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright (c) 2023 Red Hat, Inc.
- */
-
-#include <rte_log.h>
-
-extern int port_logtype;
-#define RTE_LOGTYPE_PORT port_logtype
-
-#define PORT_LOG(level, ...) \
- RTE_LOG_LINE(level, PORT, "" __VA_ARGS__)
diff --git a/lib/port/rte_port.h b/lib/port/rte_port.h
deleted file mode 100644
index 81f57c41a59a4a43e765cea6c873332233ebb203..0000000000000000000000000000000000000000
--- a/lib/port/rte_port.h
+++ /dev/null
@@ -1,223 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_H__
-#define __INCLUDE_RTE_PORT_H__
-
-/**
- * @file
- * RTE Port
- *
- * This tool is part of the DPDK Packet Framework tool suite and provides
- * a standard interface to implement different types of packet ports.
- */
-
-#include <stdint.h>
-#include <rte_mbuf.h>
-
-/**@{
- * Macros to allow accessing metadata stored in the mbuf headroom
- * just beyond the end of the mbuf data structure returned by a port
- */
-#define RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset) \
- (&((uint8_t *)(mbuf))[offset])
-#define RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset) \
- ((uint16_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset) \
- ((uint32_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset) \
- ((uint64_t *) RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-
-#define RTE_MBUF_METADATA_UINT8(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT8_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT16(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT16_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT32(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT32_PTR(mbuf, offset))
-#define RTE_MBUF_METADATA_UINT64(mbuf, offset) \
- (*RTE_MBUF_METADATA_UINT64_PTR(mbuf, offset))
-/**@}*/
-
-/*
- * Port IN
- */
-/** Maximum number of packets read from any input port in a single burst.
-Cannot be changed. */
-#define RTE_PORT_IN_BURST_SIZE_MAX 64
-
-/** Input port statistics */
-struct rte_port_in_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Input port create
- *
- * @param params
- * Parameters for input port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to input port instance
- */
-typedef void* (*rte_port_in_op_create)(void *params, int socket_id);
-
-/**
- * Input port free
- *
- * @param port
- * Handle to input port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_free)(void *port);
-
-/**
- * Input port packet burst RX
- *
- * @param port
- * Handle to input port instance
- * @param pkts
- * Burst of input packets
- * @param n_pkts
- * Number of packets in the input burst
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_in_op_rx)(
- void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts);
-
-/**
- * Input port stats get
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_in stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_in_op_stats_read)(
- void *port,
- struct rte_port_in_stats *stats,
- int clear);
-
-/** Input port interface defining the input port operation */
-struct rte_port_in_ops {
- rte_port_in_op_create f_create; /**< Create */
- rte_port_in_op_free f_free; /**< Free */
- rte_port_in_op_rx f_rx; /**< Packet RX (packet burst) */
- rte_port_in_op_stats_read f_stats; /**< Stats */
-};
-
-/*
- * Port OUT
- */
-/** Output port statistics */
-struct rte_port_out_stats {
- uint64_t n_pkts_in;
- uint64_t n_pkts_drop;
-};
-
-/**
- * Output port create
- *
- * @param params
- * Parameters for output port creation
- * @param socket_id
- * CPU socket ID (e.g. for memory allocation purpose)
- * @return
- * Handle to output port instance
- */
-typedef void* (*rte_port_out_op_create)(void *params, int socket_id);
-
-/**
- * Output port free
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_free)(void *port);
-
-/**
- * Output port single packet TX
- *
- * @param port
- * Handle to output port instance
- * @param pkt
- * Input packet
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx)(
- void *port,
- struct rte_mbuf *pkt);
-
-/**
- * Output port packet burst TX
- *
- * @param port
- * Handle to output port instance
- * @param pkts
- * Burst of input packets specified as array of up to 64 pointers to struct
- * rte_mbuf
- * @param pkts_mask
- * 64-bit bitmask specifying which packets in the input burst are valid. When
- * pkts_mask bit n is set, then element n of pkts array is pointing to a
- * valid packet. Otherwise, element n of pkts array will not be accessed.
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_tx_bulk)(
- void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask);
-
-/**
- * Output port flush
- *
- * @param port
- * Handle to output port instance
- * @return
- * 0 on success, error code otherwise
- */
-typedef int (*rte_port_out_op_flush)(void *port);
-
-/**
- * Output port stats read
- *
- * @param port
- * Handle to output port instance
- * @param stats
- * Handle to port_out stats struct to copy data
- * @param clear
- * Flag indicating that stats should be cleared after read
- *
- * @return
- * Error code or 0 on success.
- */
-typedef int (*rte_port_out_op_stats_read)(
- void *port,
- struct rte_port_out_stats *stats,
- int clear);
-
-/** Output port interface defining the output port operation */
-struct rte_port_out_ops {
- rte_port_out_op_create f_create; /**< Create */
- rte_port_out_op_free f_free; /**< Free */
- rte_port_out_op_tx f_tx; /**< Packet TX (single packet) */
- rte_port_out_op_tx_bulk f_tx_bulk; /**< Packet TX (packet burst) */
- rte_port_out_op_flush f_flush; /**< Flush */
- rte_port_out_op_stats_read f_stats; /**< Stats */
-};
-
-#endif
diff --git a/lib/port/rte_port_ethdev.c b/lib/port/rte_port_ethdev.c
deleted file mode 100644
index bdab2fbf6c58dd521acaadc436faf3e9dde93cb2..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_ethdev.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ethdev.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ethdev.h"
-
-#include "port_log.h"
-
-/*
- * Port ETHDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_reader {
- struct rte_port_in_stats stats;
-
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_reader_params *conf =
- params;
- struct rte_port_ethdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
-
- return port;
-}
-
-static int
-rte_port_ethdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ethdev_reader *p =
- port;
- uint16_t rx_pkt_cnt;
-
- rx_pkt_cnt = rte_eth_rx_burst(p->port_id, p->queue_id, pkts, n_pkts);
- RTE_PORT_ETHDEV_READER_STATS_PKTS_IN_ADD(p, rx_pkt_cnt);
- return rx_pkt_cnt;
-}
-
-static int
-rte_port_ethdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ethdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_params *conf =
- params;
- struct rte_port_ethdev_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_ethdev_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst(p);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_flush(void *port)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port ETHDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ethdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint16_t queue_id;
- uint16_t port_id;
-};
-
-static void *
-rte_port_ethdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_ethdev_writer_nodrop_params *conf =
- params;
- struct rte_port_ethdev_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ethdev_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_eth_tx_burst(p->port_id, p->queue_id, p->tx_buf,
- p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_eth_tx_burst(p->port_id, p->queue_id,
- p->tx_buf + nb_tx, p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- n_pkts_ok = rte_eth_tx_burst(p->port_id, p->queue_id, pkts,
- n_pkts);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to send all packets in single burst,
- * move remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_ETHDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ethdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_ethdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_ethdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ethdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ethdev_reader_ops)
-struct rte_port_in_ops rte_port_ethdev_reader_ops = {
- .f_create = rte_port_ethdev_reader_create,
- .f_free = rte_port_ethdev_reader_free,
- .f_rx = rte_port_ethdev_reader_rx,
- .f_stats = rte_port_ethdev_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_ops = {
- .f_create = rte_port_ethdev_writer_create,
- .f_free = rte_port_ethdev_writer_free,
- .f_tx = rte_port_ethdev_writer_tx,
- .f_tx_bulk = rte_port_ethdev_writer_tx_bulk,
- .f_flush = rte_port_ethdev_writer_flush,
- .f_stats = rte_port_ethdev_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ethdev_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops = {
- .f_create = rte_port_ethdev_writer_nodrop_create,
- .f_free = rte_port_ethdev_writer_nodrop_free,
- .f_tx = rte_port_ethdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ethdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ethdev_writer_nodrop_flush,
- .f_stats = rte_port_ethdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ethdev.h b/lib/port/rte_port_ethdev.h
deleted file mode 100644
index 7729ff0da343292cea6ef43064153bd6912c1c7b..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_ethdev.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_ETHDEV_H__
-#define __INCLUDE_RTE_PORT_ETHDEV_H__
-
-/**
- * @file
- * RTE Port Ethernet Device
- *
- * ethdev_reader: input port built on top of pre-initialized NIC RX queue
- * ethdev_writer: output port built on top of pre-initialized NIC TX queue
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ethdev_reader port parameters */
-struct rte_port_ethdev_reader_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-};
-
-/** ethdev_reader port operations */
-extern struct rte_port_in_ops rte_port_ethdev_reader_ops;
-
-/** ethdev_writer port parameters */
-struct rte_port_ethdev_writer_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ethdev_writer port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_ops;
-
-/** ethdev_writer_nodrop port parameters */
-struct rte_port_ethdev_writer_nodrop_params {
- /** NIC RX port ID */
- uint16_t port_id;
-
- /** NIC RX queue ID */
- uint16_t queue_id;
-
- /** Recommended burst size to NIC TX queue. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ethdev_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ethdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_eventdev.c b/lib/port/rte_port_eventdev.c
deleted file mode 100644
index c3a287b83476173cd1a1d699282c47d7598d68db..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_eventdev.c
+++ /dev/null
@@ -1,590 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_eventdev.h"
-
-#include "port_log.h"
-
-/*
- * Port EVENTDEV Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_reader {
- struct rte_port_in_stats stats;
-
- uint8_t eventdev_id;
- uint16_t port_id;
-
- struct rte_event ev[RTE_PORT_IN_BURST_SIZE_MAX];
-};
-
-static void *
-rte_port_eventdev_reader_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_reader_params *conf =
- params;
- struct rte_port_eventdev_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
-
- return port;
-}
-
-static int
-rte_port_eventdev_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_eventdev_reader *p = port;
- uint16_t rx_evts_cnt, i;
-
- rx_evts_cnt = rte_event_dequeue_burst(p->eventdev_id, p->port_id,
- p->ev, n_pkts, 0);
-
- for (i = 0; i < rx_evts_cnt; i++)
- pkts[i] = p->ev[i].mbuf;
-
- RTE_PORT_EVENTDEV_READER_STATS_PKTS_IN_ADD(p, rx_evts_cnt);
-
- return rx_evts_cnt;
-}
-
-static int
-rte_port_eventdev_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_eventdev_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
-
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-static void *
-rte_port_eventdev_writer_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_params *conf =
- params;
- struct rte_port_eventdev_writer *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_eventdev_writer *p)
-{
- uint32_t nb_enq;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p, p->enq_buf_count -
- nb_enq);
-
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst(p);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[2 * RTE_PORT_IN_BURST_SIZE_MAX] = {};
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_DROP_ADD(p,
- n_pkts - n_enq_ok);
- for (; n_enq_ok < n_pkts; n_enq_ok++)
- rte_pktmbuf_free(pkts[n_enq_ok]);
-
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_flush(void *port)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port EVENTDEV Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do {port->stats.n_pkts_in += val;} while (0)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do {port->stats.n_pkts_drop += val;} while (0)
-
-#else
-
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_eventdev_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_event ev[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t enq_burst_sz;
- uint32_t enq_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint8_t eventdev_id;
- uint8_t port_id;
- uint8_t queue_id;
- uint8_t sched_type;
- uint8_t evt_op;
-};
-
-
-static void *
-rte_port_eventdev_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_eventdev_writer_nodrop_params *conf =
- params;
- struct rte_port_eventdev_writer_nodrop *port;
- unsigned int i;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->enq_burst_sz == 0) ||
- (conf->enq_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->enq_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->enq_burst_sz = conf->enq_burst_sz;
- port->enq_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->enq_burst_sz - 1);
-
- port->eventdev_id = conf->eventdev_id;
- port->port_id = conf->port_id;
- port->queue_id = conf->queue_id;
- port->sched_type = conf->sched_type;
- port->evt_op = conf->evt_op;
- memset(&port->ev, 0, sizeof(port->ev));
-
- for (i = 0; i < RTE_DIM(port->ev); i++) {
- port->ev[i].queue_id = port->queue_id;
- port->ev[i].sched_type = port->sched_type;
- port->ev[i].op = port->evt_op;
- }
- /*
- * When n_retries is 0 it means that we should wait for every event to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_eventdev_writer_nodrop *p)
-{
- uint32_t nb_enq, i;
-
- nb_enq = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev, p->enq_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_enq += rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- p->ev + nb_enq,
- p->enq_buf_count - nb_enq);
-
- /* We sent all the events in more than one try */
- if (nb_enq >= p->enq_buf_count) {
- p->enq_buf_count = 0;
- return;
- }
- }
- /* We didn't send the events in maximum allowed attempts */
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->enq_buf_count - nb_enq);
- for (; nb_enq < p->enq_buf_count; nb_enq++)
- rte_pktmbuf_free(p->ev[nb_enq].mbuf);
-
- p->enq_buf_count = 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_eventdev_writer_nodrop *p = port;
-
- p->ev[p->enq_buf_count++].mbuf = pkt;
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t enq_buf_count = p->enq_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i, n_enq_ok;
-
- if (enq_buf_count)
- send_burst_nodrop(p);
-
- RTE_PORT_EVENTDEV_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- struct rte_event events[RTE_PORT_IN_BURST_SIZE_MAX] = {};
-
- for (i = 0; i < n_pkts; i++) {
- events[i].mbuf = pkts[i];
- events[i].queue_id = p->queue_id;
- events[i].sched_type = p->sched_type;
- events[i].op = p->evt_op;
- }
-
- n_enq_ok = rte_event_enqueue_burst(p->eventdev_id, p->port_id,
- events, n_pkts);
-
- if (n_enq_ok >= n_pkts)
- return 0;
-
- /*
- * If we did not manage to enqueue all events in single burst,
- * move remaining events to the buffer and call send burst.
- */
- for (; n_enq_ok < n_pkts; n_enq_ok++) {
- struct rte_mbuf *pkt = pkts[n_enq_ok];
- p->ev[p->enq_buf_count++].mbuf = pkt;
- }
- send_burst_nodrop(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
-
- p->ev[enq_buf_count++].mbuf = pkts[pkt_index];
-
- RTE_PORT_EVENTDEV_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->enq_buf_count = enq_buf_count;
- if (enq_buf_count >= p->enq_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_flush(void *port)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (p->enq_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_eventdev_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_eventdev_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_eventdev_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_eventdev_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_reader_ops, 19.11)
-struct rte_port_in_ops rte_port_eventdev_reader_ops = {
- .f_create = rte_port_eventdev_reader_create,
- .f_free = rte_port_eventdev_reader_free,
- .f_rx = rte_port_eventdev_reader_rx,
- .f_stats = rte_port_eventdev_reader_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_ops = {
- .f_create = rte_port_eventdev_writer_create,
- .f_free = rte_port_eventdev_writer_free,
- .f_tx = rte_port_eventdev_writer_tx,
- .f_tx_bulk = rte_port_eventdev_writer_tx_bulk,
- .f_flush = rte_port_eventdev_writer_flush,
- .f_stats = rte_port_eventdev_writer_stats_read,
-};
-
-RTE_EXPORT_EXPERIMENTAL_SYMBOL(rte_port_eventdev_writer_nodrop_ops, 19.11)
-struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops = {
- .f_create = rte_port_eventdev_writer_nodrop_create,
- .f_free = rte_port_eventdev_writer_nodrop_free,
- .f_tx = rte_port_eventdev_writer_nodrop_tx,
- .f_tx_bulk = rte_port_eventdev_writer_nodrop_tx_bulk,
- .f_flush = rte_port_eventdev_writer_nodrop_flush,
- .f_stats = rte_port_eventdev_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_eventdev.h b/lib/port/rte_port_eventdev.h
deleted file mode 100644
index d9eccf07d474b84a54848a640d1d08752c3907bd..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_eventdev.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2019 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_EVENTDEV_H__
-#define __INCLUDE_RTE_PORT_EVENTDEV_H__
-
-/**
- * @file
- * RTE Port Eventdev Interface
- *
- * eventdev_reader: input port built on top of pre-initialized eventdev
- * interface
- * eventdev_writer: output port built on top of pre-initialized eventdev
- * interface
- */
-
-#include <stdint.h>
-#include <rte_eventdev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Eventdev_reader port parameters */
-struct rte_port_eventdev_reader_params {
- /** Eventdev Device ID */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID */
- uint8_t port_id;
-};
-
-/** Eventdev_reader port operations. */
-extern struct rte_port_in_ops rte_port_eventdev_reader_ops;
-
-/** Eventdev_writer port parameters. */
-struct rte_port_eventdev_writer_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint8_t port_id;
-
- /** Eventdev Queue ID. */
- uint8_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-};
-
-/** Eventdev_writer port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_ops;
-
-/** Event_writer_nodrop port parameters. */
-struct rte_port_eventdev_writer_nodrop_params {
- /** Eventdev Device ID. */
- uint8_t eventdev_id;
-
- /** Eventdev Port ID. */
- uint16_t port_id;
-
- /** Eventdev Queue ID. */
- uint16_t queue_id;
-
- /** Burst size to eventdev interface. */
- uint32_t enq_burst_sz;
-
- /** Scheduler synchronization type (RTE_SCHED_TYPE_*)*/
- uint8_t sched_type;
-
- /** The type of eventdev enqueue operation - new/forward/release */
- uint8_t evt_op;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Eventdev_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_eventdev_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_fd.c b/lib/port/rte_port_fd.c
deleted file mode 100644
index dbc9efef1b1035fe762109cad0702beb95dcee76..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_fd.c
+++ /dev/null
@@ -1,524 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-#include <unistd.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-
-#include "rte_port_fd.h"
-
-#include "port_log.h"
-
-/*
- * Port FD Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_reader {
- struct rte_port_in_stats stats;
- int fd;
- uint32_t mtu;
- struct rte_mempool *mempool;
-};
-
-static void *
-rte_port_fd_reader_create(void *params, int socket_id)
-{
- struct rte_port_fd_reader_params *conf =
- params;
- struct rte_port_fd_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
- if (conf->fd < 0) {
- PORT_LOG(ERR, "%s: Invalid file descriptor", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Invalid MTU", __func__);
- return NULL;
- }
- if (conf->mempool == NULL) {
- PORT_LOG(ERR, "%s: Invalid mempool", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->mtu = conf->mtu;
- port->mempool = conf->mempool;
-
- return port;
-}
-
-static int
-rte_port_fd_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_fd_reader *p = port;
- uint32_t i, j;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void *);
- ssize_t n_bytes;
-
- n_bytes = read(p->fd, pkt_data, (size_t) p->mtu);
- if (n_bytes <= 0)
- break;
-
- pkt->data_len = n_bytes;
- pkt->pkt_len = n_bytes;
- }
-
- for (j = i; j < n_pkts; j++)
- rte_pktmbuf_free(pkts[j]);
-
- RTE_PORT_FD_READER_STATS_PKTS_IN_ADD(p, i);
-
- return i;
-}
-
-static int
-rte_port_fd_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_fd_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_params *conf =
- params;
- struct rte_port_fd_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_fd_writer *p)
-{
- uint32_t i;
-
- for (i = 0; i < p->tx_buf_count; i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret < 0)
- break;
- }
-
- RTE_PORT_FD_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_flush(void *port)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_fd_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port FD Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- do { port->stats.n_pkts_in += val; } while (0)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- do { port->stats.n_pkts_drop += val; } while (0)
-
-#else
-
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_fd_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint16_t tx_buf_count;
- uint64_t n_retries;
- uint32_t fd;
-};
-
-static void *
-rte_port_fd_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_fd_writer_nodrop_params *conf =
- params;
- struct rte_port_fd_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->fd < 0) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->fd = conf->fd;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_fd_writer_nodrop *p)
-{
- uint64_t n_retries;
- uint32_t i;
-
- n_retries = 0;
- for (i = 0; (i < p->tx_buf_count) && (n_retries < p->n_retries); i++) {
- struct rte_mbuf *pkt = p->tx_buf[i];
- void *pkt_data = rte_pktmbuf_mtod(pkt, void*);
- size_t n_bytes = rte_pktmbuf_data_len(pkt);
-
- for ( ; n_retries < p->n_retries; n_retries++) {
- ssize_t ret;
-
- ret = write(p->fd, pkt_data, n_bytes);
- if (ret)
- break;
- }
- }
-
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - i);
-
- for (i = 0; i < p->tx_buf_count; i++)
- rte_pktmbuf_free(p->tx_buf[i]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
- uint32_t tx_buf_count = p->tx_buf_count;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[tx_buf_count++] = pkts[i];
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- } else
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_FD_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_flush(void *port)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_fd_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_fd_writer_nodrop_flush(port);
- rte_free(port);
-
-return 0;
-}
-
-static int rte_port_fd_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_fd_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_fd_reader_ops)
-struct rte_port_in_ops rte_port_fd_reader_ops = {
- .f_create = rte_port_fd_reader_create,
- .f_free = rte_port_fd_reader_free,
- .f_rx = rte_port_fd_reader_rx,
- .f_stats = rte_port_fd_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_ops)
-struct rte_port_out_ops rte_port_fd_writer_ops = {
- .f_create = rte_port_fd_writer_create,
- .f_free = rte_port_fd_writer_free,
- .f_tx = rte_port_fd_writer_tx,
- .f_tx_bulk = rte_port_fd_writer_tx_bulk,
- .f_flush = rte_port_fd_writer_flush,
- .f_stats = rte_port_fd_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_fd_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_fd_writer_nodrop_ops = {
- .f_create = rte_port_fd_writer_nodrop_create,
- .f_free = rte_port_fd_writer_nodrop_free,
- .f_tx = rte_port_fd_writer_nodrop_tx,
- .f_tx_bulk = rte_port_fd_writer_nodrop_tx_bulk,
- .f_flush = rte_port_fd_writer_nodrop_flush,
- .f_stats = rte_port_fd_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_fd.h b/lib/port/rte_port_fd.h
deleted file mode 100644
index 40a5e4a426d8b5be33434adbdde2c0819b2daeef..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_fd.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_FD_H__
-#define __INCLUDE_RTE_PORT_FD_H__
-
-/**
- * @file
- * RTE Port FD Device
- *
- * fd_reader: input port built on top of valid non-blocking file descriptor
- * fd_writer: output port built on top of valid non-blocking file descriptor
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** fd_reader port parameters */
-struct rte_port_fd_reader_params {
- /** File descriptor */
- int fd;
-
- /** Maximum Transfer Unit (MTU) */
- uint32_t mtu;
-
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-};
-
-/** fd_reader port operations */
-extern struct rte_port_in_ops rte_port_fd_reader_ops;
-
-/** fd_writer port parameters */
-struct rte_port_fd_writer_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-};
-
-/** fd_writer port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_ops;
-
-/** fd_writer_nodrop port parameters */
-struct rte_port_fd_writer_nodrop_params {
- /** File descriptor */
- int fd;
-
- /**< Recommended write burst size. The actual burst size can be
- * bigger or smaller than this value.
- */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** fd_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_fd_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_frag.c b/lib/port/rte_port_frag.c
deleted file mode 100644
index 9444f5939cb3f73ebca5aad94d7f877cf8ad02e9..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_frag.c
+++ /dev/null
@@ -1,280 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-
-#include "rte_port_frag.h"
-
-#include "port_log.h"
-
-/* Max number of fragments per packet allowed */
-#define RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET 0x80
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-typedef int32_t
- (*frag_op)(struct rte_mbuf *pkt_in,
- struct rte_mbuf **pkts_out,
- uint16_t nb_pkts_out,
- uint16_t mtu_size,
- struct rte_mempool *pool_direct,
- struct rte_mempool *pool_indirect);
-
-struct __rte_cache_aligned rte_port_ring_reader_frag {
- struct rte_port_in_stats stats;
-
- /* Input parameters */
- struct rte_ring *ring;
- uint32_t mtu;
- uint32_t metadata_size;
- struct rte_mempool *pool_direct;
- struct rte_mempool *pool_indirect;
-
- /* Internal buffers */
- struct rte_mbuf *pkts[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_mbuf *frags[RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET];
- uint32_t n_pkts;
- uint32_t pos_pkts;
- uint32_t n_frags;
- uint32_t pos_frags;
-
- frag_op f_frag;
-};
-
-static void *
-rte_port_ring_reader_frag_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_reader_frag_params *conf =
- params;
- struct rte_port_ring_reader_frag *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if (conf->mtu == 0) {
- PORT_LOG(ERR, "%s: Parameter mtu is invalid", __func__);
- return NULL;
- }
- if (conf->pool_direct == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_direct is NULL",
- __func__);
- return NULL;
- }
- if (conf->pool_indirect == NULL) {
- PORT_LOG(ERR, "%s: Parameter pool_indirect is NULL",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port), RTE_CACHE_LINE_SIZE,
- socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->mtu = conf->mtu;
- port->metadata_size = conf->metadata_size;
- port->pool_direct = conf->pool_direct;
- port->pool_indirect = conf->pool_indirect;
-
- port->n_pkts = 0;
- port->pos_pkts = 0;
- port->n_frags = 0;
- port->pos_frags = 0;
-
- port->f_frag = (is_ipv4) ?
- rte_ipv4_fragment_packet : rte_ipv6_fragment_packet;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_ipv4_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_reader_ipv6_frag_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_frag_create(params, socket_id, 0);
-}
-
-static int
-rte_port_ring_reader_frag_rx(void *port,
- struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader_frag *p =
- port;
- uint32_t n_pkts_out;
-
- n_pkts_out = 0;
-
- /* Get packets from the "frag" buffer */
- if (p->n_frags >= n_pkts) {
- memcpy(pkts, &p->frags[p->pos_frags], n_pkts * sizeof(void *));
- p->pos_frags += n_pkts;
- p->n_frags -= n_pkts;
-
- return n_pkts;
- }
-
- memcpy(pkts, &p->frags[p->pos_frags], p->n_frags * sizeof(void *));
- n_pkts_out = p->n_frags;
- p->n_frags = 0;
-
- /* Look to "pkts" buffer to get more packets */
- for ( ; ; ) {
- struct rte_mbuf *pkt;
- uint32_t n_pkts_to_provide, i;
- int status;
-
- /* If "pkts" buffer is empty, read packet burst from ring */
- if (p->n_pkts == 0) {
- p->n_pkts = rte_ring_sc_dequeue_burst(p->ring,
- (void **) p->pkts, RTE_PORT_IN_BURST_SIZE_MAX,
- NULL);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_IN_ADD(p, p->n_pkts);
- if (p->n_pkts == 0)
- return n_pkts_out;
- p->pos_pkts = 0;
- }
-
- /* Read next packet from "pkts" buffer */
- pkt = p->pkts[p->pos_pkts++];
- p->n_pkts--;
-
- /* If not jumbo, pass current packet to output */
- if (pkt->pkt_len <= p->mtu) {
- pkts[n_pkts_out++] = pkt;
-
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (n_pkts_to_provide == 0)
- return n_pkts;
-
- continue;
- }
-
- /* Fragment current packet into the "frags" buffer */
- status = p->f_frag(
- pkt,
- p->frags,
- RTE_PORT_FRAG_MAX_FRAGS_PER_PACKET,
- p->mtu,
- p->pool_direct,
- p->pool_indirect
- );
-
- if (status < 0) {
- rte_pktmbuf_free(pkt);
- RTE_PORT_RING_READER_FRAG_STATS_PKTS_DROP_ADD(p, 1);
- continue;
- }
-
- p->n_frags = (uint32_t) status;
- p->pos_frags = 0;
-
- /* Copy meta-data from input jumbo packet to its fragments */
- for (i = 0; i < p->n_frags; i++) {
- uint8_t *src =
- RTE_MBUF_METADATA_UINT8_PTR(pkt, sizeof(struct rte_mbuf));
- uint8_t *dst =
- RTE_MBUF_METADATA_UINT8_PTR(p->frags[i], sizeof(struct rte_mbuf));
-
- memcpy(dst, src, p->metadata_size);
- }
-
- /* Free input jumbo packet */
- rte_pktmbuf_free(pkt);
-
- /* Get packets from "frag" buffer */
- n_pkts_to_provide = n_pkts - n_pkts_out;
- if (p->n_frags >= n_pkts_to_provide) {
- memcpy(&pkts[n_pkts_out], p->frags,
- n_pkts_to_provide * sizeof(void *));
- p->n_frags -= n_pkts_to_provide;
- p->pos_frags += n_pkts_to_provide;
-
- return n_pkts;
- }
-
- memcpy(&pkts[n_pkts_out], p->frags,
- p->n_frags * sizeof(void *));
- n_pkts_out += p->n_frags;
- p->n_frags = 0;
- }
-}
-
-static int
-rte_port_ring_reader_frag_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_frag_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader_frag *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv4_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops = {
- .f_create = rte_port_ring_reader_ipv4_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ipv6_frag_ops)
-struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops = {
- .f_create = rte_port_ring_reader_ipv6_frag_create,
- .f_free = rte_port_ring_reader_frag_free,
- .f_rx = rte_port_ring_reader_frag_rx,
- .f_stats = rte_port_frag_reader_stats_read,
-};
diff --git a/lib/port/rte_port_frag.h b/lib/port/rte_port_frag.h
deleted file mode 100644
index 9a10f10523e676352656a4d27906eefb0af991d8..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_frag.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_IP_FRAG_H__
-#define __INCLUDE_RTE_PORT_IP_FRAG_H__
-
-/**
- * @file
- * RTE Port for IPv4 Fragmentation
- *
- * This port is built on top of pre-initialized single consumer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP fragmentation functionality is executed on ring read operation,
- * hence this port is implemented as an input port. A regular ring_writer port
- * can be created to write to the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or jumbo
- * frames (i.e. IP packets with length bigger than provided MTU value). The
- * packets read from the ring are all non-jumbo frames. The complete IP
- * datagrams written to the ring are not changed. The jumbo frames are
- * fragmented into several IP packets with length less or equal to MTU.
- */
-
-#include <stdint.h>
-
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader_ipv4_frag port parameters */
-struct rte_port_ring_reader_frag_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Maximum Transfer Unit (MTU). Maximum IP packet size (in bytes). */
- uint32_t mtu;
-
- /** Size of application dependent meta-data stored per each input packet
- that has to be copied to each of the fragments originating from the
- same input IP datagram. */
- uint32_t metadata_size;
-
- /** Pre-initialized buffer pool used for allocating direct buffers for
- the output fragments. */
- struct rte_mempool *pool_direct;
-
- /** Pre-initialized buffer pool used for allocating indirect buffers for
- the output fragments. */
- struct rte_mempool *pool_indirect;
-};
-
-#define rte_port_ring_reader_ipv4_frag_params rte_port_ring_reader_frag_params
-
-#define rte_port_ring_reader_ipv6_frag_params rte_port_ring_reader_frag_params
-
-/** ring_reader_ipv4_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv4_frag_ops;
-
-/** ring_reader_ipv6_frag port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ipv6_frag_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ras.c b/lib/port/rte_port_ras.c
deleted file mode 100644
index 58ab7a1c5ba685e14e2a54c5729f1b007d4b01c6..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_ras.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_ip_frag.h>
-#include <rte_cycles.h>
-#include <rte_log.h>
-
-#include "rte_port_ras.h"
-
-#include "port_log.h"
-
-#ifndef RTE_PORT_RAS_N_BUCKETS
-#define RTE_PORT_RAS_N_BUCKETS 4094
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES_PER_BUCKET
-#define RTE_PORT_RAS_N_ENTRIES_PER_BUCKET 8
-#endif
-
-#ifndef RTE_PORT_RAS_N_ENTRIES
-#define RTE_PORT_RAS_N_ENTRIES (RTE_PORT_RAS_N_BUCKETS * RTE_PORT_RAS_N_ENTRIES_PER_BUCKET)
-#endif
-
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_ras;
-
-typedef void (*ras_op)(
- struct rte_port_ring_writer_ras *p,
- struct rte_mbuf *pkt);
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt);
-
-struct rte_port_ring_writer_ras {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- struct rte_ip_frag_tbl *frag_tbl;
- struct rte_ip_frag_death_row death_row;
-
- ras_op f_ras;
-};
-
-static void *
-rte_port_ring_writer_ras_create(void *params, int socket_id, int is_ipv4)
-{
- struct rte_port_ring_writer_ras_params *conf =
- params;
- struct rte_port_ring_writer_ras *port;
- uint64_t frag_cycles;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: Parameter conf is NULL", __func__);
- return NULL;
- }
- if (conf->ring == NULL) {
- PORT_LOG(ERR, "%s: Parameter ring is NULL", __func__);
- return NULL;
- }
- if ((conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Parameter tx_burst_sz is invalid",
- __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate socket", __func__);
- return NULL;
- }
-
- /* Create fragmentation table */
- frag_cycles = (rte_get_tsc_hz() + MS_PER_S - 1) / MS_PER_S * MS_PER_S;
- frag_cycles *= 100;
-
- port->frag_tbl = rte_ip_frag_table_create(
- RTE_PORT_RAS_N_BUCKETS,
- RTE_PORT_RAS_N_ENTRIES_PER_BUCKET,
- RTE_PORT_RAS_N_ENTRIES,
- frag_cycles,
- socket_id);
-
- if (port->frag_tbl == NULL) {
- PORT_LOG(ERR, "%s: rte_ip_frag_table_create failed",
- __func__);
- rte_free(port);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
-
- port->f_ras = (is_ipv4 == 1) ? process_ipv4 : process_ipv6;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_ipv4_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 1);
-}
-
-static void *
-rte_port_ring_writer_ipv6_ras_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_ras_create(params, socket_id, 0);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer_ras *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static void
-process_ipv4(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv4_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv4_hdr *);
-
- /* Get "More fragments" flag and fragment offset */
- uint16_t frag_field = rte_be_to_cpu_16(pkt_hdr->fragment_offset);
- uint16_t frag_offset = (uint16_t)(frag_field & RTE_IPV4_HDR_OFFSET_MASK);
- uint16_t frag_flag = (uint16_t)(frag_field & RTE_IPV4_HDR_MF_FLAG);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_flag == 0) && (frag_offset == 0))
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr);
-
- /* Process this fragment */
- mo = rte_ipv4_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(),
- pkt_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static void
-process_ipv6(struct rte_port_ring_writer_ras *p, struct rte_mbuf *pkt)
-{
- /* Assume there is no ethernet header */
- struct rte_ipv6_hdr *pkt_hdr =
- rte_pktmbuf_mtod(pkt, struct rte_ipv6_hdr *);
-
- struct rte_ipv6_fragment_ext *frag_hdr;
- uint16_t frag_data = 0;
- frag_hdr = rte_ipv6_frag_get_ipv6_fragment_header(pkt_hdr);
- if (frag_hdr != NULL)
- frag_data = rte_be_to_cpu_16(frag_hdr->frag_data);
-
- /* If it is a fragmented packet, then try to reassemble */
- if ((frag_data & RTE_IPV6_FRAG_USED_MASK) == 0)
- p->tx_buf[p->tx_buf_count++] = pkt;
- else {
- struct rte_mbuf *mo;
- struct rte_ip_frag_tbl *tbl = p->frag_tbl;
- struct rte_ip_frag_death_row *dr = &p->death_row;
-
- pkt->l3_len = sizeof(*pkt_hdr) + sizeof(*frag_hdr);
-
- /* Process this fragment */
- mo = rte_ipv6_frag_reassemble_packet(tbl, dr, pkt, rte_rdtsc(), pkt_hdr,
- frag_hdr);
- if (mo != NULL)
- p->tx_buf[p->tx_buf_count++] = mo;
-
- rte_ip_frag_free_death_row(&p->death_row, 3);
- }
-}
-
-static int
-rte_port_ring_writer_ras_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_RING_WRITER_RAS_STATS_PKTS_IN_ADD(p, 1);
- p->f_ras(p, pkt);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_flush(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_ras_free(void *port)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Parameter port is NULL", __func__);
- return -1;
- }
-
- rte_port_ring_writer_ras_flush(port);
- rte_ip_frag_table_destroy(p->frag_tbl);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ras_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_ras *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv4_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops = {
- .f_create = rte_port_ring_writer_ipv4_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ipv6_ras_ops)
-struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops = {
- .f_create = rte_port_ring_writer_ipv6_ras_create,
- .f_free = rte_port_ring_writer_ras_free,
- .f_tx = rte_port_ring_writer_ras_tx,
- .f_tx_bulk = rte_port_ring_writer_ras_tx_bulk,
- .f_flush = rte_port_ring_writer_ras_flush,
- .f_stats = rte_port_ras_writer_stats_read,
-};
diff --git a/lib/port/rte_port_ras.h b/lib/port/rte_port_ras.h
deleted file mode 100644
index 86e36f5362a66d7eca63217477d6893d352c6561..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_ras.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RAS_H__
-#define __INCLUDE_RTE_PORT_RAS_H__
-
-/**
- * @file
- * RTE Port for IPv4 Reassembly
- *
- * This port is built on top of pre-initialized single producer rte_ring. In
- * order to minimize the amount of packets stored in the ring at any given
- * time, the IP reassembly functionality is executed on ring write operation,
- * hence this port is implemented as an output port. A regular ring_reader port
- * can be created to read from the same ring.
- *
- * The packets written to the ring are either complete IP datagrams or IP
- * fragments. The packets read from the ring are all complete IP datagrams,
- * either jumbo frames (i.e. IP packets with length bigger than MTU) or not.
- * The complete IP datagrams written to the ring are not changed. The IP
- * fragments written to the ring are first reassembled and into complete IP
- * datagrams or dropped on error or IP reassembly time-out.
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_writer_ipv4_ras port parameters */
-struct rte_port_ring_writer_ras_params {
- /** Underlying single consumer ring that has to be pre-initialized. */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be bigger
- or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-#define rte_port_ring_writer_ipv4_ras_params rte_port_ring_writer_ras_params
-
-#define rte_port_ring_writer_ipv6_ras_params rte_port_ring_writer_ras_params
-
-/** ring_writer_ipv4_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv4_ras_ops;
-
-/** ring_writer_ipv6_ras port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ipv6_ras_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_ring.c b/lib/port/rte_port_ring.c
deleted file mode 100644
index 307a576d658bc267f59465e38fb30a41b9f6f67a..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_ring.c
+++ /dev/null
@@ -1,796 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-#include <stdint.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_ring.h>
-#include <rte_malloc.h>
-
-#include "rte_port_ring.h"
-
-#include "port_log.h"
-
-/*
- * Port RING Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_reader {
- struct rte_port_in_stats stats;
-
- struct rte_ring *ring;
-};
-
-static void *
-rte_port_ring_reader_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_reader_params *conf =
- params;
- struct rte_port_ring_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_cons_single(conf->ring) && is_multi) ||
- (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
-
- return port;
-}
-
-static void *
-rte_port_ring_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_reader_create(void *params, int socket_id)
-{
- return rte_port_ring_reader_create_internal(params, socket_id, 1);
-}
-
-static int
-rte_port_ring_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_sc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_multi_reader_rx(void *port, struct rte_mbuf **pkts,
- uint32_t n_pkts)
-{
- struct rte_port_ring_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_ring_mc_dequeue_burst(p->ring, (void **) pkts,
- n_pkts, NULL);
- RTE_PORT_RING_READER_STATS_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_ring_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_ring_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_params *conf =
- params;
- struct rte_port_ring_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp(struct rte_port_ring_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer *p = port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
-
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok = rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok = rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- RTE_PORT_RING_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - n_pkts_ok);
- for ( ; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- rte_pktmbuf_free(pkt);
- }
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp(p);
- else
- send_burst(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return rte_port_ring_writer_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_flush(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_free(void *port)
-{
- struct rte_port_ring_writer *p = port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_flush(port);
- else
- rte_port_ring_writer_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port RING Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_ring_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_ring *ring;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
- uint32_t is_multi;
-};
-
-static void *
-rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop_params *conf =
- params;
- struct rte_port_ring_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->ring == NULL) ||
- (rte_ring_is_prod_single(conf->ring) && is_multi) ||
- (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
- PORT_LOG(ERR, "%s: Invalid Parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->ring = conf->ring;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
- port->is_multi = is_multi;
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static void *
-rte_port_ring_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 0);
-}
-
-static void *
-rte_port_ring_multi_writer_nodrop_create(void *params, int socket_id)
-{
- return rte_port_ring_writer_nodrop_create_internal(params, socket_id, 1);
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_sp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_sp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static inline void
-send_burst_mp_nodrop(struct rte_port_ring_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_ring_mp_enqueue_burst(p->ring, (void **)p->tx_buf,
- p->tx_buf_count, NULL);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_ring_mp_enqueue_burst(p->ring,
- (void **) (p->tx_buf + nb_tx),
- p->tx_buf_count - nb_tx, NULL);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static __rte_always_inline int
-rte_port_ring_writer_nodrop_tx_bulk_internal(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask,
- uint32_t is_multi)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t n_pkts_ok;
-
- if (tx_buf_count) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
-
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
- if (is_multi)
- n_pkts_ok =
- rte_ring_mp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
- else
- n_pkts_ok =
- rte_ring_sp_enqueue_burst(p->ring,
- (void **)pkts, n_pkts, NULL);
-
- if (n_pkts_ok >= n_pkts)
- return 0;
-
- /*
- * If we didn't manage to send all packets in single burst, move
- * remaining packets to the buffer and call send burst.
- */
- for (; n_pkts_ok < n_pkts; n_pkts_ok++) {
- struct rte_mbuf *pkt = pkts[n_pkts_ok];
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- }
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_RING_WRITER_NODROP_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz) {
- if (is_multi)
- send_burst_mp_nodrop(p);
- else
- send_burst_nodrop(p);
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 0);
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- return
- rte_port_ring_writer_nodrop_tx_bulk_internal(port, pkts, pkts_mask, 1);
-}
-
-static int
-rte_port_ring_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_multi_writer_nodrop_flush(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_mp_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_free(void *port)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- if (p->is_multi)
- rte_port_ring_multi_writer_nodrop_flush(port);
- else
- rte_port_ring_writer_nodrop_flush(port);
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_ring_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_ring_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_ring_reader_ops)
-struct rte_port_in_ops rte_port_ring_reader_ops = {
- .f_create = rte_port_ring_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_ops)
-struct rte_port_out_ops rte_port_ring_writer_ops = {
- .f_create = rte_port_ring_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_writer_tx,
- .f_tx_bulk = rte_port_ring_writer_tx_bulk,
- .f_flush = rte_port_ring_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_writer_nodrop_ops = {
- .f_create = rte_port_ring_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_reader_ops)
-struct rte_port_in_ops rte_port_ring_multi_reader_ops = {
- .f_create = rte_port_ring_multi_reader_create,
- .f_free = rte_port_ring_reader_free,
- .f_rx = rte_port_ring_multi_reader_rx,
- .f_stats = rte_port_ring_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_ops = {
- .f_create = rte_port_ring_multi_writer_create,
- .f_free = rte_port_ring_writer_free,
- .f_tx = rte_port_ring_multi_writer_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_flush,
- .f_stats = rte_port_ring_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_ring_multi_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops = {
- .f_create = rte_port_ring_multi_writer_nodrop_create,
- .f_free = rte_port_ring_writer_nodrop_free,
- .f_tx = rte_port_ring_multi_writer_nodrop_tx,
- .f_tx_bulk = rte_port_ring_multi_writer_nodrop_tx_bulk,
- .f_flush = rte_port_ring_multi_writer_nodrop_flush,
- .f_stats = rte_port_ring_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_ring.h b/lib/port/rte_port_ring.h
deleted file mode 100644
index 2089d0889b3405ba6892a3e6bf30f34a8603ef4c..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_ring.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_RING_H__
-#define __INCLUDE_RTE_PORT_RING_H__
-
-/**
- * @file
- * RTE Port Ring
- *
- * ring_reader:
- * input port built on top of pre-initialized single consumer ring
- * ring_writer:
- * output port built on top of pre-initialized single producer ring
- * ring_multi_reader:
- * input port built on top of pre-initialized multi consumers ring
- * ring_multi_writer:
- * output port built on top of pre-initialized multi producers ring
- */
-
-#include <stdint.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** ring_reader port parameters */
-struct rte_port_ring_reader_params {
- /** Underlying consumer ring that has to be pre-initialized */
- struct rte_ring *ring;
-};
-
-/** ring_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_reader_ops;
-
-/** ring_writer port parameters */
-struct rte_port_ring_writer_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** ring_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_ops;
-
-/** ring_writer_nodrop port parameters */
-struct rte_port_ring_writer_nodrop_params {
- /** Underlying producer ring that has to be pre-initialized */
- struct rte_ring *ring;
-
- /** Recommended burst size to ring. The actual burst size can be
- bigger or smaller than this value. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit */
- uint32_t n_retries;
-};
-
-/** ring_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_writer_nodrop_ops;
-
-/** ring_multi_reader port parameters */
-#define rte_port_ring_multi_reader_params rte_port_ring_reader_params
-
-/** ring_multi_reader port operations */
-extern struct rte_port_in_ops rte_port_ring_multi_reader_ops;
-
-/** ring_multi_writer port parameters */
-#define rte_port_ring_multi_writer_params rte_port_ring_writer_params
-
-/** ring_multi_writer port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_ops;
-
-/** ring_multi_writer_nodrop port parameters */
-#define rte_port_ring_multi_writer_nodrop_params \
- rte_port_ring_writer_nodrop_params
-
-/** ring_multi_writer_nodrop port operations */
-extern struct rte_port_out_ops rte_port_ring_multi_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sched.c b/lib/port/rte_port_sched.c
deleted file mode 100644
index 3091078aa150f5f6c3d7a31f5809fe5a3a87db9d..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_sched.c
+++ /dev/null
@@ -1,298 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sched.h"
-
-#include "port_log.h"
-
-/*
- * Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_READER_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_READER_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_reader {
- struct rte_port_in_stats stats;
-
- struct rte_sched_port *sched;
-};
-
-static void *
-rte_port_sched_reader_create(void *params, int socket_id)
-{
- struct rte_port_sched_reader_params *conf =
- params;
- struct rte_port_sched_reader *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
-
- return port;
-}
-
-static int
-rte_port_sched_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sched_reader *p = port;
- uint32_t nb_rx;
-
- nb_rx = rte_sched_port_dequeue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_READER_PKTS_IN_ADD(p, nb_rx);
-
- return nb_rx;
-}
-
-static int
-rte_port_sched_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sched_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sched_writer {
- struct rte_port_out_stats stats;
-
- struct rte_mbuf *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- struct rte_sched_port *sched;
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-};
-
-static void *
-rte_port_sched_writer_create(void *params, int socket_id)
-{
- struct rte_port_sched_writer_params *conf =
- params;
- struct rte_port_sched_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->sched == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->sched = conf->sched;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- return port;
-}
-
-static int
-rte_port_sched_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- p->tx_buf[p->tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- __rte_unused uint32_t nb_tx;
- uint64_t n_pkts = rte_popcount64(pkts_mask);
-
- if (tx_buf_count) {
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- nb_tx = rte_sched_port_enqueue(p->sched, pkts, n_pkts);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, n_pkts - nb_tx);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = pkt;
- RTE_PORT_SCHED_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
- p->tx_buf_count = tx_buf_count;
-
- if (tx_buf_count >= p->tx_burst_sz) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf,
- tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_flush(void *port)
-{
- struct rte_port_sched_writer *p = (struct rte_port_sched_writer *) port;
-
- if (p->tx_buf_count) {
- __rte_unused uint32_t nb_tx;
-
- nb_tx = rte_sched_port_enqueue(p->sched, p->tx_buf, p->tx_buf_count);
- RTE_PORT_SCHED_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count - nb_tx);
- p->tx_buf_count = 0;
- }
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sched_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int
-rte_port_sched_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sched_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sched_reader_ops)
-struct rte_port_in_ops rte_port_sched_reader_ops = {
- .f_create = rte_port_sched_reader_create,
- .f_free = rte_port_sched_reader_free,
- .f_rx = rte_port_sched_reader_rx,
- .f_stats = rte_port_sched_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sched_writer_ops)
-struct rte_port_out_ops rte_port_sched_writer_ops = {
- .f_create = rte_port_sched_writer_create,
- .f_free = rte_port_sched_writer_free,
- .f_tx = rte_port_sched_writer_tx,
- .f_tx_bulk = rte_port_sched_writer_tx_bulk,
- .f_flush = rte_port_sched_writer_flush,
- .f_stats = rte_port_sched_writer_stats_read,
-};
diff --git a/lib/port/rte_port_sched.h b/lib/port/rte_port_sched.h
deleted file mode 100644
index 1bf08ae6a9d785896bc2dc08a5697b94a13c29c2..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_sched.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SCHED_H__
-#define __INCLUDE_RTE_PORT_SCHED_H__
-
-/**
- * @file
- * RTE Port Hierarchical Scheduler
- *
- * sched_reader: input port built on top of pre-initialized rte_sched_port
- * sched_writer: output port built on top of pre-initialized rte_sched_port
- */
-
-#include <stdint.h>
-
-#include <rte_sched.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** sched_reader port parameters */
-struct rte_port_sched_reader_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-};
-
-/** sched_reader port operations */
-extern struct rte_port_in_ops rte_port_sched_reader_ops;
-
-/** sched_writer port parameters */
-struct rte_port_sched_writer_params {
- /** Underlying pre-initialized rte_sched_port */
- struct rte_sched_port *sched;
-
- /** Recommended burst size. The actual burst size can be bigger or
- smaller than this value. */
- uint32_t tx_burst_sz;
-};
-
-/** sched_writer port operations */
-extern struct rte_port_out_ops rte_port_sched_writer_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_source_sink.c b/lib/port/rte_port_source_sink.c
deleted file mode 100644
index 0557e125066b92ec1ad390418543ab0a60706415..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_source_sink.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-#include <stdint.h>
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_mbuf.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-
-#ifdef RTE_PORT_PCAP
-#include <rte_ether.h>
-#include <pcap.h>
-#endif
-
-#include "rte_port_source_sink.h"
-
-#include "port_log.h"
-
-/*
- * Port SOURCE
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val) \
- port->stats.n_pkts_in += val
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val) \
- port->stats.n_pkts_drop += val
-
-#else
-
-#define RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SOURCE_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_source {
- struct rte_port_in_stats stats;
-
- struct rte_mempool *mempool;
-
- /* PCAP buffers and indices */
- uint8_t **pkts;
- uint8_t *pkt_buff;
- uint32_t *pkt_len;
- uint32_t n_pkts;
- uint32_t pkt_index;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_source_load(struct rte_port_source *port,
- const char *file_name,
- uint32_t n_bytes_per_pkt,
- int socket_id)
-{
- uint32_t n_pkts = 0;
- uint32_t i;
- uint32_t *pkt_len_aligns = NULL;
- size_t total_buff_len = 0;
- pcap_t *pcap_handle;
- char pcap_errbuf[PCAP_ERRBUF_SIZE];
- uint32_t max_len;
- struct pcap_pkthdr pcap_hdr;
- const uint8_t *pkt;
- uint8_t *buff = NULL;
- uint32_t pktmbuf_maxlen = (uint32_t)
- (rte_pktmbuf_data_room_size(port->mempool) -
- RTE_PKTMBUF_HEADROOM);
-
- if (n_bytes_per_pkt == 0)
- max_len = pktmbuf_maxlen;
- else
- max_len = RTE_MIN(n_bytes_per_pkt, pktmbuf_maxlen);
-
- /* first time open, get packet number */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- while ((pkt = pcap_next(pcap_handle, &pcap_hdr)) != NULL)
- n_pkts++;
-
- pcap_close(pcap_handle);
-
- port->pkt_len = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkt_len) * n_pkts), 0, socket_id);
- if (port->pkt_len == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- pkt_len_aligns = rte_malloc("PCAP",
- (sizeof(*pkt_len_aligns) * n_pkts), 0);
- if (pkt_len_aligns == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkts = rte_zmalloc_socket("PCAP",
- (sizeof(*port->pkts) * n_pkts), 0, socket_id);
- if (port->pkts == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- /* open 2nd time, get pkt_len */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pcap_next(pcap_handle, &pcap_hdr);
- port->pkt_len[i] = RTE_MIN(max_len, pcap_hdr.len);
- pkt_len_aligns[i] = RTE_CACHE_LINE_ROUNDUP(
- port->pkt_len[i]);
- total_buff_len += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- /* allocate a big trunk of data for pcap file load */
- buff = rte_zmalloc_socket("PCAP",
- total_buff_len, 0, socket_id);
- if (buff == NULL) {
- PORT_LOG(ERR, "No enough memory");
- goto error_exit;
- }
-
- port->pkt_buff = buff;
-
- /* open file one last time to copy the pkt content */
- pcap_handle = pcap_open_offline(file_name, pcap_errbuf);
- if (pcap_handle == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "'%s' for reading", file_name);
- goto error_exit;
- }
-
- for (i = 0; i < n_pkts; i++) {
- pkt = pcap_next(pcap_handle, &pcap_hdr);
- rte_memcpy(buff, pkt, port->pkt_len[i]);
- port->pkts[i] = buff;
- buff += pkt_len_aligns[i];
- }
-
- pcap_close(pcap_handle);
-
- port->n_pkts = n_pkts;
-
- rte_free(pkt_len_aligns);
-
- PORT_LOG(INFO, "Successfully load pcap file "
- "'%s' with %u pkts",
- file_name, port->n_pkts);
-
- return 0;
-
-error_exit:
- rte_free(pkt_len_aligns);
- rte_free(port->pkt_len);
- rte_free(port->pkts);
- rte_free(port->pkt_buff);
-
- return -1;
-}
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
- pcap_source_load(port, file_name, n_bytes, socket_id)
-
-#else /* RTE_PORT_PCAP */
-
-#define PCAP_SOURCE_LOAD(port, file_name, n_bytes, socket_id) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Source port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#endif /* RTE_PORT_PCAP */
-
-static void *
-rte_port_source_create(void *params, int socket_id)
-{
- struct rte_port_source_params *p =
- params;
- struct rte_port_source *port;
-
- /* Check input arguments*/
- if ((p == NULL) || (p->mempool == NULL)) {
- PORT_LOG(ERR, "%s: Invalid params", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->mempool = (struct rte_mempool *) p->mempool;
-
- if (p->file_name) {
- int status = PCAP_SOURCE_LOAD(port, p->file_name,
- p->n_bytes_per_pkt, socket_id);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_source_free(void *port)
-{
- struct rte_port_source *p =
- port;
-
- /* Check input parameters */
- if (p == NULL)
- return 0;
-
- rte_free(p->pkt_len);
- rte_free(p->pkts);
- rte_free(p->pkt_buff);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_source_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_source *p = port;
- uint32_t i;
-
- if (rte_pktmbuf_alloc_bulk(p->mempool, pkts, n_pkts) != 0)
- return 0;
-
- if (p->pkt_buff != NULL) {
- for (i = 0; i < n_pkts; i++) {
- uint8_t *pkt_data = rte_pktmbuf_mtod(pkts[i],
- uint8_t *);
-
- rte_memcpy(pkt_data, p->pkts[p->pkt_index],
- p->pkt_len[p->pkt_index]);
- pkts[i]->data_len = p->pkt_len[p->pkt_index];
- pkts[i]->pkt_len = pkts[i]->data_len;
-
- p->pkt_index++;
- if (p->pkt_index >= p->n_pkts)
- p->pkt_index = 0;
- }
- }
-
- RTE_PORT_SOURCE_STATS_PKTS_IN_ADD(p, n_pkts);
-
- return n_pkts;
-}
-
-static int
-rte_port_source_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_source *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port SINK
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val) \
- (port->stats.n_pkts_in += val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val) \
- (port->stats.n_pkts_drop += val)
-
-#else
-
-#define RTE_PORT_SINK_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SINK_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sink {
- struct rte_port_out_stats stats;
-
- /* PCAP dumper handle and pkts number */
- void *dumper;
- uint32_t max_pkts;
- uint32_t pkt_index;
- uint32_t dump_finish;
-};
-
-#ifdef RTE_PORT_PCAP
-
-static int
-pcap_sink_open(struct rte_port_sink *port,
- const char *file_name,
- uint32_t max_n_pkts)
-{
- pcap_t *tx_pcap;
- pcap_dumper_t *pcap_dumper;
-
- /** Open a dead pcap handler for opening dumper file */
- tx_pcap = pcap_open_dead(DLT_EN10MB, 65535);
- if (tx_pcap == NULL) {
- PORT_LOG(ERR, "Cannot open pcap dead handler");
- return -1;
- }
-
- /* The dumper is created using the previous pcap_t reference */
- pcap_dumper = pcap_dump_open(tx_pcap, file_name);
- if (pcap_dumper == NULL) {
- PORT_LOG(ERR, "Failed to open pcap file "
- "\"%s\" for writing", file_name);
- return -1;
- }
-
- port->dumper = pcap_dumper;
- port->max_pkts = max_n_pkts;
- port->pkt_index = 0;
- port->dump_finish = 0;
-
- PORT_LOG(INFO, "Ready to dump packets to file \"%s\"",
- file_name);
-
- return 0;
-}
-
-static void
-pcap_sink_write_pkt(struct rte_port_sink *port, struct rte_mbuf *mbuf)
-{
- uint8_t *pcap_dumper = (port->dumper);
- struct pcap_pkthdr pcap_hdr;
- uint8_t jumbo_pkt_buf[RTE_ETHER_MAX_JUMBO_FRAME_LEN];
- uint8_t *pkt;
-
- /* Maximum num packets already reached */
- if (port->dump_finish)
- return;
-
- pkt = rte_pktmbuf_mtod(mbuf, uint8_t *);
-
- pcap_hdr.len = mbuf->pkt_len;
- pcap_hdr.caplen = pcap_hdr.len;
- gettimeofday(&(pcap_hdr.ts), NULL);
-
- if (mbuf->nb_segs > 1) {
- struct rte_mbuf *jumbo_mbuf;
- uint32_t pkt_index = 0;
-
- /* if packet size longer than RTE_ETHER_MAX_JUMBO_FRAME_LEN,
- * ignore it.
- */
- if (mbuf->pkt_len > RTE_ETHER_MAX_JUMBO_FRAME_LEN)
- return;
-
- for (jumbo_mbuf = mbuf; jumbo_mbuf != NULL;
- jumbo_mbuf = jumbo_mbuf->next) {
- rte_memcpy(&jumbo_pkt_buf[pkt_index],
- rte_pktmbuf_mtod(jumbo_mbuf, uint8_t *),
- jumbo_mbuf->data_len);
- pkt_index += jumbo_mbuf->data_len;
- }
-
- jumbo_pkt_buf[pkt_index] = '\0';
-
- pkt = jumbo_pkt_buf;
- }
-
- pcap_dump(pcap_dumper, &pcap_hdr, pkt);
-
- port->pkt_index++;
-
- if ((port->max_pkts != 0) && (port->pkt_index >= port->max_pkts)) {
- port->dump_finish = 1;
- PORT_LOG(INFO, "Dumped %u packets to file",
- port->pkt_index);
- }
-
-}
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
- pcap_sink_open(port, file_name, max_n_pkts)
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) \
- pcap_sink_write_pkt(port, mbuf)
-
-#define PCAP_SINK_FLUSH_PKT(dumper) \
-do { \
- if (dumper) \
- pcap_dump_flush((pcap_dumper_t *)dumper); \
-} while (0)
-
-#define PCAP_SINK_CLOSE(dumper) \
-do { \
- if (dumper) \
- pcap_dump_close((pcap_dumper_t *)dumper); \
-} while (0)
-
-#else
-
-#define PCAP_SINK_OPEN(port, file_name, max_n_pkts) \
-__extension__ ({ \
- int _ret = 0; \
- \
- if (file_name) { \
- PORT_LOG(ERR, "Sink port field " \
- "\"file_name\" is not NULL."); \
- _ret = -1; \
- } \
- \
- _ret; \
-})
-
-#define PCAP_SINK_WRITE_PKT(port, mbuf) {}
-
-#define PCAP_SINK_FLUSH_PKT(dumper)
-
-#define PCAP_SINK_CLOSE(dumper)
-
-#endif
-
-static void *
-rte_port_sink_create(void *params, int socket_id)
-{
- struct rte_port_sink *port;
- struct rte_port_sink_params *p = params;
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- if (!p)
- return port;
-
- if (p->file_name) {
- int status = PCAP_SINK_OPEN(port, p->file_name,
- p->max_n_pkts);
-
- if (status < 0) {
- rte_free(port);
- port = NULL;
- }
- }
-
- return port;
-}
-
-static int
-rte_port_sink_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sink *p = port;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- if (p->dumper != NULL)
- PCAP_SINK_WRITE_PKT(p, pkt);
- rte_pktmbuf_free(pkt);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
-
- return 0;
-}
-
-static int
-rte_port_sink_tx_bulk(void *port, struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sink *p = port;
-
- if ((pkts_mask & (pkts_mask + 1)) == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, n_pkts);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, n_pkts);
-
- if (p->dumper) {
- for (i = 0; i < n_pkts; i++)
- PCAP_SINK_WRITE_PKT(p, pkts[i]);
- }
-
- for (i = 0; i < n_pkts; i++) {
- struct rte_mbuf *pkt = pkts[i];
-
- rte_pktmbuf_free(pkt);
- }
-
- } else {
- if (p->dumper) {
- uint64_t dump_pkts_mask = pkts_mask;
- uint32_t pkt_index;
-
- for ( ; dump_pkts_mask; ) {
- pkt_index = rte_ctz64(
- dump_pkts_mask);
- PCAP_SINK_WRITE_PKT(p, pkts[pkt_index]);
- dump_pkts_mask &= ~(1LLU << pkt_index);
- }
- }
-
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- RTE_PORT_SINK_STATS_PKTS_IN_ADD(p, 1);
- RTE_PORT_SINK_STATS_PKTS_DROP_ADD(p, 1);
- rte_pktmbuf_free(pkt);
- pkts_mask &= ~pkt_mask;
- }
- }
-
- return 0;
-}
-
-static int
-rte_port_sink_flush(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_FLUSH_PKT(p->dumper);
-
- return 0;
-}
-
-static int
-rte_port_sink_free(void *port)
-{
- struct rte_port_sink *p =
- port;
-
- if (p == NULL)
- return 0;
-
- PCAP_SINK_CLOSE(p->dumper);
-
- rte_free(p);
-
- return 0;
-}
-
-static int
-rte_port_sink_stats_read(void *port, struct rte_port_out_stats *stats,
- int clear)
-{
- struct rte_port_sink *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_source_ops)
-struct rte_port_in_ops rte_port_source_ops = {
- .f_create = rte_port_source_create,
- .f_free = rte_port_source_free,
- .f_rx = rte_port_source_rx,
- .f_stats = rte_port_source_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sink_ops)
-struct rte_port_out_ops rte_port_sink_ops = {
- .f_create = rte_port_sink_create,
- .f_free = rte_port_sink_free,
- .f_tx = rte_port_sink_tx,
- .f_tx_bulk = rte_port_sink_tx_bulk,
- .f_flush = rte_port_sink_flush,
- .f_stats = rte_port_sink_stats_read,
-};
diff --git a/lib/port/rte_port_source_sink.h b/lib/port/rte_port_source_sink.h
deleted file mode 100644
index 3122dd50380e305ce386e6962a188888262fffa2..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_source_sink.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-#define __INCLUDE_RTE_PORT_SOURCE_SINK_H__
-
-/**
- * @file
- * RTE Port Source/Sink
- *
- * source: input port that can be used to generate packets
- * sink: output port that drops all packets written to it
- */
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** source port parameters */
-struct rte_port_source_params {
- /** Pre-initialized buffer pool */
- struct rte_mempool *mempool;
-
- /** The full path of the pcap file to read packets from */
- const char *file_name;
- /** The number of bytes to be read from each packet in the
- * pcap file. If this value is 0, the whole packet is read;
- * if it is bigger than packet size, the generated packets
- * will contain the whole packet */
- uint32_t n_bytes_per_pkt;
-};
-
-/** source port operations */
-extern struct rte_port_in_ops rte_port_source_ops;
-
-/** sink port parameters */
-struct rte_port_sink_params {
- /** The full path of the pcap file to write the packets to */
- const char *file_name;
- /** The maximum number of packets write to the pcap file.
- * If this value is 0, the "infinite" write will be carried
- * out.
- */
- uint32_t max_n_pkts;
-};
-
-/** sink port operations */
-extern struct rte_port_out_ops rte_port_sink_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/port/rte_port_sym_crypto.c b/lib/port/rte_port_sym_crypto.c
deleted file mode 100644
index 30c9d1283e63b6ba3350c0d25ce082cb7b295500..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_sym_crypto.c
+++ /dev/null
@@ -1,558 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-#include <string.h>
-
-#include <eal_export.h>
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "rte_port_sym_crypto.h"
-
-#include "port_log.h"
-
-/*
- * Port Crypto Reader
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_reader {
- struct rte_port_in_stats stats;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- struct rte_crypto_op *ops[RTE_PORT_IN_BURST_SIZE_MAX];
- rte_port_sym_crypto_reader_callback_fn f_callback;
- void *arg_callback;
-};
-
-static void *
-rte_port_sym_crypto_reader_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_reader_params *conf =
- params;
- struct rte_port_sym_crypto_reader *port;
-
- /* Check input parameters */
- if (conf == NULL) {
- PORT_LOG(ERR, "%s: params is NULL", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->f_callback = conf->f_callback;
- port->arg_callback = conf->arg_callback;
-
- return port;
-}
-
-static int
-rte_port_sym_crypto_reader_rx(void *port, struct rte_mbuf **pkts, uint32_t n_pkts)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
- uint16_t rx_ops_cnt, i, n = 0;
-
- rx_ops_cnt = rte_cryptodev_dequeue_burst(p->cryptodev_id, p->queue_id,
- p->ops, n_pkts);
-
- for (i = 0; i < rx_ops_cnt; i++) {
- struct rte_crypto_op *op = p->ops[i];
-
- /** Drop failed pkts */
- if (unlikely(op->status != RTE_CRYPTO_OP_STATUS_SUCCESS)) {
- rte_pktmbuf_free(op->sym->m_src);
- continue;
- }
-
- pkts[n++] = op->sym->m_src;
- }
-
- if (p->f_callback)
- (*p->f_callback)(pkts, n, p->arg_callback);
-
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_IN_ADD(p, n);
- RTE_PORT_SYM_CRYPTO_READER_STATS_PKTS_DROP_ADD(p, rx_ops_cnt - n);
-
- return n;
-}
-
-static int
-rte_port_sym_crypto_reader_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_reader_stats_read(void *port,
- struct rte_port_in_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_reader *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
-
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_params *conf =
- params;
- struct rte_port_sym_crypto_writer *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
-
- return port;
-}
-
-static inline void
-send_burst(struct rte_port_sym_crypto_writer *p)
-{
- uint32_t nb_tx;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_DROP_ADD(p, p->tx_buf_count -
- nb_tx);
- for (; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- } else {
- for (; pkts_mask;) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
-
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_flush(void *port)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-/*
- * Port crypto Writer Nodrop
- */
-#ifdef RTE_PORT_STATS_COLLECT
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val) \
- (port)->stats.n_pkts_in += (val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val) \
- (port)->stats.n_pkts_drop += (val)
-
-#else
-
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(port, val)
-#define RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(port, val)
-
-#endif
-
-struct rte_port_sym_crypto_writer_nodrop {
- struct rte_port_out_stats stats;
-
- struct rte_crypto_op *tx_buf[2 * RTE_PORT_IN_BURST_SIZE_MAX];
- uint32_t tx_burst_sz;
- uint32_t tx_buf_count;
- uint64_t bsz_mask;
- uint64_t n_retries;
-
- uint8_t cryptodev_id;
- uint16_t queue_id;
- uint16_t crypto_op_offset;
-};
-
-static void *
-rte_port_sym_crypto_writer_nodrop_create(void *params, int socket_id)
-{
- struct rte_port_sym_crypto_writer_nodrop_params *conf =
- params;
- struct rte_port_sym_crypto_writer_nodrop *port;
-
- /* Check input parameters */
- if ((conf == NULL) ||
- (conf->tx_burst_sz == 0) ||
- (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX) ||
- (!rte_is_power_of_2(conf->tx_burst_sz))) {
- PORT_LOG(ERR, "%s: Invalid input parameters", __func__);
- return NULL;
- }
-
- /* Memory allocation */
- port = rte_zmalloc_socket("PORT", sizeof(*port),
- RTE_CACHE_LINE_SIZE, socket_id);
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Failed to allocate port", __func__);
- return NULL;
- }
-
- /* Initialization */
- port->cryptodev_id = conf->cryptodev_id;
- port->queue_id = conf->queue_id;
- port->crypto_op_offset = conf->crypto_op_offset;
- port->tx_burst_sz = conf->tx_burst_sz;
- port->tx_buf_count = 0;
- port->bsz_mask = 1LLU << (conf->tx_burst_sz - 1);
-
- /*
- * When n_retries is 0 it means that we should wait for every packet to
- * send no matter how many retries should it take. To limit number of
- * branches in fast path, we use UINT64_MAX instead of branching.
- */
- port->n_retries = (conf->n_retries == 0) ? UINT64_MAX : conf->n_retries;
-
- return port;
-}
-
-static inline void
-send_burst_nodrop(struct rte_port_sym_crypto_writer_nodrop *p)
-{
- uint32_t nb_tx = 0, i;
-
- nb_tx = rte_cryptodev_enqueue_burst(p->cryptodev_id, p->queue_id,
- p->tx_buf, p->tx_buf_count);
-
- /* We sent all the packets in a first try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
-
- for (i = 0; i < p->n_retries; i++) {
- nb_tx += rte_cryptodev_enqueue_burst(p->cryptodev_id,
- p->queue_id, p->tx_buf + nb_tx,
- p->tx_buf_count - nb_tx);
-
- /* We sent all the packets in more than one try */
- if (nb_tx >= p->tx_buf_count) {
- p->tx_buf_count = 0;
- return;
- }
- }
-
- /* We didn't send the packets in maximum allowed attempts */
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_DROP_ADD(p,
- p->tx_buf_count - nb_tx);
- for ( ; nb_tx < p->tx_buf_count; nb_tx++)
- rte_pktmbuf_free(p->tx_buf[nb_tx]->sym->m_src);
-
- p->tx_buf_count = 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx(void *port, struct rte_mbuf *pkt)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_STATS_PKTS_IN_ADD(p, 1);
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_tx_bulk(void *port,
- struct rte_mbuf **pkts,
- uint64_t pkts_mask)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- uint64_t bsz_mask = p->bsz_mask;
- uint32_t tx_buf_count = p->tx_buf_count;
- uint64_t expr = (pkts_mask & (pkts_mask + 1)) |
- ((pkts_mask & bsz_mask) ^ bsz_mask);
-
- if (expr == 0) {
- uint64_t n_pkts = rte_popcount64(pkts_mask);
- uint32_t i;
-
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p, n_pkts);
-
- for (i = 0; i < n_pkts; i++)
- p->tx_buf[p->tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[i],
- p->crypto_op_offset);
-
- if (p->tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- } else {
- for ( ; pkts_mask; ) {
- uint32_t pkt_index = rte_ctz64(pkts_mask);
- uint64_t pkt_mask = 1LLU << pkt_index;
- struct rte_mbuf *pkt = pkts[pkt_index];
-
- p->tx_buf[tx_buf_count++] = (struct rte_crypto_op *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt,
- p->crypto_op_offset);
- RTE_PORT_SYM_CRYPTO_WRITER_NODROP_STATS_PKTS_IN_ADD(p,
- 1);
- pkts_mask &= ~pkt_mask;
- }
-
- p->tx_buf_count = tx_buf_count;
- if (tx_buf_count >= p->tx_burst_sz)
- send_burst_nodrop(p);
- }
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_flush(void *port)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (p->tx_buf_count > 0)
- send_burst_nodrop(p);
-
- return 0;
-}
-
-static int
-rte_port_sym_crypto_writer_nodrop_free(void *port)
-{
- if (port == NULL) {
- PORT_LOG(ERR, "%s: Port is NULL", __func__);
- return -EINVAL;
- }
-
- rte_port_sym_crypto_writer_nodrop_flush(port);
- rte_free(port);
-
- return 0;
-}
-
-static int rte_port_sym_crypto_writer_nodrop_stats_read(void *port,
- struct rte_port_out_stats *stats, int clear)
-{
- struct rte_port_sym_crypto_writer_nodrop *p =
- port;
-
- if (stats != NULL)
- memcpy(stats, &p->stats, sizeof(p->stats));
-
- if (clear)
- memset(&p->stats, 0, sizeof(p->stats));
-
- return 0;
-}
-
-
-/*
- * Summary of port operations
- */
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_reader_ops)
-struct rte_port_in_ops rte_port_sym_crypto_reader_ops = {
- .f_create = rte_port_sym_crypto_reader_create,
- .f_free = rte_port_sym_crypto_reader_free,
- .f_rx = rte_port_sym_crypto_reader_rx,
- .f_stats = rte_port_sym_crypto_reader_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_ops = {
- .f_create = rte_port_sym_crypto_writer_create,
- .f_free = rte_port_sym_crypto_writer_free,
- .f_tx = rte_port_sym_crypto_writer_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_flush,
- .f_stats = rte_port_sym_crypto_writer_stats_read,
-};
-
-RTE_EXPORT_SYMBOL(rte_port_sym_crypto_writer_nodrop_ops)
-struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops = {
- .f_create = rte_port_sym_crypto_writer_nodrop_create,
- .f_free = rte_port_sym_crypto_writer_nodrop_free,
- .f_tx = rte_port_sym_crypto_writer_nodrop_tx,
- .f_tx_bulk = rte_port_sym_crypto_writer_nodrop_tx_bulk,
- .f_flush = rte_port_sym_crypto_writer_nodrop_flush,
- .f_stats = rte_port_sym_crypto_writer_nodrop_stats_read,
-};
diff --git a/lib/port/rte_port_sym_crypto.h b/lib/port/rte_port_sym_crypto.h
deleted file mode 100644
index d03cdc1e8ba7f0a338d91188f3a1fd2998aefb8f..0000000000000000000000000000000000000000
--- a/lib/port/rte_port_sym_crypto.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2018 Intel Corporation
- */
-
-#ifndef __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-#define __INCLUDE_RTE_PORT_SYM_CRYPTO_H__
-
-/**
- * @file
- * RTE Port sym crypto Interface
- *
- * crypto_reader: input port built on top of pre-initialized crypto interface
- * crypto_writer: output port built on top of pre-initialized crypto interface
- */
-
-#include <stdint.h>
-
-#include <rte_cryptodev.h>
-
-#include "rte_port.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/** Function prototype for reader post action. */
-typedef void (*rte_port_sym_crypto_reader_callback_fn)(struct rte_mbuf **pkts,
- uint16_t n_pkts, void *arg);
-
-/** Crypto_reader port parameters */
-struct rte_port_sym_crypto_reader_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** Crypto reader post callback function. */
- rte_port_sym_crypto_reader_callback_fn f_callback;
-
- /** Crypto reader post callback function arguments. */
- void *arg_callback;
-};
-
-/** Crypto_reader port operations. */
-extern struct rte_port_in_ops rte_port_sym_crypto_reader_ops;
-
-
-/** Crypto_writer port parameters. */
-struct rte_port_sym_crypto_writer_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev Queue Pair ID. */
- uint16_t queue_id;
-
- /** offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-};
-
-/** Crypto_writer port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_ops;
-
-/** Crypto_writer_nodrop port parameters. */
-struct rte_port_sym_crypto_writer_nodrop_params {
- /** Target cryptodev ID. */
- uint8_t cryptodev_id;
-
- /** Target cryptodev queue pair id. */
- uint16_t queue_id;
-
- /** Offset to rte_crypto_op in the mbufs. */
- uint16_t crypto_op_offset;
-
- /** Burst size to crypto interface. */
- uint32_t tx_burst_sz;
-
- /** Maximum number of retries, 0 for no limit. */
- uint32_t n_retries;
-};
-
-/** Crypto_writer_nodrop port operations. */
-extern struct rte_port_out_ops rte_port_sym_crypto_writer_nodrop_ops;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 29+ messages in thread* [PATCH v4 7/7] doc: remove packet framework images
2026-07-24 16:43 [PATCH 0/6] remove legacy Packet Framework API Stephen Hemminger
` (14 preceding siblings ...)
2026-07-28 16:35 ` [PATCH v4 6/7] port: " Stephen Hemminger
@ 2026-07-28 16:35 ` Stephen Hemminger
15 siblings, 0 replies; 29+ messages in thread
From: Stephen Hemminger @ 2026-07-28 16:35 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
Remove no longer used documentation images.
Split out as standalone patch to workaround patchwork encoding
issues.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
doc/guides/prog_guide/img/figure32.png | Bin 11603 -> 0 bytes
doc/guides/prog_guide/img/figure33.png | Bin 65216 -> 0 bytes
doc/guides/prog_guide/img/figure34.png | Bin 11581 -> 0 bytes
doc/guides/prog_guide/img/figure35.png | Bin 75012 -> 0 bytes
doc/guides/prog_guide/img/figure37.png | Bin 6934 -> 0 bytes
doc/guides/prog_guide/img/figure38.png | Bin 7372 -> 0 bytes
doc/guides/prog_guide/img/figure39.png | Bin 55986 -> 0 bytes
.../sample_app_ug/img/test_pipeline_app.png | Bin 67410 -> 0 bytes
8 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 doc/guides/prog_guide/img/figure32.png
delete mode 100644 doc/guides/prog_guide/img/figure33.png
delete mode 100644 doc/guides/prog_guide/img/figure34.png
delete mode 100644 doc/guides/prog_guide/img/figure35.png
delete mode 100644 doc/guides/prog_guide/img/figure37.png
delete mode 100644 doc/guides/prog_guide/img/figure38.png
delete mode 100644 doc/guides/prog_guide/img/figure39.png
delete mode 100644 doc/guides/sample_app_ug/img/test_pipeline_app.png
diff --git a/doc/guides/prog_guide/img/figure32.png b/doc/guides/prog_guide/img/figure32.png
deleted file mode 100644
index 5215113fd9d533ff56526e21e1832bc7a6cabd04..0000000000000000000000000000000000000000
Binary files a/doc/guides/prog_guide/img/figure32.png and /dev/null differ
diff --git a/doc/guides/prog_guide/img/figure33.png b/doc/guides/prog_guide/img/figure33.png
deleted file mode 100644
index f0670eb0053da643e1ee932ee3f30fdd0aa973e6..0000000000000000000000000000000000000000
Binary files a/doc/guides/prog_guide/img/figure33.png and /dev/null differ
diff --git a/doc/guides/prog_guide/img/figure34.png b/doc/guides/prog_guide/img/figure34.png
deleted file mode 100644
index caa2517a4013acbfc7c405866abfa180dbcacb63..0000000000000000000000000000000000000000
Binary files a/doc/guides/prog_guide/img/figure34.png and /dev/null differ
diff --git a/doc/guides/prog_guide/img/figure35.png b/doc/guides/prog_guide/img/figure35.png
deleted file mode 100644
index 42053f006745dbe7e02869817995e2b38dc56932..0000000000000000000000000000000000000000
Binary files a/doc/guides/prog_guide/img/figure35.png and /dev/null differ
diff --git a/doc/guides/prog_guide/img/figure37.png b/doc/guides/prog_guide/img/figure37.png
deleted file mode 100644
index 20be4aaa6de8040339e0db4200a5e800816f14b7..0000000000000000000000000000000000000000
Binary files a/doc/guides/prog_guide/img/figure37.png and /dev/null differ
diff --git a/doc/guides/prog_guide/img/figure38.png b/doc/guides/prog_guide/img/figure38.png
deleted file mode 100644
index 261c561f98a98d572c9247b7187b33f7e03002ce..0000000000000000000000000000000000000000
Binary files a/doc/guides/prog_guide/img/figure38.png and /dev/null differ
diff --git a/doc/guides/prog_guide/img/figure39.png b/doc/guides/prog_guide/img/figure39.png
deleted file mode 100644
index d2db6a499a0f764b9e661b905b0f136ea871b457..0000000000000000000000000000000000000000
Binary files a/doc/guides/prog_guide/img/figure39.png and /dev/null differ
diff --git a/doc/guides/sample_app_ug/img/test_pipeline_app.png b/doc/guides/sample_app_ug/img/test_pipeline_app.png
deleted file mode 100644
index d322a9e46e5e714126988a76456c9eae41635879..0000000000000000000000000000000000000000
Binary files a/doc/guides/sample_app_ug/img/test_pipeline_app.png and /dev/null differ
--
2.53.0
^ permalink raw reply [flat|nested] 29+ messages in thread