summaryrefslogtreecommitdiffstats
path: root/examples/ip_pipeline
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ip_pipeline')
-rw-r--r--examples/ip_pipeline/Makefile55
-rw-r--r--examples/ip_pipeline/action.c358
-rw-r--r--examples/ip_pipeline/action.h77
-rw-r--r--examples/ip_pipeline/app.h1401
-rw-r--r--examples/ip_pipeline/cli.c5240
-rw-r--r--examples/ip_pipeline/cli.h18
-rw-r--r--examples/ip_pipeline/common.h12
-rw-r--r--examples/ip_pipeline/config/action.cfg68
-rw-r--r--examples/ip_pipeline/config/action.sh119
-rw-r--r--examples/ip_pipeline/config/action.txt8
-rwxr-xr-xexamples/ip_pipeline/config/diagram-generator.py317
-rw-r--r--examples/ip_pipeline/config/edge_router_downstream.cfg97
-rw-r--r--examples/ip_pipeline/config/edge_router_downstream.sh13
-rw-r--r--examples/ip_pipeline/config/edge_router_upstream.cfg124
-rw-r--r--examples/ip_pipeline/config/edge_router_upstream.sh33
-rw-r--r--examples/ip_pipeline/config/firewall.cfg68
-rw-r--r--examples/ip_pipeline/config/firewall.sh13
-rw-r--r--examples/ip_pipeline/config/firewall.txt9
-rw-r--r--examples/ip_pipeline/config/flow.cfg72
-rw-r--r--examples/ip_pipeline/config/flow.sh25
-rw-r--r--examples/ip_pipeline/config/flow.txt17
-rw-r--r--examples/ip_pipeline/config/ip_pipeline.cfg9
-rw-r--r--examples/ip_pipeline/config/ip_pipeline.sh5
-rw-r--r--examples/ip_pipeline/config/kni.cfg67
-rw-r--r--examples/ip_pipeline/config/l2fwd.cfg58
-rw-r--r--examples/ip_pipeline/config/l3fwd.cfg68
-rw-r--r--examples/ip_pipeline/config/l3fwd.sh33
-rw-r--r--examples/ip_pipeline/config/l3fwd_arp.cfg70
-rw-r--r--examples/ip_pipeline/config/l3fwd_arp.sh43
-rw-r--r--examples/ip_pipeline/config/network_layers.cfg227
-rw-r--r--examples/ip_pipeline/config/network_layers.sh79
-rwxr-xr-xexamples/ip_pipeline/config/pipeline-to-core-mapping.py906
-rw-r--r--examples/ip_pipeline/config/tap.cfg64
-rw-r--r--examples/ip_pipeline/config/tm_profile.cfg105
-rw-r--r--examples/ip_pipeline/config_check.c488
-rw-r--r--examples/ip_pipeline/config_parse.c3395
-rw-r--r--examples/ip_pipeline/config_parse_tm.c419
-rw-r--r--examples/ip_pipeline/conn.c329
-rw-r--r--examples/ip_pipeline/conn.h47
-rw-r--r--examples/ip_pipeline/cpu_core_map.c471
-rw-r--r--examples/ip_pipeline/cpu_core_map.h40
-rw-r--r--examples/ip_pipeline/examples/firewall.cli59
-rw-r--r--examples/ip_pipeline/examples/flow.cli60
-rw-r--r--examples/ip_pipeline/examples/kni.cli69
-rw-r--r--examples/ip_pipeline/examples/l2fwd.cli51
-rw-r--r--examples/ip_pipeline/examples/route.cli60
-rw-r--r--examples/ip_pipeline/examples/route_ecmp.cli57
-rw-r--r--examples/ip_pipeline/examples/rss.cli112
-rw-r--r--examples/ip_pipeline/examples/tap.cli66
-rw-r--r--examples/ip_pipeline/hash_func.h (renamed from examples/ip_pipeline/pipeline/hash_func.h)3
-rw-r--r--examples/ip_pipeline/hash_func_arm64.h (renamed from examples/ip_pipeline/pipeline/hash_func_arm64.h)33
-rw-r--r--examples/ip_pipeline/init.c1927
-rw-r--r--examples/ip_pipeline/kni.c175
-rw-r--r--examples/ip_pipeline/kni.h46
-rw-r--r--examples/ip_pipeline/link.c267
-rw-r--r--examples/ip_pipeline/link.h66
-rw-r--r--examples/ip_pipeline/main.c259
-rw-r--r--examples/ip_pipeline/mempool.c82
-rw-r--r--examples/ip_pipeline/mempool.h40
-rw-r--r--examples/ip_pipeline/meson.build36
-rw-r--r--examples/ip_pipeline/parser.c17
-rw-r--r--examples/ip_pipeline/parser.h8
-rw-r--r--examples/ip_pipeline/pipeline.c988
-rw-r--r--examples/ip_pipeline/pipeline.h389
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_actions_common.h202
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_common_be.c176
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_common_be.h134
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_common_fe.c1455
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_common_fe.h231
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_firewall.c1421
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_firewall.h60
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_firewall_be.c856
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_firewall_be.h147
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_actions.c1286
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_actions.h60
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c960
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_actions_be.h139
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_classification.c1878
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_classification.h106
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c723
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h113
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_master.c20
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_master.h12
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_master_be.c141
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_master_be.h12
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_passthrough.c45
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_passthrough.h12
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_passthrough_be.c929
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_passthrough_be.h44
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_routing.c1613
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_routing.h71
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_routing_be.c1966
-rw-r--r--examples/ip_pipeline/pipeline/pipeline_routing_be.h283
-rw-r--r--examples/ip_pipeline/pipeline_be.h322
-rw-r--r--examples/ip_pipeline/swq.c76
-rw-r--r--examples/ip_pipeline/swq.h37
-rw-r--r--examples/ip_pipeline/tap.c102
-rw-r--r--examples/ip_pipeline/tap.h29
-rw-r--r--examples/ip_pipeline/thread.c3053
-rw-r--r--examples/ip_pipeline/thread.h75
-rw-r--r--examples/ip_pipeline/thread_fe.c457
-rw-r--r--examples/ip_pipeline/thread_fe.h72
-rw-r--r--examples/ip_pipeline/tmgr.c229
-rw-r--r--examples/ip_pipeline/tmgr.h70
104 files changed, 12344 insertions, 27210 deletions
diff --git a/examples/ip_pipeline/Makefile b/examples/ip_pipeline/Makefile
index 27f7cc6a..3fb98ce3 100644
--- a/examples/ip_pipeline/Makefile
+++ b/examples/ip_pipeline/Makefile
@@ -1,34 +1,23 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2010-2014 Intel Corporation
+# Copyright(c) 2010-2018 Intel Corporation
# binary name
APP = ip_pipeline
# all source are stored in SRCS-y
-SRCS-y := main.c
-SRCS-y += config_parse.c
+SRCS-y := action.c
+SRCS-y += cli.c
+SRCS-y += conn.c
+SRCS-y += kni.c
+SRCS-y += link.c
+SRCS-y += main.c
+SRCS-y += mempool.c
SRCS-y += parser.c
-SRCS-y += config_parse_tm.c
-SRCS-y += config_check.c
-SRCS-y += init.c
+SRCS-y += pipeline.c
+SRCS-y += swq.c
+SRCS-y += tap.c
SRCS-y += thread.c
-SRCS-y += thread_fe.c
-SRCS-y += cpu_core_map.c
-
-SRCS-y += pipeline_common_be.c
-SRCS-y += pipeline_common_fe.c
-SRCS-y += pipeline_master_be.c
-SRCS-y += pipeline_master.c
-SRCS-y += pipeline_passthrough_be.c
-SRCS-y += pipeline_passthrough.c
-SRCS-y += pipeline_firewall_be.c
-SRCS-y += pipeline_firewall.c
-SRCS-y += pipeline_flow_classification_be.c
-SRCS-y += pipeline_flow_classification.c
-SRCS-y += pipeline_flow_actions_be.c
-SRCS-y += pipeline_flow_actions.c
-SRCS-y += pipeline_routing_be.c
-SRCS-y += pipeline_routing.c
+SRCS-y += tmgr.c
# Build using pkg-config variables if possible
$(shell pkg-config --exists libdpdk)
@@ -46,8 +35,7 @@ CFLAGS += -O3 $(shell pkg-config --cflags libdpdk)
LDFLAGS_SHARED = $(shell pkg-config --libs libdpdk)
LDFLAGS_STATIC = -Wl,-Bstatic $(shell pkg-config --static --libs libdpdk)
-VPATH += pipeline
-CFLAGS += -I. -I./pipeline/
+CFLAGS += -I.
OBJS := $(patsubst %.c,build/%.o,$(SRCS-y))
@@ -74,21 +62,28 @@ ifeq ($(RTE_SDK),)
$(error "Please define RTE_SDK environment variable")
endif
-VPATH += $(SRCDIR)/pipeline
-
# Default target, can be overridden by command line or environment
RTE_TARGET ?= x86_64-native-linuxapp-gcc
include $(RTE_SDK)/mk/rte.vars.mk
-INC += $(sort $(wildcard *.h)) $(sort $(wildcard pipeline/*.h))
+ifneq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+$(info This application can only operate in a linuxapp environment, \
+please change the definition of the RTE_TARGET environment variable)
+all:
+clean:
+else
+
+INC += $(sort $(wildcard *.h))
SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := $(SRCS-y)
-CFLAGS += -I$(SRCDIR) -I$(SRCDIR)/pipeline
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -I$(SRCDIR)
CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS) -Wno-error=unused-function -Wno-error=unused-variable
+CFLAGS += $(WERROR_FLAGS)
include $(RTE_SDK)/mk/rte.extapp.mk
endif
+endif
diff --git a/examples/ip_pipeline/action.c b/examples/ip_pipeline/action.c
new file mode 100644
index 00000000..a29c2b36
--- /dev/null
+++ b/examples/ip_pipeline/action.c
@@ -0,0 +1,358 @@
+/* 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 "action.h"
+#include "hash_func.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 = hash_default_key8;
+ break;
+
+ case 16:
+ params->lb.f_hash = hash_default_key16;
+ break;
+
+ case 24:
+ params->lb.f_hash = hash_default_key24;
+ break;
+
+ case 32:
+ params->lb.f_hash = hash_default_key32;
+ break;
+
+ case 40:
+ params->lb.f_hash = hash_default_key40;
+ break;
+
+ case 48:
+ params->lb.f_hash = hash_default_key48;
+ break;
+
+ case 56:
+ params->lb.f_hash = hash_default_key56;
+ break;
+
+ case 64:
+ params->lb.f_hash = hash_default_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,
+ &params->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,
+ &params->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 = hash_default_key8;
+ break;
+
+ case 16:
+ params->lb.f_hash = hash_default_key16;
+ break;
+
+ case 24:
+ params->lb.f_hash = hash_default_key24;
+ break;
+
+ case 32:
+ params->lb.f_hash = hash_default_key32;
+ break;
+
+ case 40:
+ params->lb.f_hash = hash_default_key40;
+ break;
+
+ case 48:
+ params->lb.f_hash = hash_default_key48;
+ break;
+
+ case 56:
+ params->lb.f_hash = hash_default_key56;
+ break;
+
+ case 64:
+ params->lb.f_hash = hash_default_key64;
+ break;
+
+ default:
+ return NULL;
+ }
+
+ params->lb.seed = 0;
+ }
+
+ /* Resource */
+ ap = rte_table_action_profile_create(&params->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,
+ &params->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,
+ &params->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,
+ &params->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,
+ &params->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,
+ &params->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,
+ &params->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,
+ &params->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;
+ }
+ }
+
+ 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
new file mode 100644
index 00000000..417200e8
--- /dev/null
+++ b/examples/ip_pipeline/action.h
@@ -0,0 +1,77 @@
+/* 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 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/app.h b/examples/ip_pipeline/app.h
deleted file mode 100644
index 907d4e7c..00000000
--- a/examples/ip_pipeline/app.h
+++ /dev/null
@@ -1,1401 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_APP_H__
-#define __INCLUDE_APP_H__
-
-#include <stdint.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_mempool.h>
-#include <rte_ring.h>
-#include <rte_sched.h>
-#include <cmdline_parse.h>
-
-#include <rte_ethdev.h>
-#ifdef RTE_LIBRTE_KNI
-#include <rte_kni.h>
-#endif
-
-#include "cpu_core_map.h"
-#include "pipeline.h"
-
-#define APP_PARAM_NAME_SIZE PIPELINE_NAME_SIZE
-#define APP_LINK_PCI_BDF_SIZE 16
-
-#ifndef APP_LINK_MAX_HWQ_IN
-#define APP_LINK_MAX_HWQ_IN 128
-#endif
-
-#ifndef APP_LINK_MAX_HWQ_OUT
-#define APP_LINK_MAX_HWQ_OUT 128
-#endif
-
-struct app_mempool_params {
- char *name;
- uint32_t parsed;
- uint32_t buffer_size;
- uint32_t pool_size;
- uint32_t cache_size;
- uint32_t cpu_socket_id;
-};
-
-struct app_link_params {
- char *name;
- uint32_t parsed;
- uint32_t pmd_id; /* Generated based on port mask */
- uint32_t arp_q; /* 0 = Disabled (packets go to default queue 0) */
- uint32_t tcp_syn_q; /* 0 = Disabled (pkts go to default queue) */
- uint32_t ip_local_q; /* 0 = Disabled (pkts go to default queue 0) */
- uint32_t tcp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
- uint32_t udp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
- uint32_t sctp_local_q; /* 0 = Disabled (pkts go to default queue 0) */
- uint32_t rss_qs[APP_LINK_MAX_HWQ_IN];
- uint32_t n_rss_qs;
- uint64_t rss_proto_ipv4;
- uint64_t rss_proto_ipv6;
- uint64_t rss_proto_l2;
- uint32_t promisc;
- uint32_t state; /* DOWN = 0, UP = 1 */
- uint32_t ip; /* 0 = Invalid */
- uint32_t depth; /* Valid only when IP is valid */
- uint64_t mac_addr; /* Read from HW */
- char pci_bdf[APP_LINK_PCI_BDF_SIZE];
-
- struct rte_eth_conf conf;
-};
-
-struct app_pktq_hwq_in_params {
- char *name;
- uint32_t parsed;
- uint32_t mempool_id; /* Position in the app->mempool_params */
- uint32_t size;
- uint32_t burst;
-
- struct rte_eth_rxconf conf;
-};
-
-struct app_pktq_hwq_out_params {
- char *name;
- uint32_t parsed;
- uint32_t size;
- uint32_t burst;
- uint32_t dropless;
- uint64_t n_retries;
- struct rte_eth_txconf conf;
-};
-
-struct app_pktq_swq_params {
- char *name;
- uint32_t parsed;
- uint32_t size;
- uint32_t burst_read;
- uint32_t burst_write;
- uint32_t dropless;
- uint64_t n_retries;
- uint32_t cpu_socket_id;
- uint32_t ipv4_frag;
- uint32_t ipv6_frag;
- uint32_t ipv4_ras;
- uint32_t ipv6_ras;
- uint32_t mtu;
- uint32_t metadata_size;
- uint32_t mempool_direct_id;
- uint32_t mempool_indirect_id;
-};
-
-struct app_pktq_kni_params {
- char *name;
- uint32_t parsed;
-
- uint32_t socket_id;
- uint32_t core_id;
- uint32_t hyper_th_id;
- uint32_t force_bind;
-
- uint32_t mempool_id; /* Position in the app->mempool_params */
- uint32_t burst_read;
- uint32_t burst_write;
- uint32_t dropless;
- uint64_t n_retries;
-};
-
-#ifndef APP_FILE_NAME_SIZE
-#define APP_FILE_NAME_SIZE 256
-#endif
-
-#ifndef APP_MAX_SCHED_SUBPORTS
-#define APP_MAX_SCHED_SUBPORTS 8
-#endif
-
-#ifndef APP_MAX_SCHED_PIPES
-#define APP_MAX_SCHED_PIPES 4096
-#endif
-
-struct app_pktq_tm_params {
- char *name;
- uint32_t parsed;
- const char *file_name;
- struct rte_sched_port_params sched_port_params;
- struct rte_sched_subport_params
- sched_subport_params[APP_MAX_SCHED_SUBPORTS];
- struct rte_sched_pipe_params
- sched_pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT];
- int sched_pipe_to_profile[APP_MAX_SCHED_SUBPORTS * APP_MAX_SCHED_PIPES];
- uint32_t burst_read;
- uint32_t burst_write;
-};
-
-struct app_pktq_tap_params {
- char *name;
- uint32_t parsed;
- uint32_t burst_read;
- uint32_t burst_write;
- uint32_t dropless;
- uint64_t n_retries;
- uint32_t mempool_id; /* Position in the app->mempool_params */
-};
-
-struct app_pktq_source_params {
- char *name;
- uint32_t parsed;
- uint32_t mempool_id; /* Position in the app->mempool_params array */
- uint32_t burst;
- const char *file_name; /* Full path of PCAP file to be copied to mbufs */
- uint32_t n_bytes_per_pkt;
-};
-
-struct app_pktq_sink_params {
- char *name;
- uint8_t parsed;
- const char *file_name; /* Full path of PCAP file to be copied to mbufs */
- uint32_t n_pkts_to_dump;
-};
-
-struct app_msgq_params {
- char *name;
- uint32_t parsed;
- uint32_t size;
- uint32_t cpu_socket_id;
-};
-
-enum app_pktq_in_type {
- APP_PKTQ_IN_HWQ,
- APP_PKTQ_IN_SWQ,
- APP_PKTQ_IN_TM,
- APP_PKTQ_IN_TAP,
- APP_PKTQ_IN_KNI,
- APP_PKTQ_IN_SOURCE,
-};
-
-struct app_pktq_in_params {
- enum app_pktq_in_type type;
- uint32_t id; /* Position in the appropriate app array */
-};
-
-enum app_pktq_out_type {
- APP_PKTQ_OUT_HWQ,
- APP_PKTQ_OUT_SWQ,
- APP_PKTQ_OUT_TM,
- APP_PKTQ_OUT_TAP,
- APP_PKTQ_OUT_KNI,
- APP_PKTQ_OUT_SINK,
-};
-
-struct app_pktq_out_params {
- enum app_pktq_out_type type;
- uint32_t id; /* Position in the appropriate app array */
-};
-
-#define APP_PIPELINE_TYPE_SIZE PIPELINE_TYPE_SIZE
-
-#define APP_MAX_PIPELINE_PKTQ_IN PIPELINE_MAX_PORT_IN
-#define APP_MAX_PIPELINE_PKTQ_OUT PIPELINE_MAX_PORT_OUT
-#define APP_MAX_PIPELINE_MSGQ_IN PIPELINE_MAX_MSGQ_IN
-#define APP_MAX_PIPELINE_MSGQ_OUT PIPELINE_MAX_MSGQ_OUT
-
-#define APP_MAX_PIPELINE_ARGS PIPELINE_MAX_ARGS
-
-struct app_pipeline_params {
- char *name;
- uint8_t parsed;
-
- char type[APP_PIPELINE_TYPE_SIZE];
-
- uint32_t socket_id;
- uint32_t core_id;
- uint32_t hyper_th_id;
-
- struct app_pktq_in_params pktq_in[APP_MAX_PIPELINE_PKTQ_IN];
- struct app_pktq_out_params pktq_out[APP_MAX_PIPELINE_PKTQ_OUT];
- uint32_t msgq_in[APP_MAX_PIPELINE_MSGQ_IN];
- uint32_t msgq_out[APP_MAX_PIPELINE_MSGQ_OUT];
-
- uint32_t n_pktq_in;
- uint32_t n_pktq_out;
- uint32_t n_msgq_in;
- uint32_t n_msgq_out;
-
- uint32_t timer_period;
-
- char *args_name[APP_MAX_PIPELINE_ARGS];
- char *args_value[APP_MAX_PIPELINE_ARGS];
- uint32_t n_args;
-};
-
-struct app_params;
-
-typedef void (*app_link_op)(struct app_params *app,
- uint32_t link_id,
- uint32_t up,
- void *arg);
-
-#ifndef APP_MAX_PIPELINES
-#define APP_MAX_PIPELINES 64
-#endif
-
-struct app_link_data {
- app_link_op f_link[APP_MAX_PIPELINES];
- void *arg[APP_MAX_PIPELINES];
-};
-
-struct app_pipeline_data {
- void *be;
- void *fe;
- struct pipeline_type *ptype;
- uint64_t timer_period;
- uint32_t enabled;
-};
-
-struct app_thread_pipeline_data {
- uint32_t pipeline_id;
- void *be;
- pipeline_be_op_run f_run;
- pipeline_be_op_timer f_timer;
- uint64_t timer_period;
- uint64_t deadline;
-};
-
-#ifndef APP_MAX_THREAD_PIPELINES
-#define APP_MAX_THREAD_PIPELINES 64
-#endif
-
-#ifndef APP_THREAD_TIMER_PERIOD
-#define APP_THREAD_TIMER_PERIOD 1
-#endif
-
-struct app_thread_data {
- struct app_thread_pipeline_data regular[APP_MAX_THREAD_PIPELINES];
- struct app_thread_pipeline_data custom[APP_MAX_THREAD_PIPELINES];
-
- uint32_t n_regular;
- uint32_t n_custom;
-
- uint64_t timer_period;
- uint64_t thread_req_deadline;
-
- uint64_t deadline;
-
- struct rte_ring *msgq_in;
- struct rte_ring *msgq_out;
-
- uint64_t headroom_time;
- uint64_t headroom_cycles;
- double headroom_ratio;
-} __rte_cache_aligned;
-
-#ifndef APP_MAX_LINKS
-#define APP_MAX_LINKS 16
-#endif
-
-struct app_eal_params {
- /* Map lcore set to physical cpu set */
- char *coremap;
-
- /* Core ID that is used as master */
- uint32_t master_lcore_present;
- uint32_t master_lcore;
-
- /* Number of memory channels */
- uint32_t channels_present;
- uint32_t channels;
-
- /* Memory to allocate (see also --socket-mem) */
- uint32_t memory_present;
- uint32_t memory;
-
- /* Force number of memory ranks (don't detect) */
- uint32_t ranks_present;
- uint32_t ranks;
-
- /* Add a PCI device in black list. */
- char *pci_blacklist[APP_MAX_LINKS];
-
- /* Add a PCI device in white list. */
- char *pci_whitelist[APP_MAX_LINKS];
-
- /* Add a virtual device. */
- char *vdev[APP_MAX_LINKS];
-
- /* Use VMware TSC map instead of native RDTSC */
- uint32_t vmware_tsc_map_present;
- int vmware_tsc_map;
-
- /* Type of this process (primary|secondary|auto) */
- char *proc_type;
-
- /* Set syslog facility */
- char *syslog;
-
- /* Set default log level */
- uint32_t log_level_present;
- uint32_t log_level;
-
- /* Display version information on startup */
- uint32_t version_present;
- int version;
-
- /* This help */
- uint32_t help_present;
- int help;
-
- /* Use malloc instead of hugetlbfs */
- uint32_t no_huge_present;
- int no_huge;
-
- /* Disable PCI */
- uint32_t no_pci_present;
- int no_pci;
-
- /* Disable HPET */
- uint32_t no_hpet_present;
- int no_hpet;
-
- /* No shared config (mmap'd files) */
- uint32_t no_shconf_present;
- int no_shconf;
-
- /* Add driver */
- char *add_driver;
-
- /* Memory to allocate on sockets (comma separated values)*/
- char *socket_mem;
-
- /* Directory where hugetlbfs is mounted */
- char *huge_dir;
-
- /* Prefix for hugepage filenames */
- char *file_prefix;
-
- /* Base virtual address */
- char *base_virtaddr;
-
- /* Create /dev/uioX (usually done by hotplug) */
- uint32_t create_uio_dev_present;
- int create_uio_dev;
-
- /* Interrupt mode for VFIO (legacy|msi|msix) */
- char *vfio_intr;
-
- uint32_t parsed;
-};
-
-#ifndef APP_APPNAME_SIZE
-#define APP_APPNAME_SIZE 256
-#endif
-
-#ifndef APP_MAX_MEMPOOLS
-#define APP_MAX_MEMPOOLS 8
-#endif
-
-#define APP_MAX_HWQ_IN (APP_MAX_LINKS * APP_LINK_MAX_HWQ_IN)
-
-#define APP_MAX_HWQ_OUT (APP_MAX_LINKS * APP_LINK_MAX_HWQ_OUT)
-
-#ifndef APP_MAX_PKTQ_SWQ
-#define APP_MAX_PKTQ_SWQ 256
-#endif
-
-#define APP_MAX_PKTQ_TM APP_MAX_LINKS
-
-#ifndef APP_MAX_PKTQ_TAP
-#define APP_MAX_PKTQ_TAP APP_MAX_LINKS
-#endif
-
-#define APP_MAX_PKTQ_KNI APP_MAX_LINKS
-
-#ifndef APP_MAX_PKTQ_SOURCE
-#define APP_MAX_PKTQ_SOURCE 64
-#endif
-
-#ifndef APP_MAX_PKTQ_SINK
-#define APP_MAX_PKTQ_SINK 64
-#endif
-
-#ifndef APP_MAX_MSGQ
-#define APP_MAX_MSGQ 256
-#endif
-
-#ifndef APP_EAL_ARGC
-#define APP_EAL_ARGC 64
-#endif
-
-#ifndef APP_MAX_PIPELINE_TYPES
-#define APP_MAX_PIPELINE_TYPES 64
-#endif
-
-#ifndef APP_MAX_THREADS
-#define APP_MAX_THREADS RTE_MAX_LCORE
-#endif
-
-#ifndef APP_MAX_CMDS
-#define APP_MAX_CMDS 64
-#endif
-
-#ifndef APP_THREAD_HEADROOM_STATS_COLLECT
-#define APP_THREAD_HEADROOM_STATS_COLLECT 1
-#endif
-
-#define APP_CORE_MASK_SIZE \
- (RTE_MAX_LCORE / 64 + ((RTE_MAX_LCORE % 64) ? 1 : 0))
-
-struct app_params {
- /* Config */
- char app_name[APP_APPNAME_SIZE];
- const char *config_file;
- const char *script_file;
- const char *parser_file;
- const char *output_file;
- const char *preproc;
- const char *preproc_args;
- uint64_t port_mask;
- uint32_t log_level;
-
- struct app_eal_params eal_params;
- struct app_mempool_params mempool_params[APP_MAX_MEMPOOLS];
- struct app_link_params link_params[APP_MAX_LINKS];
- struct app_pktq_hwq_in_params hwq_in_params[APP_MAX_HWQ_IN];
- struct app_pktq_hwq_out_params hwq_out_params[APP_MAX_HWQ_OUT];
- struct app_pktq_swq_params swq_params[APP_MAX_PKTQ_SWQ];
- struct app_pktq_tm_params tm_params[APP_MAX_PKTQ_TM];
- struct app_pktq_tap_params tap_params[APP_MAX_PKTQ_TAP];
- struct app_pktq_kni_params kni_params[APP_MAX_PKTQ_KNI];
- struct app_pktq_source_params source_params[APP_MAX_PKTQ_SOURCE];
- struct app_pktq_sink_params sink_params[APP_MAX_PKTQ_SINK];
- struct app_msgq_params msgq_params[APP_MAX_MSGQ];
- struct app_pipeline_params pipeline_params[APP_MAX_PIPELINES];
-
- uint32_t n_mempools;
- uint32_t n_links;
- uint32_t n_pktq_hwq_in;
- uint32_t n_pktq_hwq_out;
- uint32_t n_pktq_swq;
- uint32_t n_pktq_tm;
- uint32_t n_pktq_tap;
- uint32_t n_pktq_kni;
- uint32_t n_pktq_source;
- uint32_t n_pktq_sink;
- uint32_t n_msgq;
- uint32_t n_pipelines;
-
- /* Init */
- char *eal_argv[1 + APP_EAL_ARGC];
- struct cpu_core_map *core_map;
- uint64_t core_mask[APP_CORE_MASK_SIZE];
- struct rte_mempool *mempool[APP_MAX_MEMPOOLS];
- struct app_link_data link_data[APP_MAX_LINKS];
- struct rte_ring *swq[APP_MAX_PKTQ_SWQ];
- struct rte_sched_port *tm[APP_MAX_PKTQ_TM];
- int tap[APP_MAX_PKTQ_TAP];
-#ifdef RTE_LIBRTE_KNI
- struct rte_kni *kni[APP_MAX_PKTQ_KNI];
-#endif /* RTE_LIBRTE_KNI */
- struct rte_ring *msgq[APP_MAX_MSGQ];
- struct pipeline_type pipeline_type[APP_MAX_PIPELINE_TYPES];
- struct app_pipeline_data pipeline_data[APP_MAX_PIPELINES];
- struct app_thread_data thread_data[APP_MAX_THREADS];
- cmdline_parse_ctx_t cmds[APP_MAX_CMDS + 1];
-
- int eal_argc;
- uint32_t n_pipeline_types;
- uint32_t n_cmds;
-};
-
-#define APP_PARAM_VALID(obj) ((obj)->name != NULL)
-
-#define APP_PARAM_COUNT(obj_array, n_objs) \
-{ \
- size_t i; \
- \
- n_objs = 0; \
- for (i = 0; i < RTE_DIM(obj_array); i++) \
- if (APP_PARAM_VALID(&((obj_array)[i]))) \
- n_objs++; \
-}
-
-#define APP_PARAM_FIND(obj_array, key) \
-({ \
- ssize_t obj_idx; \
- const ssize_t obj_count = RTE_DIM(obj_array); \
- \
- for (obj_idx = 0; obj_idx < obj_count; obj_idx++) { \
- if (!APP_PARAM_VALID(&((obj_array)[obj_idx]))) \
- continue; \
- \
- if (strcmp(key, (obj_array)[obj_idx].name) == 0) \
- break; \
- } \
- obj_idx < obj_count ? obj_idx : -ENOENT; \
-})
-
-#define APP_PARAM_FIND_BY_ID(obj_array, prefix, id, obj) \
-do { \
- char name[APP_PARAM_NAME_SIZE]; \
- ssize_t pos; \
- \
- sprintf(name, prefix "%" PRIu32, id); \
- pos = APP_PARAM_FIND(obj_array, name); \
- obj = (pos < 0) ? NULL : &((obj_array)[pos]); \
-} while (0)
-
-#define APP_PARAM_GET_ID(obj, prefix, id) \
-do \
- sscanf(obj->name, prefix "%" SCNu32, &id); \
-while (0) \
-
-#define APP_CHECK(exp, fmt, ...) \
-do { \
- if (!(exp)) { \
- fprintf(stderr, fmt "\n", ## __VA_ARGS__); \
- abort(); \
- } \
-} while (0)
-
-enum app_log_level {
- APP_LOG_LEVEL_HIGH = 1,
- APP_LOG_LEVEL_LOW,
- APP_LOG_LEVELS
-};
-
-#define APP_LOG(app, level, fmt, ...) \
-do { \
- if (app->log_level >= APP_LOG_LEVEL_ ## level) \
- fprintf(stdout, "[APP] " fmt "\n", ## __VA_ARGS__); \
-} while (0)
-
-static inline uint32_t
-app_link_get_n_rxq(struct app_params *app, struct app_link_params *link)
-{
- uint32_t n_rxq = 0, link_id, i;
- uint32_t n_pktq_hwq_in = RTE_MIN(app->n_pktq_hwq_in,
- RTE_DIM(app->hwq_in_params));
-
- APP_PARAM_GET_ID(link, "LINK", link_id);
-
- for (i = 0; i < n_pktq_hwq_in; i++) {
- struct app_pktq_hwq_in_params *p = &app->hwq_in_params[i];
- uint32_t rxq_link_id, rxq_queue_id;
-
- sscanf(p->name, "RXQ%" SCNu32 ".%" SCNu32,
- &rxq_link_id, &rxq_queue_id);
- if (rxq_link_id == link_id)
- n_rxq++;
- }
-
- return n_rxq;
-}
-
-static inline uint32_t
-app_link_get_n_txq(struct app_params *app, struct app_link_params *link)
-{
- uint32_t n_txq = 0, link_id, i;
- uint32_t n_pktq_hwq_out = RTE_MIN(app->n_pktq_hwq_out,
- RTE_DIM(app->hwq_out_params));
-
- APP_PARAM_GET_ID(link, "LINK", link_id);
-
- for (i = 0; i < n_pktq_hwq_out; i++) {
- struct app_pktq_hwq_out_params *p = &app->hwq_out_params[i];
- uint32_t txq_link_id, txq_queue_id;
-
- sscanf(p->name, "TXQ%" SCNu32 ".%" SCNu32,
- &txq_link_id, &txq_queue_id);
- if (txq_link_id == link_id)
- n_txq++;
- }
-
- return n_txq;
-}
-
-static inline uint32_t
-app_rxq_get_readers(struct app_params *app, struct app_pktq_hwq_in_params *rxq)
-{
- uint32_t pos = rxq - app->hwq_in_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_HWQ) &&
- (pktq->id == pos))
- n_readers++;
- }
- }
-
- return n_readers;
-}
-
-static inline uint32_t
-app_swq_get_readers(struct app_params *app, struct app_pktq_swq_params *swq)
-{
- uint32_t pos = swq - app->swq_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_SWQ) &&
- (pktq->id == pos))
- n_readers++;
- }
- }
-
- return n_readers;
-}
-
-static inline struct app_pipeline_params *
-app_swq_get_reader(struct app_params *app,
- struct app_pktq_swq_params *swq,
- uint32_t *pktq_in_id)
-{
- struct app_pipeline_params *reader = NULL;
- uint32_t pos = swq - app->swq_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_SWQ) &&
- (pktq->id == pos)) {
- n_readers++;
- reader = p;
- id = j;
- }
- }
- }
-
- if (n_readers != 1)
- return NULL;
-
- *pktq_in_id = id;
- return reader;
-}
-
-static inline uint32_t
-app_tm_get_readers(struct app_params *app, struct app_pktq_tm_params *tm)
-{
- uint32_t pos = tm - app->tm_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_TM) &&
- (pktq->id == pos))
- n_readers++;
- }
- }
-
- return n_readers;
-}
-
-static inline struct app_pipeline_params *
-app_tm_get_reader(struct app_params *app,
- struct app_pktq_tm_params *tm,
- uint32_t *pktq_in_id)
-{
- struct app_pipeline_params *reader = NULL;
- uint32_t pos = tm - app->tm_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_TM) &&
- (pktq->id == pos)) {
- n_readers++;
- reader = p;
- id = j;
- }
- }
- }
-
- if (n_readers != 1)
- return NULL;
-
- *pktq_in_id = id;
- return reader;
-}
-
-static inline uint32_t
-app_tap_get_readers(struct app_params *app, struct app_pktq_tap_params *tap)
-{
- uint32_t pos = tap - app->tap_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_TAP) &&
- (pktq->id == pos))
- n_readers++;
- }
- }
-
- return n_readers;
-}
-
-static inline struct app_pipeline_params *
-app_tap_get_reader(struct app_params *app,
- struct app_pktq_tap_params *tap,
- uint32_t *pktq_in_id)
-{
- struct app_pipeline_params *reader = NULL;
- uint32_t pos = tap - app->tap_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_TAP) &&
- (pktq->id == pos)) {
- n_readers++;
- reader = p;
- id = j;
- }
- }
- }
-
- if (n_readers != 1)
- return NULL;
-
- *pktq_in_id = id;
- return reader;
-}
-
-static inline uint32_t
-app_kni_get_readers(struct app_params *app, struct app_pktq_kni_params *kni)
-{
- uint32_t pos = kni - app->kni_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_KNI) &&
- (pktq->id == pos))
- n_readers++;
- }
- }
-
- return n_readers;
-}
-
-static inline struct app_pipeline_params *
-app_kni_get_reader(struct app_params *app,
- struct app_pktq_kni_params *kni,
- uint32_t *pktq_in_id)
-{
- struct app_pipeline_params *reader = NULL;
- uint32_t pos = kni - app->kni_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_KNI) &&
- (pktq->id == pos)) {
- n_readers++;
- reader = p;
- id = j;
- }
- }
- }
-
- if (n_readers != 1)
- return NULL;
-
- *pktq_in_id = id;
- return reader;
-}
-
-static inline uint32_t
-app_source_get_readers(struct app_params *app,
-struct app_pktq_source_params *source)
-{
- uint32_t pos = source - app->source_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_in = RTE_MIN(p->n_pktq_in, RTE_DIM(p->pktq_in));
- uint32_t j;
-
- for (j = 0; j < n_pktq_in; j++) {
- struct app_pktq_in_params *pktq = &p->pktq_in[j];
-
- if ((pktq->type == APP_PKTQ_IN_SOURCE) &&
- (pktq->id == pos))
- n_readers++;
- }
- }
-
- return n_readers;
-}
-
-static inline uint32_t
-app_msgq_get_readers(struct app_params *app, struct app_msgq_params *msgq)
-{
- uint32_t pos = msgq - app->msgq_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_readers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_msgq_in = RTE_MIN(p->n_msgq_in, RTE_DIM(p->msgq_in));
- uint32_t j;
-
- for (j = 0; j < n_msgq_in; j++)
- if (p->msgq_in[j] == pos)
- n_readers++;
- }
-
- return n_readers;
-}
-
-static inline uint32_t
-app_txq_get_writers(struct app_params *app, struct app_pktq_hwq_out_params *txq)
-{
- uint32_t pos = txq - app->hwq_out_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_HWQ) &&
- (pktq->id == pos))
- n_writers++;
- }
- }
-
- return n_writers;
-}
-
-static inline uint32_t
-app_swq_get_writers(struct app_params *app, struct app_pktq_swq_params *swq)
-{
- uint32_t pos = swq - app->swq_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_SWQ) &&
- (pktq->id == pos))
- n_writers++;
- }
- }
-
- return n_writers;
-}
-
-static inline struct app_pipeline_params *
-app_swq_get_writer(struct app_params *app,
- struct app_pktq_swq_params *swq,
- uint32_t *pktq_out_id)
-{
- struct app_pipeline_params *writer = NULL;
- uint32_t pos = swq - app->swq_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_SWQ) &&
- (pktq->id == pos)) {
- n_writers++;
- writer = p;
- id = j;
- }
- }
- }
-
- if (n_writers != 1)
- return NULL;
-
- *pktq_out_id = id;
- return writer;
-}
-
-static inline uint32_t
-app_tm_get_writers(struct app_params *app, struct app_pktq_tm_params *tm)
-{
- uint32_t pos = tm - app->tm_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_TM) &&
- (pktq->id == pos))
- n_writers++;
- }
- }
-
- return n_writers;
-}
-
-static inline struct app_pipeline_params *
-app_tm_get_writer(struct app_params *app,
- struct app_pktq_tm_params *tm,
- uint32_t *pktq_out_id)
-{
- struct app_pipeline_params *writer = NULL;
- uint32_t pos = tm - app->tm_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_TM) &&
- (pktq->id == pos)) {
- n_writers++;
- writer = p;
- id = j;
- }
- }
- }
-
- if (n_writers != 1)
- return NULL;
-
- *pktq_out_id = id;
- return writer;
-}
-
-static inline uint32_t
-app_tap_get_writers(struct app_params *app, struct app_pktq_tap_params *tap)
-{
- uint32_t pos = tap - app->tap_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_TAP) &&
- (pktq->id == pos))
- n_writers++;
- }
- }
-
- return n_writers;
-}
-
-static inline struct app_pipeline_params *
-app_tap_get_writer(struct app_params *app,
- struct app_pktq_tap_params *tap,
- uint32_t *pktq_out_id)
-{
- struct app_pipeline_params *writer = NULL;
- uint32_t pos = tap - app->tap_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_TAP) &&
- (pktq->id == pos)) {
- n_writers++;
- writer = p;
- id = j;
- }
- }
- }
-
- if (n_writers != 1)
- return NULL;
-
- *pktq_out_id = id;
- return writer;
-}
-
-static inline uint32_t
-app_kni_get_writers(struct app_params *app, struct app_pktq_kni_params *kni)
-{
- uint32_t pos = kni - app->kni_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_KNI) &&
- (pktq->id == pos))
- n_writers++;
- }
- }
-
- return n_writers;
-}
-
-static inline struct app_pipeline_params *
-app_kni_get_writer(struct app_params *app,
- struct app_pktq_kni_params *kni,
- uint32_t *pktq_out_id)
-{
- struct app_pipeline_params *writer = NULL;
- uint32_t pos = kni - app->kni_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, id = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_KNI) &&
- (pktq->id == pos)) {
- n_writers++;
- writer = p;
- id = j;
- }
- }
- }
-
- if (n_writers != 1)
- return NULL;
-
- *pktq_out_id = id;
- return writer;
-}
-
-static inline uint32_t
-app_sink_get_writers(struct app_params *app, struct app_pktq_sink_params *sink)
-{
- uint32_t pos = sink - app->sink_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_pktq_out = RTE_MIN(p->n_pktq_out,
- RTE_DIM(p->pktq_out));
- uint32_t j;
-
- for (j = 0; j < n_pktq_out; j++) {
- struct app_pktq_out_params *pktq = &p->pktq_out[j];
-
- if ((pktq->type == APP_PKTQ_OUT_SINK) &&
- (pktq->id == pos))
- n_writers++;
- }
- }
-
- return n_writers;
-}
-
-static inline uint32_t
-app_msgq_get_writers(struct app_params *app, struct app_msgq_params *msgq)
-{
- uint32_t pos = msgq - app->msgq_params;
- uint32_t n_pipelines = RTE_MIN(app->n_pipelines,
- RTE_DIM(app->pipeline_params));
- uint32_t n_writers = 0, i;
-
- for (i = 0; i < n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- uint32_t n_msgq_out = RTE_MIN(p->n_msgq_out,
- RTE_DIM(p->msgq_out));
- uint32_t j;
-
- for (j = 0; j < n_msgq_out; j++)
- if (p->msgq_out[j] == pos)
- n_writers++;
- }
-
- return n_writers;
-}
-
-static inline struct app_link_params *
-app_get_link_for_rxq(struct app_params *app, struct app_pktq_hwq_in_params *p)
-{
- char link_name[APP_PARAM_NAME_SIZE];
- ssize_t link_param_idx;
- uint32_t rxq_link_id, rxq_queue_id;
-
- sscanf(p->name, "RXQ%" SCNu32 ".%" SCNu32,
- &rxq_link_id, &rxq_queue_id);
- sprintf(link_name, "LINK%" PRIu32, rxq_link_id);
- link_param_idx = APP_PARAM_FIND(app->link_params, link_name);
- APP_CHECK((link_param_idx >= 0),
- "Cannot find %s for %s", link_name, p->name);
-
- return &app->link_params[link_param_idx];
-}
-
-static inline struct app_link_params *
-app_get_link_for_txq(struct app_params *app, struct app_pktq_hwq_out_params *p)
-{
- char link_name[APP_PARAM_NAME_SIZE];
- ssize_t link_param_idx;
- uint32_t txq_link_id, txq_queue_id;
-
- sscanf(p->name, "TXQ%" SCNu32 ".%" SCNu32,
- &txq_link_id, &txq_queue_id);
- sprintf(link_name, "LINK%" PRIu32, txq_link_id);
- link_param_idx = APP_PARAM_FIND(app->link_params, link_name);
- APP_CHECK((link_param_idx >= 0),
- "Cannot find %s for %s", link_name, p->name);
-
- return &app->link_params[link_param_idx];
-}
-
-static inline struct app_link_params *
-app_get_link_for_tm(struct app_params *app, struct app_pktq_tm_params *p_tm)
-{
- char link_name[APP_PARAM_NAME_SIZE];
- uint32_t link_id;
- ssize_t link_param_idx;
-
- sscanf(p_tm->name, "TM%" PRIu32, &link_id);
- sprintf(link_name, "LINK%" PRIu32, link_id);
- link_param_idx = APP_PARAM_FIND(app->link_params, link_name);
- APP_CHECK((link_param_idx >= 0),
- "Cannot find %s for %s", link_name, p_tm->name);
-
- return &app->link_params[link_param_idx];
-}
-
-static inline struct app_link_params *
-app_get_link_for_kni(struct app_params *app, struct app_pktq_kni_params *p_kni)
-{
- char link_name[APP_PARAM_NAME_SIZE];
- uint32_t link_id;
- ssize_t link_param_idx;
-
- sscanf(p_kni->name, "KNI%" PRIu32, &link_id);
- sprintf(link_name, "LINK%" PRIu32, link_id);
- link_param_idx = APP_PARAM_FIND(app->link_params, link_name);
- APP_CHECK((link_param_idx >= 0),
- "Cannot find %s for %s", link_name, p_kni->name);
-
- return &app->link_params[link_param_idx];
-}
-
-static inline uint32_t
-app_core_is_enabled(struct app_params *app, uint32_t lcore_id)
-{
- return(app->core_mask[lcore_id / 64] &
- (1LLU << (lcore_id % 64)));
-}
-
-static inline void
-app_core_enable_in_core_mask(struct app_params *app, int lcore_id)
-{
- app->core_mask[lcore_id / 64] |= 1LLU << (lcore_id % 64);
-
-}
-
-static inline void
-app_core_build_core_mask_string(struct app_params *app, char *mask_buffer)
-{
- int i;
-
- mask_buffer[0] = '\0';
- for (i = (int)RTE_DIM(app->core_mask); i > 0; i--) {
- /* For Hex representation of bits in uint64_t */
- char buffer[(64 / 8) * 2 + 1];
- memset(buffer, 0, sizeof(buffer));
- snprintf(buffer, sizeof(buffer), "%016" PRIx64,
- app->core_mask[i-1]);
- strcat(mask_buffer, buffer);
- }
-}
-
-void app_pipeline_params_get(struct app_params *app,
- struct app_pipeline_params *p_in,
- struct pipeline_params *p_out);
-
-int app_config_init(struct app_params *app);
-
-int app_config_args(struct app_params *app,
- int argc, char **argv);
-
-int app_config_preproc(struct app_params *app);
-
-int app_config_parse(struct app_params *app,
- const char *file_name);
-
-int app_config_parse_tm(struct app_params *app);
-
-void app_config_save(struct app_params *app,
- const char *file_name);
-
-int app_config_check(struct app_params *app);
-
-int app_init(struct app_params *app);
-
-int app_post_init(struct app_params *app);
-
-int app_thread(void *arg);
-
-int app_pipeline_type_register(struct app_params *app,
- struct pipeline_type *ptype);
-
-struct pipeline_type *app_pipeline_type_find(struct app_params *app,
- char *name);
-
-void app_link_up_internal(struct app_params *app,
- struct app_link_params *cp);
-
-void app_link_down_internal(struct app_params *app,
- struct app_link_params *cp);
-
-#endif
diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c
new file mode 100644
index 00000000..102a1d6b
--- /dev/null
+++ b/examples/ip_pipeline/cli.c
@@ -0,0 +1,5240 @@
+/* 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 "kni.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 ether_addr mac_addr;
+ struct rte_eth_link eth_link;
+ uint16_t mtu;
+
+ memset(&stats, 0, sizeof(stats));
+ rte_eth_stats_get(link->port_id, &stats);
+
+ rte_eth_macaddr_get(link->port_id, &mac_addr);
+ rte_eth_link_get(link->port_id, &eth_link);
+ rte_eth_dev_get_mtu(link->port_id, &mtu);
+
+ snprintf(out, out_size,
+ "\n"
+ "%s: flags=<%s> mtu %u\n"
+ "\tether %02X:%02X:%02X:%02X:%02X:%02X rxqueues %u txqueues %u\n"
+ "\tport# %u speed %u Mbps\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,
+ mac_addr.addr_bytes[0], mac_addr.addr_bytes[1],
+ mac_addr.addr_bytes[2], mac_addr.addr_bytes[3],
+ mac_addr.addr_bytes[4], mac_addr.addr_bytes[5],
+ link->n_rxq,
+ link->n_txq,
+ link->port_id,
+ 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>\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_params p;
+ int status, i;
+
+ if (n_tokens != 10) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
+ return;
+ }
+
+ if (parser_read_uint32(&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_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
+ return;
+ }
+
+ if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
+ return;
+ }
+
+ status = tmgr_subport_profile_add(&p);
+ 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>\n"
+" <tc_period>\n"
+" <tc_ov_weight>\n"
+" <wrr_weight0..15>\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 != 27) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ if (parser_read_uint32(&p.tb_rate, tokens[3]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "tb_rate");
+ return;
+ }
+
+ if (parser_read_uint32(&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_uint32(&p.tc_rate[i], tokens[5 + i]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "tc_rate");
+ return;
+ }
+
+ if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "tc_period");
+ return;
+ }
+
+#ifdef RTE_SCHED_SUBPORT_TC_OV
+ if (parser_read_uint8(&p.tc_ov_weight, tokens[10]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight");
+ return;
+ }
+#endif
+
+ for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++)
+ if (parser_read_uint8(&p.wrr_weights[i], tokens[11 + 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"
+" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>\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;
+ int i;
+
+ if (n_tokens != 19) {
+ 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_uint32(&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, "pps");
+ 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], "qsize") != 0) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "qsize");
+ return;
+ }
+
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
+ if (parser_read_uint16(&p.qsize[i], tokens[9 + i]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "qsize");
+ return;
+ }
+
+ if (strcmp(tokens[13], "fo") != 0) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo");
+ return;
+ }
+
+ if (parser_read_uint32(&p.frame_overhead, tokens[14]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead");
+ return;
+ }
+
+ if (strcmp(tokens[15], "mtu") != 0) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu");
+ return;
+ }
+
+ if (parser_read_uint32(&p.mtu, tokens[16]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "mtu");
+ return;
+ }
+
+ if (strcmp(tokens[17], "cpu") != 0) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu");
+ return;
+ }
+
+ if (parser_read_uint32(&p.cpu_id, tokens[18]) != 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_kni_help[] =
+"kni <kni_name>\n"
+" link <link_name>\n"
+" mempool <mempool_name>\n"
+" [thread <thread_id>]\n";
+
+static void
+cmd_kni(char **tokens,
+ uint32_t n_tokens,
+ char *out,
+ size_t out_size)
+{
+ struct kni_params p;
+ char *name;
+ struct kni *kni;
+
+ memset(&p, 0, sizeof(p));
+ if ((n_tokens != 6) && (n_tokens != 8)) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+ return;
+ }
+
+ name = tokens[1];
+
+ if (strcmp(tokens[2], "link") != 0) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "link");
+ return;
+ }
+
+ p.link_name = tokens[3];
+
+ if (strcmp(tokens[4], "mempool") != 0) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mempool");
+ return;
+ }
+
+ p.mempool_name = tokens[5];
+
+ if (n_tokens == 8) {
+ if (strcmp(tokens[6], "thread") != 0) {
+ snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread");
+ return;
+ }
+
+ if (parser_read_uint32(&p.thread_id, tokens[7]) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "thread_id");
+ return;
+ }
+
+ p.force_bind = 1;
+ } else
+ p.force_bind = 0;
+
+ kni = kni_create(name, &p);
+ if (kni == 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]\n"
+" [nat src | dst\n"
+" proto udp | tcp]\n"
+" [ttl drop | fwd\n"
+" stats none | pkts]\n"
+" [stats pkts | bytes | both]\n"
+" [time]\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)) {
+ 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 {
+ snprintf(out, out_size, MSG_ARG_MISMATCH, "encap");
+ return;
+ }
+
+ p.action_mask |= 1LLU << RTE_TABLE_ACTION_ENCAP;
+ t0 += 2;
+ } /* 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) {
+ 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"
+" | kni <kni_name>\n"
+" | source mempool <mempool_name> file <file_name> bpp <n_bytes_per_pkt>\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], "kni") == 0) {
+ if (n_tokens < t0 + 2) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH,
+ "pipeline port in kni");
+ return;
+ }
+
+ p.type = PORT_IN_KNI;
+
+ p.dev_name = tokens[t0 + 1];
+
+ t0 += 2;
+ } 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 {
+ 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"
+" | kni <kni_name>\n"
+" | sink [file <file_name> pkts <max_n_pkts>]\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], "kni") == 0) {
+ if (n_tokens != 8) {
+ snprintf(out, out_size, MSG_ARG_MISMATCH,
+ "pipeline port out kni");
+ return;
+ }
+
+ p.type = PORT_OUT_KNI;
+
+ 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 {
+ 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;
+} __attribute__((__packed__));
+
+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;
+} __attribute__((__packed__));
+
+struct pkt_key_ipv6_5tuple {
+ uint16_t payload_length;
+ uint8_t proto;
+ uint8_t hop_limit;
+ uint8_t sa[16];
+ uint8_t da[16];
+ uint16_t sp;
+ uint16_t dp;
+} __attribute__((__packed__));
+
+struct pkt_key_ipv4_addr {
+ uint32_t addr;
+} __attribute__((__packed__));
+
+struct pkt_key_ipv6_addr {
+ uint8_t addr[16];
+} __attribute__((__packed__));
+
+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 in6_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;
+ }
+ memcpy(m->match.acl.ipv6.sa, saddr.s6_addr, 16);
+
+ if (parse_ipv6_addr(tokens[7], &daddr) != 0) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "da");
+ return 0;
+ }
+ memcpy(m->match.acl.ipv6.da, daddr.s6_addr, 16);
+ } 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 in6_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;
+ }
+
+ memcpy(ipv6->sa, saddr.s6_addr, 16);
+ memcpy(ipv6->da, daddr.s6_addr, 16);
+ 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 in6_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;
+ }
+
+ memcpy(ipv6_addr->addr, addr.s6_addr, 16);
+
+ 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 in6_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;
+ }
+
+ memcpy(m->match.lpm.ipv6, addr.s6_addr, 16);
+ } 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>
+ * | 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]
+ *
+ * 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[e_RTE_METER_GREEN]) ||
+ strcmp(tokens[5], "y") ||
+ parse_policer_action(tokens[6], &mtr->policer[e_RTE_METER_YELLOW]) ||
+ strcmp(tokens[7], "r") ||
+ parse_policer_action(tokens[8], &mtr->policer[e_RTE_METER_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;
+ }
+
+ /* 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;
+ }
+
+ 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 in6_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;
+ memcpy(a->nat.addr.ipv6, addr.s6_addr, 16);
+ 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 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_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;
+ void *data;
+ 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, &data);
+ if (status) {
+ snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+ return;
+ }
+}
+
+
+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;
+ void *data;
+ 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,
+ &data);
+ 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_rules>\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_match *m,
+ struct table_rule_action *a,
+ 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_match *match;
+ struct table_rule_action *action;
+ void **data;
+ char *pipeline_name, *file_name;
+ uint32_t table_id, n_rules, n_rules_parsed, line_number;
+ 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, "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];
+
+ if ((parser_read_uint32(&n_rules, tokens[8]) != 0) ||
+ (n_rules == 0)) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "n_rules");
+ return;
+ }
+
+ /* Memory allocation. */
+ match = calloc(n_rules, sizeof(struct table_rule_match));
+ action = calloc(n_rules, sizeof(struct table_rule_action));
+ data = calloc(n_rules, sizeof(void *));
+ if ((match == NULL) || (action == NULL) || (data == NULL)) {
+ snprintf(out, out_size, MSG_OUT_OF_MEMORY);
+ free(data);
+ free(action);
+ free(match);
+ return;
+ }
+
+ /* Load rule file */
+ n_rules_parsed = n_rules;
+ status = cli_rule_file_process(file_name,
+ 1024,
+ match,
+ action,
+ &n_rules_parsed,
+ &line_number,
+ out,
+ out_size);
+ if (status) {
+ snprintf(out, out_size, MSG_FILE_ERR, file_name, line_number);
+ free(data);
+ free(action);
+ free(match);
+ return;
+ }
+ if (n_rules_parsed != n_rules) {
+ snprintf(out, out_size, MSG_FILE_NOT_ENOUGH, file_name);
+ free(data);
+ free(action);
+ free(match);
+ return;
+ }
+
+ /* Rule bulk add */
+ status = pipeline_table_rule_add_bulk(pipeline_name,
+ table_id,
+ match,
+ action,
+ data,
+ &n_rules);
+ if (status) {
+ snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+ free(data);
+ free(action);
+ free(match);
+ return;
+ }
+
+ /* Memory free */
+ free(data);
+ free(action);
+ free(match);
+}
+
+
+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 const char cmd_pipeline_table_rule_stats_read_help[] =
+"pipeline <pipeline_name> table <table_id> rule read stats [clear]\n";
+
+static void
+cmd_pipeline_table_rule_stats_read(char **tokens,
+ uint32_t n_tokens __rte_unused,
+ char *out,
+ size_t out_size)
+{
+ snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
+}
+
+
+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";
+
+static void
+cmd_pipeline_table_rule_meter_read(char **tokens,
+ uint32_t n_tokens __rte_unused,
+ char *out,
+ size_t out_size)
+{
+ snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
+}
+
+
+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_meter_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 = e_RTE_METER_GREEN;
+ break;
+
+ case 'y':
+ case 'Y':
+ color = e_RTE_METER_YELLOW;
+ break;
+
+ case 'r':
+ case 'R':
+ color = e_RTE_METER_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";
+
+static void
+cmd_pipeline_table_rule_ttl_read(char **tokens,
+ uint32_t n_tokens __rte_unused,
+ char *out,
+ size_t out_size)
+{
+ snprintf(out, out_size, MSG_CMD_UNIMPLEM, tokens[0]);
+}
+
+
+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"
+ "\tkni\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 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"
+ "\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], "kni") == 0) {
+ snprintf(out, out_size, "\n%s\n", cmd_kni_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 == 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 == 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], "kni") == 0) {
+ cmd_kni(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 >= 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 (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_match *m,
+ struct table_rule_action *a,
+ uint32_t *n_rules,
+ uint32_t *line_number,
+ char *out,
+ size_t out_size)
+{
+ FILE *f = NULL;
+ char *line = NULL;
+ uint32_t rule_id, line_id;
+ int status = 0;
+
+ /* Check input arguments */
+ if ((file_name == NULL) ||
+ (strlen(file_name) == 0) ||
+ (line_len_max == 0)) {
+ *line_number = 0;
+ return -EINVAL;
+ }
+
+ /* Memory allocation */
+ line = malloc(line_len_max + 1);
+ if (line == NULL) {
+ *line_number = 0;
+ return -ENOMEM;
+ }
+
+ /* Open file */
+ f = fopen(file_name, "r");
+ if (f == NULL) {
+ *line_number = 0;
+ free(line);
+ return -EIO;
+ }
+
+ /* Read file */
+ for (line_id = 1, rule_id = 0; rule_id < *n_rules; line_id++) {
+ char *tokens[CMD_MAX_TOKENS];
+ 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;
+ break;
+ }
+
+ /* Empty line. */
+ if (n_tokens == 0)
+ continue;
+ t0 = 0;
+
+ /* Rule match. */
+ n_tokens_parsed = parse_match(tokens + t0,
+ n_tokens - t0,
+ out,
+ out_size,
+ &m[rule_id]);
+ if (n_tokens_parsed == 0) {
+ status = -EINVAL;
+ break;
+ }
+ t0 += n_tokens_parsed;
+
+ /* Rule action. */
+ n_tokens_parsed = parse_table_action(tokens + t0,
+ n_tokens - t0,
+ out,
+ out_size,
+ &a[rule_id]);
+ if (n_tokens_parsed == 0) {
+ status = -EINVAL;
+ break;
+ }
+ t0 += n_tokens_parsed;
+
+ /* Line completed. */
+ if (t0 < n_tokens) {
+ status = -EINVAL;
+ break;
+ }
+
+ /* Increment rule count */
+ rule_id++;
+ }
+
+ /* Close file */
+ fclose(f);
+
+ /* Memory free */
+ free(line);
+
+ *n_rules = rule_id;
+ *line_number = line_id;
+ return status;
+}
diff --git a/examples/ip_pipeline/cli.h b/examples/ip_pipeline/cli.h
new file mode 100644
index 00000000..992e4c3a
--- /dev/null
+++ b/examples/ip_pipeline/cli.h
@@ -0,0 +1,18 @@
+/* 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
new file mode 100644
index 00000000..0886dfbe
--- /dev/null
+++ b/examples/ip_pipeline/common.h
@@ -0,0 +1,12 @@
+/* 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/config/action.cfg b/examples/ip_pipeline/config/action.cfg
deleted file mode 100644
index 994ae94a..00000000
--- a/examples/ip_pipeline/config/action.cfg
+++ /dev/null
@@ -1,68 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; ________________
-; RXQ0.0 --->| |---> TXQ0.0
-; | |
-; RXQ1.0 --->| |---> TXQ1.0
-; | Flow |
-; RXQ2.0 --->| Actions |---> TXQ2.0
-; | |
-; RXQ3.0 --->| |---> TXQ3.0
-; |________________|
-;
-;
-; 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
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = FLOW_ACTIONS
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0
-n_flows = 65536
-n_meters_per_flow = 4
-flow_id_offset = 286; ipdaddr
-ip_hdr_offset = 270
-color_offset = 128
diff --git a/examples/ip_pipeline/config/action.sh b/examples/ip_pipeline/config/action.sh
deleted file mode 100644
index 2986ae60..00000000
--- a/examples/ip_pipeline/config/action.sh
+++ /dev/null
@@ -1,119 +0,0 @@
-#
-# run ./config/action.sh
-#
-
-p 1 action flow 0 meter 0 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 0 policer 0 g G y Y r R
-p 1 action flow 0 meter 1 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 0 policer 1 g G y Y r R
-p 1 action flow 0 meter 2 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 0 policer 2 g G y Y r R
-p 1 action flow 0 meter 3 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 0 policer 3 g G y Y r R
-p 1 action flow 0 port 0
-
-p 1 action flow 1 meter 0 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 1 policer 0 g G y Y r R
-p 1 action flow 1 meter 1 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 1 policer 1 g G y Y r R
-p 1 action flow 1 meter 2 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 1 policer 2 g G y Y r R
-p 1 action flow 1 meter 3 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 1 policer 3 g G y Y r R
-p 1 action flow 1 port 1
-
-p 1 action flow 2 meter 0 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 2 policer 0 g G y Y r R
-p 1 action flow 2 meter 1 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 2 policer 1 g G y Y r R
-p 1 action flow 2 meter 2 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 2 policer 2 g G y Y r R
-p 1 action flow 2 meter 3 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 2 policer 3 g G y Y r R
-p 1 action flow 2 port 2
-
-p 1 action flow 3 meter 0 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 3 policer 0 g G y Y r R
-p 1 action flow 3 meter 1 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 3 policer 1 g G y Y r R
-p 1 action flow 3 meter 2 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 3 policer 2 g G y Y r R
-p 1 action flow 3 meter 3 trtcm 1250000000 1250000000 1000000 1000000
-p 1 action flow 3 policer 3 g G y Y r R
-p 1 action flow 3 port 3
-
-#p 1 action flow bulk ./config/action.txt
-
-#p 1 action flow ls
-
-p 1 action flow 0 stats
-p 1 action flow 1 stats
-p 1 action flow 2 stats
-p 1 action flow 3 stats
-
-p 1 action dscp 0 class 0 color G
-p 1 action dscp 1 class 1 color G
-p 1 action dscp 2 class 2 color G
-p 1 action dscp 3 class 3 color G
-p 1 action dscp 4 class 0 color G
-p 1 action dscp 5 class 1 color G
-p 1 action dscp 6 class 2 color G
-p 1 action dscp 7 class 3 color G
-p 1 action dscp 8 class 0 color G
-p 1 action dscp 9 class 1 color G
-p 1 action dscp 10 class 2 color G
-p 1 action dscp 11 class 3 color G
-p 1 action dscp 12 class 0 color G
-p 1 action dscp 13 class 1 color G
-p 1 action dscp 14 class 2 color G
-p 1 action dscp 15 class 3 color G
-p 1 action dscp 16 class 0 color G
-p 1 action dscp 17 class 1 color G
-p 1 action dscp 18 class 2 color G
-p 1 action dscp 19 class 3 color G
-p 1 action dscp 20 class 0 color G
-p 1 action dscp 21 class 1 color G
-p 1 action dscp 22 class 2 color G
-p 1 action dscp 23 class 3 color G
-p 1 action dscp 24 class 0 color G
-p 1 action dscp 25 class 1 color G
-p 1 action dscp 26 class 2 color G
-p 1 action dscp 27 class 3 color G
-p 1 action dscp 27 class 0 color G
-p 1 action dscp 29 class 1 color G
-p 1 action dscp 30 class 2 color G
-p 1 action dscp 31 class 3 color G
-p 1 action dscp 32 class 0 color G
-p 1 action dscp 33 class 1 color G
-p 1 action dscp 34 class 2 color G
-p 1 action dscp 35 class 3 color G
-p 1 action dscp 36 class 0 color G
-p 1 action dscp 37 class 1 color G
-p 1 action dscp 38 class 2 color G
-p 1 action dscp 39 class 3 color G
-p 1 action dscp 40 class 0 color G
-p 1 action dscp 41 class 1 color G
-p 1 action dscp 42 class 2 color G
-p 1 action dscp 43 class 3 color G
-p 1 action dscp 44 class 0 color G
-p 1 action dscp 45 class 1 color G
-p 1 action dscp 46 class 2 color G
-p 1 action dscp 47 class 3 color G
-p 1 action dscp 48 class 0 color G
-p 1 action dscp 49 class 1 color G
-p 1 action dscp 50 class 2 color G
-p 1 action dscp 51 class 3 color G
-p 1 action dscp 52 class 0 color G
-p 1 action dscp 53 class 1 color G
-p 1 action dscp 54 class 2 color G
-p 1 action dscp 55 class 3 color G
-p 1 action dscp 56 class 0 color G
-p 1 action dscp 57 class 1 color G
-p 1 action dscp 58 class 2 color G
-p 1 action dscp 59 class 3 color G
-p 1 action dscp 60 class 0 color G
-p 1 action dscp 61 class 1 color G
-p 1 action dscp 62 class 2 color G
-p 1 action dscp 63 class 3 color G
-
-p 1 action dscp ls
diff --git a/examples/ip_pipeline/config/action.txt b/examples/ip_pipeline/config/action.txt
deleted file mode 100644
index f14207b9..00000000
--- a/examples/ip_pipeline/config/action.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-#
-# p <pipelineid> action flow bulk ./config/action.txt
-#
-
-flow 0 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 0
-flow 1 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 1
-flow 2 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 2
-flow 3 meter 0 trtcm 1250000000 1250000000 1000000 1000000 policer 0 g G y Y r R meter 1 trtcm 1250000000 1250000000 1000000 1000000 policer 1 g G y Y r R meter 2 trtcm 1250000000 1250000000 1000000 1000000 policer 2 g G y Y r R meter 3 trtcm 1250000000 1250000000 1000000 1000000 policer 3 g G y Y r R port 3
diff --git a/examples/ip_pipeline/config/diagram-generator.py b/examples/ip_pipeline/config/diagram-generator.py
deleted file mode 100755
index d9efc75e..00000000
--- a/examples/ip_pipeline/config/diagram-generator.py
+++ /dev/null
@@ -1,317 +0,0 @@
-#!/usr/bin/env python
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2016 Intel Corporation
-
-#
-# This script creates a visual representation for a configuration file used by
-# the DPDK ip_pipeline application.
-#
-# The input configuration file is translated to an output file in DOT syntax,
-# which is then used to create the image file using graphviz
-# (www.graphviz.org).
-#
-
-from __future__ import print_function
-import argparse
-import re
-import os
-
-#
-# Command to generate the image file
-#
-DOT_COMMAND = 'dot -Gsize=20,30 -Tpng %s > %s'
-
-#
-# Layout of generated DOT file
-#
-DOT_INTRO = \
- '#\n# Command to generate image file:\n# \t%s\n#\n\n'
-DOT_GRAPH_BEGIN = \
- 'digraph g {\n graph [ splines = true rankdir = "LR" ]\n'
-DOT_NODE_LINK_RX = \
- ' "%s RX" [ shape = box style = filled fillcolor = yellowgreen ]\n'
-DOT_NODE_LINK_TX = \
- ' "%s TX" [ shape = box style = filled fillcolor = yellowgreen ]\n'
-DOT_NODE_KNI_RX = \
- ' "%s RX" [ shape = box style = filled fillcolor = orange ]\n'
-DOT_NODE_KNI_TX = \
- ' "%s TX" [ shape = box style = filled fillcolor = orange ]\n'
-DOT_NODE_TAP_RX = \
- ' "%s RX" [ shape = box style = filled fillcolor = gold ]\n'
-DOT_NODE_TAP_TX = \
- ' "%s TX" [ shape = box style = filled fillcolor = gold ]\n'
-DOT_NODE_SOURCE = \
- ' "%s" [ shape = box style = filled fillcolor = darkgreen ]\n'
-DOT_NODE_SINK = \
- ' "%s" [ shape = box style = filled fillcolor = peachpuff ]\n'
-DOT_NODE_PIPELINE = \
- ' "%s" [ shape = box style = filled fillcolor = royalblue ]\n'
-DOT_EDGE_PKTQ = \
- ' "%s" -> "%s" [ label = "%s" color = gray ]\n'
-DOT_GRAPH_END = \
- '}\n'
-
-# Relationships between the graph nodes and the graph edges:
-#
-# Edge ID | Edge Label | Writer Node | Reader Node | Dependencies
-# --------+------------+-------------+---------------+--------------
-# RXQx.y | RXQx.y | LINKx | PIPELINEz | LINKx
-# TXQx.y | TXQx.y | PIPELINEz | LINKx | LINKx
-# SWQx | SWQx | PIPELINEy | PIPELINEz | -
-# TMx | TMx | PIPELINEy | PIPELINEz | LINKx
-# KNIx RX | KNIx | KNIx RX | PIPELINEy | KNIx, LINKx
-# KNIx TX | KNIx | PIPELINEy | KNIx TX | KNIx, LINKx
-# TAPx RX | TAPx | TAPx RX | PIPELINEy | TAPx
-# TAPx TX | TAPx | PIPELINEy | TAPx TX | TAPx
-# SOURCEx | SOURCEx | SOURCEx | PIPELINEy | SOURCEx
-# SINKx | SINKx | PIPELINEy | SINKx | SINKx
-
-
-#
-# Parse the input configuration file to detect the graph nodes and edges
-#
-def process_config_file(cfgfile):
- edges = {}
- links = set()
- knis = set()
- taps = set()
- sources = set()
- sinks = set()
- pipelines = set()
- pipeline = ''
-
- dotfile = cfgfile + '.txt'
- imgfile = cfgfile + '.png'
-
- #
- # Read configuration file
- #
- lines = open(cfgfile, 'r')
- for line in lines:
- # Remove any leading and trailing white space characters
- line = line.strip()
-
- # Remove any comment at end of line
- line, sep, tail = line.partition(';')
-
- # Look for next "PIPELINE" section
- match = re.search(r'\[(PIPELINE\d+)\]', line)
- if match:
- pipeline = match.group(1)
- continue
-
- # Look for next "pktq_in" section entry
- match = re.search(r'pktq_in\s*=\s*(.+)', line)
- if match:
- pipelines.add(pipeline)
- for q in re.findall('\S+', match.group(1)):
- match_rxq = re.search(r'^RXQ(\d+)\.\d+$', q)
- match_swq = re.search(r'^SWQ\d+$', q)
- match_tm = re.search(r'^TM(\d+)$', q)
- match_kni = re.search(r'^KNI(\d+)$', q)
- match_tap = re.search(r'^TAP\d+$', q)
- match_source = re.search(r'^SOURCE\d+$', q)
-
- # Set ID for the current packet queue (graph edge)
- q_id = ''
- if match_rxq or match_swq or match_tm or match_source:
- q_id = q
- elif match_kni or match_tap:
- q_id = q + ' RX'
- else:
- print('Error: Unrecognized pktq_in element "%s"' % q)
- return
-
- # Add current packet queue to the set of graph edges
- if q_id not in edges:
- edges[q_id] = {}
- if 'label' not in edges[q_id]:
- edges[q_id]['label'] = q
- if 'readers' not in edges[q_id]:
- edges[q_id]['readers'] = []
- if 'writers' not in edges[q_id]:
- edges[q_id]['writers'] = []
-
- # Add reader for the new edge
- edges[q_id]['readers'].append(pipeline)
-
- # Check for RXQ
- if match_rxq:
- link = 'LINK' + str(match_rxq.group(1))
- edges[q_id]['writers'].append(link + ' RX')
- links.add(link)
- continue
-
- # Check for SWQ
- if match_swq:
- continue
-
- # Check for TM
- if match_tm:
- link = 'LINK' + str(match_tm.group(1))
- links.add(link)
- continue
-
- # Check for KNI
- if match_kni:
- link = 'LINK' + str(match_kni.group(1))
- edges[q_id]['writers'].append(q_id)
- knis.add(q)
- links.add(link)
- continue
-
- # Check for TAP
- if match_tap:
- edges[q_id]['writers'].append(q_id)
- taps.add(q)
- continue
-
- # Check for SOURCE
- if match_source:
- edges[q_id]['writers'].append(q)
- sources.add(q)
- continue
-
- continue
-
- # Look for next "pktq_out" section entry
- match = re.search(r'pktq_out\s*=\s*(.+)', line)
- if match:
- for q in re.findall('\S+', match.group(1)):
- match_txq = re.search(r'^TXQ(\d+)\.\d+$', q)
- match_swq = re.search(r'^SWQ\d+$', q)
- match_tm = re.search(r'^TM(\d+)$', q)
- match_kni = re.search(r'^KNI(\d+)$', q)
- match_tap = re.search(r'^TAP(\d+)$', q)
- match_sink = re.search(r'^SINK(\d+)$', q)
-
- # Set ID for the current packet queue (graph edge)
- q_id = ''
- if match_txq or match_swq or match_tm or match_sink:
- q_id = q
- elif match_kni or match_tap:
- q_id = q + ' TX'
- else:
- print('Error: Unrecognized pktq_out element "%s"' % q)
- return
-
- # Add current packet queue to the set of graph edges
- if q_id not in edges:
- edges[q_id] = {}
- if 'label' not in edges[q_id]:
- edges[q_id]['label'] = q
- if 'readers' not in edges[q_id]:
- edges[q_id]['readers'] = []
- if 'writers' not in edges[q_id]:
- edges[q_id]['writers'] = []
-
- # Add writer for the new edge
- edges[q_id]['writers'].append(pipeline)
-
- # Check for TXQ
- if match_txq:
- link = 'LINK' + str(match_txq.group(1))
- edges[q_id]['readers'].append(link + ' TX')
- links.add(link)
- continue
-
- # Check for SWQ
- if match_swq:
- continue
-
- # Check for TM
- if match_tm:
- link = 'LINK' + str(match_tm.group(1))
- links.add(link)
- continue
-
- # Check for KNI
- if match_kni:
- link = 'LINK' + str(match_kni.group(1))
- edges[q_id]['readers'].append(q_id)
- knis.add(q)
- links.add(link)
- continue
-
- # Check for TAP
- if match_tap:
- edges[q_id]['readers'].append(q_id)
- taps.add(q)
- continue
-
- # Check for SINK
- if match_sink:
- edges[q_id]['readers'].append(q)
- sinks.add(q)
- continue
-
- continue
-
- #
- # Write DOT file
- #
- print('Creating DOT file "%s" ...' % dotfile)
- dot_cmd = DOT_COMMAND % (dotfile, imgfile)
- file = open(dotfile, 'w')
- file.write(DOT_INTRO % dot_cmd)
- file.write(DOT_GRAPH_BEGIN)
-
- # Write the graph nodes to the DOT file
- for l in sorted(links):
- file.write(DOT_NODE_LINK_RX % l)
- file.write(DOT_NODE_LINK_TX % l)
- for k in sorted(knis):
- file.write(DOT_NODE_KNI_RX % k)
- file.write(DOT_NODE_KNI_TX % k)
- for t in sorted(taps):
- file.write(DOT_NODE_TAP_RX % t)
- file.write(DOT_NODE_TAP_TX % t)
- for s in sorted(sources):
- file.write(DOT_NODE_SOURCE % s)
- for s in sorted(sinks):
- file.write(DOT_NODE_SINK % s)
- for p in sorted(pipelines):
- file.write(DOT_NODE_PIPELINE % p)
-
- # Write the graph edges to the DOT file
- for q in sorted(edges.keys()):
- rw = edges[q]
- if 'writers' not in rw:
- print('Error: "%s" has no writer' % q)
- return
- if 'readers' not in rw:
- print('Error: "%s" has no reader' % q)
- return
- for w in rw['writers']:
- for r in rw['readers']:
- file.write(DOT_EDGE_PKTQ % (w, r, rw['label']))
-
- file.write(DOT_GRAPH_END)
- file.close()
-
- #
- # Execute the DOT command to create the image file
- #
- print('Creating image file "%s" ...' % imgfile)
- if os.system('which dot > /dev/null'):
- print('Error: Unable to locate "dot" executable.'
- 'Please install the "graphviz" package (www.graphviz.org).')
- return
-
- os.system(dot_cmd)
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Create diagram for IP '
- 'pipeline configuration '
- 'file.')
-
- parser.add_argument(
- '-f',
- '--file',
- help='input configuration file (e.g. "ip_pipeline.cfg")',
- required=True)
-
- args = parser.parse_args()
-
- process_config_file(args.file)
diff --git a/examples/ip_pipeline/config/edge_router_downstream.cfg b/examples/ip_pipeline/config/edge_router_downstream.cfg
deleted file mode 100644
index c6b4e1f2..00000000
--- a/examples/ip_pipeline/config/edge_router_downstream.cfg
+++ /dev/null
@@ -1,97 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-; An edge router typically sits between two networks such as the provider
-; core network and the provider access network. A typical packet processing
-; pipeline for the downstream traffic (i.e. traffic from core to access
-; network) contains the following functional blocks: Packet RX & Routing,
-; Traffic management and Packet TX. The input packets are assumed to be
-; IPv4, while the output packets are Q-in-Q IPv4.
-;
-; A simple implementation for this functional pipeline is presented below.
-;
-; Packet Rx & Traffic Management Packet Tx
-; Routing (Pass-Through) (Pass-Through)
-; _____________________ SWQ0 ______________________ SWQ4 _____________________
-; RXQ0.0 --->| |----->| |----->| |---> TXQ0.0
-; | | SWQ1 | | SWQ5 | |
-; RXQ1.0 --->| |----->| |----->| |---> TXQ1.0
-; | (P1) | SWQ2 | (P2) | SWQ6 | (P3) |
-; RXQ2.0 --->| |----->| |----->| |---> TXQ2.0
-; | | SWQ3 | | SWQ7 | |
-; RXQ3.0 --->| |----->| |----->| |---> TXQ3.0
-; |_____________________| |______________________| |_____________________|
-; | | ^ | ^ | ^ | ^
-; | |__| |__| |__| |__|
-; +--> SINK0 TM0 TM1 TM2 TM3
-; (Default)
-;
-; Input packet: Ethernet/IPv4
-; Output packet: Ethernet/QinQ/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
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = ROUTING
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = SWQ0 SWQ1 SWQ2 SWQ3 SINK0
-encap = ethernet_qinq
-qinq_sched = test
-ip_hdr_offset = 270
-
-[PIPELINE2]
-type = PASS-THROUGH
-core = 2
-pktq_in = SWQ0 SWQ1 SWQ2 SWQ3 TM0 TM1 TM2 TM3
-pktq_out = TM0 TM1 TM2 TM3 SWQ4 SWQ5 SWQ6 SWQ7
-
-[PIPELINE3]
-type = PASS-THROUGH
-core = 3
-pktq_in = SWQ4 SWQ5 SWQ6 SWQ7
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0
-
-[MEMPOOL0]
-pool_size = 2M
diff --git a/examples/ip_pipeline/config/edge_router_downstream.sh b/examples/ip_pipeline/config/edge_router_downstream.sh
deleted file mode 100644
index 67c3a0d1..00000000
--- a/examples/ip_pipeline/config/edge_router_downstream.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# run ./config/edge_router_downstream.sh
-#
-
-################################################################################
-# Routing: Ether QinQ, ARP off
-################################################################################
-p 1 route add default 4 #SINK0
-p 1 route add 0.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 qinq 256 257
-p 1 route add 0.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 qinq 258 259
-p 1 route add 0.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 qinq 260 261
-p 1 route add 0.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 qinq 262 263
-#p 1 route ls
diff --git a/examples/ip_pipeline/config/edge_router_upstream.cfg b/examples/ip_pipeline/config/edge_router_upstream.cfg
deleted file mode 100644
index dea42b95..00000000
--- a/examples/ip_pipeline/config/edge_router_upstream.cfg
+++ /dev/null
@@ -1,124 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-; An edge router typically sits between two networks such as the provider
-; core network and the provider access network. A typical packet processing
-; pipeline for the upstream traffic (i.e. traffic from access to core
-; network) contains the following functional blocks: Packet RX & Firewall,
-; Flow classification, Metering, Routing and Packet TX. The input packets
-; are assumed to be Q-in-Q IPv4, while the output packets are MPLS IPv4
-; (with variable number of labels per route).
-;
-; A simple implementation for this functional pipeline is presented below.
-;
-; Packet RX & Pass-Through Flow Classification Flow Actions Routing
-: Firewall
-; __________ SWQ0 __________ SWQ4 __________ SWQ8 __________ SWQ12 __________
-; RXQ0.0 --->| |------>| |------>| |------>| |------>| |------> TXQ0.0
-; | | SWQ1 | | SWQ5 | | SWQ9 | | SWQ13 | |
-; RXQ1.0 --->| |------>| |------>| |------>| |------>| |------> TXQ1.0
-; | (P1) | SWQ2 | (P2) | SWQ6 | (P3) | SWQ10 | (P4) | SWQ14 | (P5) |
-; RXQ2.0 --->| |------>| |------>| |------>| |------>| |------> TXQ2.0
-; | | SWQ3 | | SWQ7 | | SWQ11 | | SWQ15 | |
-; RXQ3.0 --->| |------>| |------>| |------>| |------>| |------> TXQ3.0
-; |__________| |__________| |__________| |__________| |__________|
-; | | |
-; +--> SINK0 (Default) +--> SINK1 (Default) +--> SINK2 (Default)
-;
-; Input packet: Ethernet/QinQ/IPv4
-; Output packet: Ethernet/MPLS/IPv4
-;
-; Packet buffer layout:
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 QinQ header 270 8
-; 4 IPv4 header 278 20
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = FIREWALL
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = SWQ0 SWQ1 SWQ2 SWQ3 SINK0
-n_rules = 4096
-pkt_type = qinq_ipv4
-
-[PIPELINE2]
-type = PASS-THROUGH
-core = 2
-pktq_in = SWQ0 SWQ1 SWQ2 SWQ3
-pktq_out = SWQ4 SWQ5 SWQ6 SWQ7
-dma_size = 8
-dma_dst_offset = 128
-dma_src_offset = 268; 1st Ethertype offset
-dma_src_mask = 00000FFF00000FFF; qinq
-dma_hash_offset = 136; dma_dst_offset + dma_size
-
-[PIPELINE3]
-type = FLOW_CLASSIFICATION
-core = 2
-pktq_in = SWQ4 SWQ5 SWQ6 SWQ7
-pktq_out = SWQ8 SWQ9 SWQ10 SWQ11 SINK1
-n_flows = 65536
-key_size = 8; dma_size
-key_offset = 128; dma_dst_offset
-hash_offset = 136; dma_hash_offset
-flowid_offset = 192
-
-[PIPELINE4]
-type = FLOW_ACTIONS
-core = 3
-pktq_in = SWQ8 SWQ9 SWQ10 SWQ11
-pktq_out = SWQ12 SWQ13 SWQ14 SWQ15
-n_flows = 65536
-n_meters_per_flow = 1
-flow_id_offset = 192; flowid_offset
-ip_hdr_offset = 278
-color_offset = 196; flowid_offset + sizeof(flow_id)
-
-[PIPELINE5]
-type = ROUTING
-core = 4
-pktq_in = SWQ12 SWQ13 SWQ14 SWQ15
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK2
-encap = ethernet_mpls
-mpls_color_mark = yes
-ip_hdr_offset = 278
-color_offset = 196; flowid_offset + sizeof(flow_id)
diff --git a/examples/ip_pipeline/config/edge_router_upstream.sh b/examples/ip_pipeline/config/edge_router_upstream.sh
deleted file mode 100644
index 5d574c1a..00000000
--- a/examples/ip_pipeline/config/edge_router_upstream.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# run ./config/edge_router_upstream.sh
-#
-
-################################################################################
-# Firewall
-################################################################################
-p 1 firewall add default 4 #SINK0
-p 1 firewall add bulk ./config/edge_router_upstream_firewall.txt
-#p 1 firewall ls
-
-################################################################################
-# Flow Classification
-################################################################################
-p 3 flow add default 4 #SINK1
-p 3 flow add qinq bulk ./config/edge_router_upstream_flow.txt
-#p 3 flow ls
-
-################################################################################
-# Flow Actions - Metering and Policing
-################################################################################
-p 4 action flow bulk ./config/edge_router_upstream_action.txt
-#p 4 action flow ls
-
-################################################################################
-# Routing: Ether MPLS, ARP off
-################################################################################
-p 5 route add default 4 #SINK2
-p 5 route add 0.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 mpls 0:1
-p 5 route add 0.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 mpls 10:11
-p 5 route add 0.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 mpls 20:21
-p 5 route add 0.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 mpls 30:31
-#p 5 route ls
diff --git a/examples/ip_pipeline/config/firewall.cfg b/examples/ip_pipeline/config/firewall.cfg
deleted file mode 100644
index 2f5dd9f6..00000000
--- a/examples/ip_pipeline/config/firewall.cfg
+++ /dev/null
@@ -1,68 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; _______________
-; RXQ0.0 --->| |---> TXQ0.0
-; | |
-; RXQ1.0 --->| |---> TXQ1.0
-; | Firewall |
-; RXQ2.0 --->| |---> TXQ2.0
-; | |
-; RXQ3.0 --->| |---> TXQ3.0
-; |_______________|
-; |
-; +-----------> SINK0 (default rule)
-;
-; 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
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = FIREWALL
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
-n_rules = 4096
-pkt_type = ipv4
-;pkt_type = vlan_ipv4
-;pkt_type = qinq_ipv4
diff --git a/examples/ip_pipeline/config/firewall.sh b/examples/ip_pipeline/config/firewall.sh
deleted file mode 100644
index c83857ee..00000000
--- a/examples/ip_pipeline/config/firewall.sh
+++ /dev/null
@@ -1,13 +0,0 @@
-#
-# run ./config/firewall.sh
-#
-
-p 1 firewall add default 4 #SINK0
-p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 0xF port 0
-p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 0xF port 1
-p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 0xF port 2
-p 1 firewall add priority 1 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 0xF port 3
-
-#p 1 firewall add bulk ./config/firewall.txt
-
-p 1 firewall ls
diff --git a/examples/ip_pipeline/config/firewall.txt b/examples/ip_pipeline/config/firewall.txt
deleted file mode 100644
index 54cfffda..00000000
--- a/examples/ip_pipeline/config/firewall.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# p <pipelineid> firewall add bulk ./config/firewall.txt
-# p <pipelineid> firewall del bulk ./config/firewall.txt
-#
-
-priority 1 ipv4 0.0.0.0 0 100.0.0.0 10 0 65535 0 65535 6 0xF port 0
-priority 1 ipv4 0.0.0.0 0 100.64.0.0 10 0 65535 0 65535 6 0xF port 1
-priority 1 ipv4 0.0.0.0 0 100.128.0.0 10 0 65535 0 65535 6 0xF port 2
-priority 1 ipv4 0.0.0.0 0 100.192.0.0 10 0 65535 0 65535 6 0xF port 3
diff --git a/examples/ip_pipeline/config/flow.cfg b/examples/ip_pipeline/config/flow.cfg
deleted file mode 100644
index cec990ab..00000000
--- a/examples/ip_pipeline/config/flow.cfg
+++ /dev/null
@@ -1,72 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; ________________
-; RXQ0.0 --->| |---> TXQ0.0
-; | |
-; RXQ1.0 --->| |---> TXQ1.0
-; | Flow |
-; RXQ2.0 --->| Classification |---> TXQ2.0
-; | |
-; RXQ3.0 --->| |---> TXQ3.0
-; |________________|
-; |
-; +-----------> 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 QinQ/IPv4/IPv6 header 270 8/20/40
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = FLOW_CLASSIFICATION
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
-n_flows = 65536
-;key_size = 8 ; QinQ key size
-;key_offset = 268 ; QinQ key offset
-;key_mask = 00000FFF00000FFF ; QinQ key mask
-key_size = 16 ; IPv4 5-tuple key size
-key_offset = 278 ; IPv4 5-tuple key offset
-key_mask = 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF ; IPv4 5-tuple key mask
-flowid_offset = 128
diff --git a/examples/ip_pipeline/config/flow.sh b/examples/ip_pipeline/config/flow.sh
deleted file mode 100644
index 489c7079..00000000
--- a/examples/ip_pipeline/config/flow.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#
-# run ./config/flow.sh
-#
-
-################################################################################
-# Flow classification (QinQ)
-################################################################################
-#p 1 flow add default 4 #SINK0
-#p 1 flow add qinq 100 200 port 0 id 0
-#p 1 flow add qinq 101 201 port 1 id 1
-#p 1 flow add qinq 102 202 port 2 id 2
-#p 1 flow add qinq 103 203 port 3 id 3
-
-#p 1 flow add qinq bulk ./config/flow.txt
-
-################################################################################
-# Flow classification (IPv4 5-tuple)
-################################################################################
-p 1 flow add default 4 #SINK0
-p 1 flow add ipv4 100.0.0.10 200.0.0.10 100 200 6 port 0 id 0
-p 1 flow add ipv4 100.0.0.11 200.0.0.11 101 201 6 port 1 id 1
-p 1 flow add ipv4 100.0.0.12 200.0.0.12 102 202 6 port 2 id 2
-p 1 flow add ipv4 100.0.0.13 200.0.0.13 103 203 6 port 3 id 3
-
-#p 1 flow add ipv4 bulk ./config/flow.txt
diff --git a/examples/ip_pipeline/config/flow.txt b/examples/ip_pipeline/config/flow.txt
deleted file mode 100644
index c1a141dd..00000000
--- a/examples/ip_pipeline/config/flow.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# p <pipelineid> flow add qinq bulk ./config/flow.txt
-#
-
-#qinq 100 200 port 0 id 0
-#qinq 101 201 port 1 id 1
-#qinq 102 202 port 2 id 2
-#qinq 103 203 port 3 id 3
-
-#
-# p <pipelineid> flow add ipv4 bulk ./config/flow.txt
-#
-
-ipv4 100.0.0.10 200.0.0.10 100 200 6 port 0 id 0
-ipv4 100.0.0.11 200.0.0.11 101 201 6 port 1 id 1
-ipv4 100.0.0.12 200.0.0.12 102 202 6 port 2 id 2
-ipv4 100.0.0.13 200.0.0.13 103 203 6 port 3 id 3
diff --git a/examples/ip_pipeline/config/ip_pipeline.cfg b/examples/ip_pipeline/config/ip_pipeline.cfg
deleted file mode 100644
index 095ed25e..00000000
--- a/examples/ip_pipeline/config/ip_pipeline.cfg
+++ /dev/null
@@ -1,9 +0,0 @@
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = PASS-THROUGH
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0
diff --git a/examples/ip_pipeline/config/ip_pipeline.sh b/examples/ip_pipeline/config/ip_pipeline.sh
deleted file mode 100644
index 4fca2597..00000000
--- a/examples/ip_pipeline/config/ip_pipeline.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-#run config/ip_pipeline.sh
-#
-
-p 1 ping
diff --git a/examples/ip_pipeline/config/kni.cfg b/examples/ip_pipeline/config/kni.cfg
deleted file mode 100644
index cea208b4..00000000
--- a/examples/ip_pipeline/config/kni.cfg
+++ /dev/null
@@ -1,67 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2016 Intel Corporation.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-;
-; ______________ ______________________
-; | | KNI0 | |
-; RXQ0.0 --->| |------->|--+ |
-; | | KNI1 | | br0 |
-; TXQ1.0 <---| |<-------|<-+ |
-; | Pass-through | | Linux Kernel |
-; | (P1) | | Network Stack |
-; | | KNI1 | |
-; RXQ1.0 --->| |------->|--+ |
-; | | KNI0 | | br0 |
-; TXQ0.0 <---| |<-------|<-+ |
-; |______________| |______________________|
-;
-; Insert Linux kernel KNI module:
-; [Linux]$ insmod rte_kni.ko
-;
-; Configure Linux kernel bridge between KNI0 and KNI1 interfaces:
-; [Linux]$ ifconfig KNI0 up
-; [Linux]$ ifconfig KNI1 up
-; [Linux]$ brctl addbr "br0"
-; [Linux]$ brctl addif br0 KNI0
-; [Linux]$ brctl addif br0 KNI1
-; [Linux]$ ifconfig br0 up
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = PASS-THROUGH
-core = 1
-pktq_in = RXQ0.0 KNI1 RXQ1.0 KNI0
-pktq_out = KNI0 TXQ1.0 KNI1 TXQ0.0
diff --git a/examples/ip_pipeline/config/l2fwd.cfg b/examples/ip_pipeline/config/l2fwd.cfg
deleted file mode 100644
index a1df9e6a..00000000
--- a/examples/ip_pipeline/config/l2fwd.cfg
+++ /dev/null
@@ -1,58 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-;
-; The pass-through pipeline below connects the input ports to the output ports
-; as follows: RXQ0.0 -> TXQ1.0, RXQ1.0 -> TXQ0.0, RXQ2.0 -> TXQ3.0 and
-; RXQ3.0 -> TXQ2.0.
-; ________________
-; RXQ0.0 --->|................|---> TXQ1.0
-; | |
-; RXQ1.0 --->|................|---> TXQ0.0
-; | Pass-through |
-; RXQ2.0 --->|................|---> TXQ3.0
-; | |
-; RXQ3.0 --->|................|---> TXQ2.0
-; |________________|
-;
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = PASS-THROUGH
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = TXQ1.0 TXQ0.0 TXQ3.0 TXQ2.0
diff --git a/examples/ip_pipeline/config/l3fwd.cfg b/examples/ip_pipeline/config/l3fwd.cfg
deleted file mode 100644
index 02c8f36f..00000000
--- a/examples/ip_pipeline/config/l3fwd.cfg
+++ /dev/null
@@ -1,68 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; _______________
-; RXQ0.0 --->| |---> TXQ0.0
-; | |
-; RXQ1.0 --->| |---> TXQ1.0
-; | Routing |
-; RXQ2.0 --->| |---> TXQ2.0
-; | |
-; RXQ3.0 --->| |---> TXQ3.0
-; |_______________|
-; |
-; +-----------> 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
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = ROUTING
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
-encap = ethernet
-;encap = ethernet_qinq
-;encap = ethernet_mpls
-ip_hdr_offset = 270
diff --git a/examples/ip_pipeline/config/l3fwd.sh b/examples/ip_pipeline/config/l3fwd.sh
deleted file mode 100644
index 47406aa4..00000000
--- a/examples/ip_pipeline/config/l3fwd.sh
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# run ./config/l3fwd.sh
-#
-
-################################################################################
-# Routing: encap = ethernet, arp = off
-################################################################################
-p 1 route add default 4 #SINK0
-p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0
-p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1
-p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2
-p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3
-p 1 route ls
-
-################################################################################
-# Routing: encap = ethernet_qinq, arp = off
-################################################################################
-#p 1 route add default 4 #SINK0
-#p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 qinq 1000 2000
-#p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 qinq 1001 2001
-#p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 qinq 1002 2002
-#p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 qinq 1003 2003
-#p 1 route ls
-
-################################################################################
-# Routing: encap = ethernet_mpls, arp = off
-################################################################################
-#p 1 route add default 4 #SINK0
-#p 1 route add 100.0.0.0 10 port 0 ether a0:b0:c0:d0:e0:f0 mpls 1000:2000
-#p 1 route add 100.64.0.0 10 port 1 ether a1:b1:c1:d1:e1:f1 mpls 1001:2001
-#p 1 route add 100.128.0.0 10 port 2 ether a2:b2:c2:d2:e2:f2 mpls 1002:2002
-#p 1 route add 100.192.0.0 10 port 3 ether a3:b3:c3:d3:e3:f3 mpls 1003:2003
-#p 1 route ls
diff --git a/examples/ip_pipeline/config/l3fwd_arp.cfg b/examples/ip_pipeline/config/l3fwd_arp.cfg
deleted file mode 100644
index 2c63c8fd..00000000
--- a/examples/ip_pipeline/config/l3fwd_arp.cfg
+++ /dev/null
@@ -1,70 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2015-2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; _______________
-; RXQ0.0 --->| |---> TXQ0.0
-; | |
-; RXQ1.0 --->| |---> TXQ1.0
-; | Routing |
-; RXQ2.0 --->| |---> TXQ2.0
-; | |
-; RXQ3.0 --->| |---> TXQ3.0
-; |_______________|
-; |
-; +-----------> 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
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = ROUTING
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK0
-encap = ethernet
-;encap = ethernet_qinq
-;encap = ethernet_mpls
-n_arp_entries = 1024
-ip_hdr_offset = 270
-arp_key_offset = 128
diff --git a/examples/ip_pipeline/config/l3fwd_arp.sh b/examples/ip_pipeline/config/l3fwd_arp.sh
deleted file mode 100644
index 20bea582..00000000
--- a/examples/ip_pipeline/config/l3fwd_arp.sh
+++ /dev/null
@@ -1,43 +0,0 @@
-#
-# run ./config/l3fwd_arp.sh
-#
-
-################################################################################
-# ARP
-################################################################################
-p 1 arp add default 4 #SINK0
-p 1 arp add 0 10.0.0.1 a0:b0:c0:d0:e0:f0
-p 1 arp add 1 11.0.0.1 a1:b1:c1:d1:e1:f1
-p 1 arp add 2 12.0.0.1 a2:b2:c2:d2:e2:f2
-p 1 arp add 3 13.0.0.1 a3:b3:c3:d3:e3:f3
-p 1 arp ls
-
-################################################################################
-# Routing: encap = ethernet, arp = on
-################################################################################
-p 1 route add default 4 #SINK0
-p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1
-p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1
-p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1
-p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1
-p 1 route ls
-
-################################################################################
-# Routing: encap = ethernet_qinq, arp = on
-################################################################################
-#p 1 route add default 4 #SINK0
-#p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1 qinq 1000 2000
-#p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1 qinq 1001 2001
-#p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1 qinq 1002 2002
-#p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1 qinq 1003 2003
-#p 1 route ls
-
-################################################################################
-# Routing: encap = ethernet_mpls, arp = on
-################################################################################
-#p 1 route add default 4 #SINK0
-#p 1 route add 100.0.0.0 10 port 0 ether 10.0.0.1 mpls 1000:2000
-#p 1 route add 100.64.0.0 10 port 1 ether 11.0.0.1 mpls 1001:2001
-#p 1 route add 100.128.0.0 10 port 2 ether 12.0.0.1 mpls 1002:2002
-#p 1 route add 100.192.0.0 10 port 3 ether 13.0.0.1 mpls 1003:2003
-#p 1 route ls
diff --git a/examples/ip_pipeline/config/network_layers.cfg b/examples/ip_pipeline/config/network_layers.cfg
deleted file mode 100644
index 397b5d77..00000000
--- a/examples/ip_pipeline/config/network_layers.cfg
+++ /dev/null
@@ -1,227 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; The diagram below shows how additional protocol components can be plugged into
-; the IP layer implemented by the ip_pipeline application. Pick your favorite
-; open source components for dynamic ARP, ICMP, UDP or TCP termination, etc and
-; connect them through SWQs to the IP infrastructure.
-;
-; The input packets with local destination are sent to the UDP/TCP applications
-; while the input packets with remote destination are routed back to the
-; network. Additional features can easily be added to this setup:
-; * IP Reassembly: add SWQs with IP reassembly enabled (typically required for
-; the input traffic with local destination);
-; * IP Fragmentation: add SWQs with IP fragmentation enabled (typically
-; required to enforce the MTU for the routed output traffic);
-; * Traffic Metering: add Flow Action pipeline instances (e.g. for metering the
-; TCP connections or ICMP input traffic);
-; * Traffic Management: add TMs for the required output LINKs;
-; * Protocol encapsulations (QinQ, MPLS) for the output packets: part of the
-; routing pipeline configuration.
-;
-; _________ _________
-; | | | |
-; | UDP | | TCP |
-; | App | | App |
-; |_________| |_________|
-; ^ | ^ |
-; __|___V__ __|___V__
-; | | SWQ0 (UDP TX) | | SWQ1 (TCP TX)
-; | UDP |-------+ | TCP |------------+
-; | | | | | |
-; |_________| | |_________| |
-; ^ | ^ |
-; | SWQ2 | | SWQ3 |
-; | (UDP RX) | | (TCP RX) |
-; ____|____ | ____|____ |
-; | | | | | |
-; RXQ<0..3>.1 ------>|Firewall +--->| | +------>| Flow +--->| |
-; (UDP local dest) | (P2) | SINK0 | | | (P3) | SINK1 |
-; |_________| (Deny)| | |_________| (RST) |
-; RXQ<0..3>.2 -------------------------|-----+ |
-; (TCP local dest) | |
-; | +------------------------------+
-; | |
-; _V_____V_
-; | |
-; | Routing | TXQ<0..3>.0
-; RXQ<0..3>.0 ---------------------->| & ARP +----------------------------->
-; (IP remote dest) | (P1) |
-; |_________|
-; | ^ |
-; SWQ4 +-------------+ | | SWQ5 (ARP miss)
-; (Route miss) | | +------------+
-; | +-------------+ |
-; ___V__|__ SWQ6 ____V____
-; | | (ICMP TX) | | TXQ<0..3>.1
-; RXQ<0..3>.3 ------>| ICMP | +------>| Dyn ARP +------------->
-; (IP local dest) | | | | |
-; |_________| | |_________|
-; RXQ<0..3>.4 -------------------------------+
-; (ARP)
-;
-; This configuration file implements the diagram presented below, where the
-; dynamic ARP, ICMP, UDP and TCP components have been stubbed out and replaced
-; with loop-back and packet drop devices.
-;
-; _________ _________
-; | | SWQ0 (UDP TX) | | SWQ1 (TCP TX)
-; |Loobpack |-------+ |Loopback |------------+
-; | (P4) | | | (P5) | |
-; |_________| | |_________| |
-; ^ | ^ |
-; | SWQ2 | | SWQ3 |
-; | (UDP RX) | | (TCP RX) |
-; ____|____ | ____|____ |
-; | | | | | |
-; RXQ<0..3>.1 ------>|Firewall +--->| | +------>| Flow +--->| |
-; (UDP local dest) | (P2) | SINK0 | | | (P3) | SINK1 |
-; |_________| (Deny)| | |_________| (RST) |
-; RXQ<0..3>.2 -------------------------|-----+ |
-; (TCP local dest) | |
-; | +------------------------------+
-; | |
-; _V_____V_
-; | |
-; | Routing | TXQ<0..3>.0
-; RXQ<0..3>.0 ---------------------->| & ARP +----------------------------->
-; (IP remote dest) | (P1) |
-; |_________|
-; | |
-; SINK2 |<---+ +--->| SINK3
-; (Route miss) (ARP miss)
-;
-; _________ _________
-; | | | |
-; RXQ<0..3>.3 ------>| Drop +--->| SINK<4..7> +------>| Drop +--->| SINK<8..11>
-; (IP local dest) | (P6) | (IP local dest) | | (P7) | (ARP)
-; |_________| | |_________|
-; RXQ<0..3>.4 ------------------------------------+
-; (ARP)
-;
-;
-; Input packet: Ethernet/IPv4 or Ethernet/ARP
-; Output packet: Ethernet/IPv4 or Ethernet/ARP
-;
-; Packet buffer layout (for input IPv4 packets):
-; # Field Name Offset (Bytes) Size (Bytes)
-; 0 Mbuf 0 128
-; 1 Headroom 128 128
-; 2 Ethernet header 256 14
-; 3 IPv4 header 270 20
-; 4 ICMP/UDP/TCP header 290 8/8/20
-
-[EAL]
-log_level = 0
-
-[LINK0]
-udp_local_q = 1
-tcp_local_q = 2
-ip_local_q = 3
-arp_q = 4
-
-[LINK1]
-udp_local_q = 1
-tcp_local_q = 2
-ip_local_q = 3
-arp_q = 4
-
-[LINK2]
-udp_local_q = 1
-tcp_local_q = 2
-ip_local_q = 3
-arp_q = 4
-
-[LINK3]
-udp_local_q = 1
-tcp_local_q = 2
-ip_local_q = 3
-arp_q = 4
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = ROUTING
-core = 1
-pktq_in = RXQ0.0 RXQ1.0 RXQ2.0 RXQ3.0 SWQ0 SWQ1
-pktq_out = TXQ0.0 TXQ1.0 TXQ2.0 TXQ3.0 SINK2 SINK3
-port_local_dest = 4 ; SINK2 (Drop)
-n_arp_entries = 1000
-ip_hdr_offset = 270
-arp_key_offset = 128
-
-[PIPELINE2]
-type = FIREWALL
-core = 1
-pktq_in = RXQ0.1 RXQ1.1 RXQ2.1 RXQ3.1
-pktq_out = SWQ2 SINK0
-n_rules = 4096
-
-[PIPELINE3]
-type = FLOW_CLASSIFICATION
-core = 1
-pktq_in = RXQ0.2 RXQ1.2 RXQ2.2 RXQ3.2
-pktq_out = SWQ3 SINK1
-n_flows = 65536
-key_size = 16 ; IPv4 5-tuple key size
-key_offset = 278 ; IPv4 5-tuple key offset
-key_mask = 00FF0000FFFFFFFFFFFFFFFFFFFFFFFF ; IPv4 5-tuple key mask
-flowid_offset = 128 ; Flow ID effectively acts as TCP socket ID
-
-[PIPELINE4]
-type = PASS-THROUGH ; Loop-back (UDP place-holder)
-core = 1
-pktq_in = SWQ2
-pktq_out = SWQ0
-swap = 282 286 ; IPSRC <-> IPDST
-swap = 290 292 ; PORTSRC <-> PORTDST
-
-[PIPELINE5]
-type = PASS-THROUGH ; Loop-back (TCP place-holder)
-core = 1
-pktq_in = SWQ3
-pktq_out = SWQ1
-swap = 282 286 ; IPSRC <-> IPDST
-swap = 290 292 ; PORTSRC <-> PORTDST
-
-[PIPELINE6]
-type = PASS-THROUGH ; Drop (ICMP place-holder)
-core = 1
-pktq_in = RXQ0.3 RXQ1.3 RXQ2.3 RXQ3.3
-pktq_out = SINK4 SINK5 SINK6 SINK7
-
-[PIPELINE7]
-type = PASS-THROUGH ; Drop (Dynamic ARP place-holder)
-core = 1
-pktq_in = RXQ0.4 RXQ1.4 RXQ2.4 RXQ3.4
-pktq_out = SINK8 SINK9 SINK10 SINK11
diff --git a/examples/ip_pipeline/config/network_layers.sh b/examples/ip_pipeline/config/network_layers.sh
deleted file mode 100644
index 449b0069..00000000
--- a/examples/ip_pipeline/config/network_layers.sh
+++ /dev/null
@@ -1,79 +0,0 @@
-#
-# run ./config/network_layers.sh
-#
-
-################################################################################
-# Link configuration
-################################################################################
-# Routes added implicitly when links are brought UP:
-# IP Prefix = 10.0.0.1/16 => (Port 0, Local)
-# IP Prefix = 10.0.0.1/32 => (Port 4, Local)
-# IP Prefix = 10.1.0.1/16 => (Port 1, Local)
-# IP Prefix = 10.1.0.1/32 => (Port 4, Local)
-# IP Prefix = 10.2.0.1/16 => (Port 2, Local)
-# IP Prefix = 10.2.0.1/32 => (Port 4, Local)
-# IP Prefix = 10.3.0.1/16 => (Port 3, Local)
-# IP Prefix = 10.3.0.1/32 => (Port 4, Local)
-link 0 down
-link 1 down
-link 2 down
-link 3 down
-link 0 config 10.0.0.1 16
-link 1 config 10.1.0.1 16
-link 2 config 10.2.0.1 16
-link 3 config 10.3.0.1 16
-link 0 up
-link 1 up
-link 2 up
-link 3 up
-#link ls
-
-################################################################################
-# Static ARP
-################################################################################
-p 1 arp add default 5 #SINK3
-p 1 arp add 0 10.0.0.2 a0:b0:c0:d0:e0:f0
-p 1 arp add 1 10.1.0.2 a1:b1:c1:d1:e1:f1
-p 1 arp add 2 10.2.0.2 a2:b2:c2:d2:e2:f2
-p 1 arp add 3 10.3.0.2 a3:b3:c3:d3:e3:f3
-#p 1 arp ls
-
-################################################################################
-# Routes
-################################################################################
-p 1 route add default 4 #SINK2
-p 1 route add 100.0.0.0 16 port 0 ether 10.0.0.2
-p 1 route add 100.1.0.0 16 port 1 ether 10.1.0.2
-p 1 route add 100.2.0.0 16 port 2 ether 10.2.0.2
-p 1 route add 100.3.0.0 16 port 3 ether 10.3.0.2
-#p 1 route ls
-
-################################################################################
-# Local destination UDP traffic
-################################################################################
-# Prio = Lowest: [SA = ANY, DA = ANY, SP = ANY, DP = ANY, PROTO = ANY] => Drop
-# Prio = 1 (High): [SA = ANY, DA = 10.0.0.1, SP = ANY, DP = 1000, PROTO = UDP] => Allow
-# Prio = 1 (High): [SA = ANY, DA = 10.1.0.1, SP = ANY, DP = 1001, PROTO = UDP] => Allow
-# Prio = 1 (High): [SA = ANY, DA = 10.2.0.1, SP = ANY, DP = 1002, PROTO = UDP] => Allow
-# Prio = 1 (High): [SA = ANY, DA = 10.3.0.1, SP = ANY, DP = 1003, PROTO = UDP] => Allow
-p 2 firewall add default 1 #SINK0
-p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.0.0.1 32 0 65535 1000 1000 17 0xF port 0
-p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.1.0.1 32 0 65535 1001 1001 17 0xF port 0
-p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.2.0.1 32 0 65535 1002 1002 17 0xF port 0
-p 2 firewall add priority 1 ipv4 0.0.0.0 0 10.3.0.1 32 0 65535 1003 1003 17 0xF port 0
-#p 2 firewall ls
-
-################################################################################
-# Local destination TCP traffic
-################################################################################
-# Unknown connection => Drop
-# TCP [SA = 100.0.0.10, DA = 10.0.0.1, SP = 1000, DP = 80] => socket ID = 0
-# TCP [SA = 100.1.0.10, DA = 10.1.0.1, SP = 1001, DP = 80] => socket ID = 1
-# TCP [SA = 100.2.0.10, DA = 10.2.0.1, SP = 1002, DP = 80] => socket ID = 2
-# TCP [SA = 100.3.0.10, DA = 10.3.0.1, SP = 1003, DP = 80] => socket ID = 3
-p 3 flow add default 1 #SINK1
-p 3 flow add ipv4 100.0.0.10 10.0.0.1 1000 80 6 port 0 id 0
-p 3 flow add ipv4 100.1.0.10 10.1.0.1 1001 80 6 port 0 id 1
-p 3 flow add ipv4 100.2.0.10 10.2.0.1 1002 80 6 port 0 id 2
-p 3 flow add ipv4 100.3.0.10 10.3.0.1 1003 80 6 port 0 id 3
-#p 3 flow ls
diff --git a/examples/ip_pipeline/config/pipeline-to-core-mapping.py b/examples/ip_pipeline/config/pipeline-to-core-mapping.py
deleted file mode 100755
index fc52b2b3..00000000
--- a/examples/ip_pipeline/config/pipeline-to-core-mapping.py
+++ /dev/null
@@ -1,906 +0,0 @@
-#!/usr/bin/env python
-# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2016 Intel Corporation
-
-#
-# This script maps the set of pipelines identified (MASTER pipelines are
-# ignored) from the input configuration file to the set of cores
-# provided as input argument and creates configuration files for each of
-# the mapping combinations.
-#
-
-from __future__ import print_function
-from collections import namedtuple
-import argparse
-import array
-import errno
-import itertools
-import os
-import re
-import sys
-
-# default values
-enable_stage0_traceout = 1
-enable_stage1_traceout = 1
-enable_stage2_traceout = 1
-
-enable_stage1_fileout = 1
-enable_stage2_fileout = 1
-
-Constants = namedtuple('Constants', ['MAX_CORES', 'MAX_PIPELINES'])
-constants = Constants(16, 64)
-
-# pattern for physical core
-pattern_phycore = '^(s|S)\d(c|C)[1-9][0-9]*$'
-reg_phycore = re.compile(pattern_phycore)
-
-
-def popcount(mask):
- return bin(mask).count("1")
-
-
-def len2mask(length):
- if (length == 0):
- return 0
-
- if (length > 64):
- sys.exit('error: len2mask - length %i > 64. exiting' % length)
-
- return int('1' * length, 2)
-
-
-def bitstring_write(n, n_bits):
- tmpstr = ""
- if (n_bits > 64):
- return
-
- i = n_bits - 1
- while (i >= 0):
- cond = (n & (1 << i))
- if (cond):
- print('1', end='')
- tmpstr += '1'
- else:
- print('0', end='')
- tmpstr += '0'
- i -= 1
- return tmpstr
-
-
-class Cores0:
-
- def __init__(self):
- self.n_pipelines = 0
-
-
-class Cores1:
-
- def __init__(self):
- self.pipelines = 0
- self.n_pipelines = 0
-
-
-class Cores2:
-
- def __init__(self):
- self.pipelines = 0
- self.n_pipelines = 0
- self.counter = 0
- self.counter_max = 0
- self.bitpos = array.array(
- "L", itertools.repeat(0, constants.MAX_PIPELINES))
-
-
-class Context0:
-
- def __init__(self):
- self.cores = [Cores0() for i in range(0, constants.MAX_CORES)]
- self.n_cores = 0
- self.n_pipelines = 0
- self.n_pipelines0 = 0
- self.pos = 0
- self.file_comment = ""
- self.ctx1 = None
- self.ctx2 = None
-
- def stage0_print(self):
- print('printing Context0 obj')
- print('c0.cores(n_pipelines) = [ ', end='')
- for cores_count in range(0, constants.MAX_CORES):
- print(self.cores[cores_count].n_pipelines, end=' ')
- print(']')
- print('c0.n_cores = %d' % self.n_cores)
- print('c0.n_pipelines = %d' % self.n_pipelines)
- print('c0.n_pipelines0 = %d' % self.n_pipelines0)
- print('c0.pos = %d' % self.pos)
- print('c0.file_comment = %s' % self.file_comment)
- if (self.ctx1 is not None):
- print('c0.ctx1 = ', end='')
- print(repr(self.ctx1))
- else:
- print('c0.ctx1 = None')
-
- if (self.ctx2 is not None):
- print('c0.ctx2 = ', end='')
- print(repr(self.ctx2))
- else:
- print('c0.ctx2 = None')
-
- def stage0_init(self, num_cores, num_pipelines, ctx1, ctx2):
- self.n_cores = num_cores
- self.n_pipelines = num_pipelines
- self.ctx1 = ctx1
- self.ctx2 = ctx2
-
- def stage0_process(self):
- # stage0 init
- self.cores[0].n_pipelines = self.n_pipelines
- self.n_pipelines0 = 0
- self.pos = 1
-
- while True:
- # go forward
- while True:
- if ((self.pos < self.n_cores) and (self.n_pipelines0 > 0)):
- self.cores[self.pos].n_pipelines = min(
- self.cores[self.pos - 1].n_pipelines,
- self.n_pipelines0)
- self.n_pipelines0 -= self.cores[self.pos].n_pipelines
- self.pos += 1
- else:
- break
-
- # check solution
- if (self.n_pipelines0 == 0):
- self.stage0_log()
- self.ctx1.stage1_init(self, self.ctx2) # self is object c0
- self.ctx1.stage1_process()
-
- # go backward
- while True:
- if (self.pos == 0):
- return
-
- self.pos -= 1
- if ((self.cores[self.pos].n_pipelines > 1) and
- (self.pos != (self.n_cores - 1))):
- break
-
- self.n_pipelines0 += self.cores[self.pos].n_pipelines
- self.cores[self.pos].n_pipelines = 0
-
- # rearm
- self.cores[self.pos].n_pipelines -= 1
- self.n_pipelines0 += 1
- self.pos += 1
-
- def stage0_log(self):
- tmp_file_comment = ""
- if(enable_stage0_traceout != 1):
- return
-
- print('STAGE0: ', end='')
- tmp_file_comment += 'STAGE0: '
- for cores_count in range(0, self.n_cores):
- print('C%d = %d\t'
- % (cores_count,
- self.cores[cores_count].n_pipelines), end='')
- tmp_file_comment += "C{} = {}\t".format(
- cores_count, self.cores[cores_count].n_pipelines)
- # end for
- print('')
- self.ctx1.stage0_file_comment = tmp_file_comment
- self.ctx2.stage0_file_comment = tmp_file_comment
-
-
-class Context1:
- _fileTrace = None
-
- def __init__(self):
- self.cores = [Cores1() for i in range(constants.MAX_CORES)]
- self.n_cores = 0
- self.n_pipelines = 0
- self.pos = 0
- self.stage0_file_comment = ""
- self.stage1_file_comment = ""
-
- self.ctx2 = None
- self.arr_pipelines2cores = []
-
- def stage1_reset(self):
- for i in range(constants.MAX_CORES):
- self.cores[i].pipelines = 0
- self.cores[i].n_pipelines = 0
-
- self.n_cores = 0
- self.n_pipelines = 0
- self.pos = 0
- self.ctx2 = None
- # clear list
- del self.arr_pipelines2cores[:]
-
- def stage1_print(self):
- print('printing Context1 obj')
- print('ctx1.cores(pipelines,n_pipelines) = [ ', end='')
- for cores_count in range(0, constants.MAX_CORES):
- print('(%d,%d)' % (self.cores[cores_count].pipelines,
- self.cores[cores_count].n_pipelines), end=' ')
- print(']')
- print('ctx1.n_cores = %d' % self.n_cores)
- print('ctx1.n_pipelines = %d' % self.n_pipelines)
- print('ctx1.pos = %d' % self.pos)
- print('ctx1.stage0_file_comment = %s' % self.stage0_file_comment)
- print('ctx1.stage1_file_comment = %s' % self.stage1_file_comment)
- if (self.ctx2 is not None):
- print('ctx1.ctx2 = ', end='')
- print(self.ctx2)
- else:
- print('ctx1.ctx2 = None')
-
- def stage1_init(self, c0, ctx2):
- self.stage1_reset()
- self.n_cores = 0
- while (c0.cores[self.n_cores].n_pipelines > 0):
- self.n_cores += 1
-
- self.n_pipelines = c0.n_pipelines
- self.ctx2 = ctx2
-
- self.arr_pipelines2cores = [0] * self.n_pipelines
-
- i = 0
- while (i < self.n_cores):
- self.cores[i].n_pipelines = c0.cores[i].n_pipelines
- i += 1
-
- def stage1_process(self):
- pipelines_max = len2mask(self.n_pipelines)
- while True:
- pos = 0
- overlap = 0
-
- if (self.cores[self.pos].pipelines == pipelines_max):
- if (self.pos == 0):
- return
-
- self.cores[self.pos].pipelines = 0
- self.pos -= 1
- continue
-
- self.cores[self.pos].pipelines += 1
- if (popcount(self.cores[self.pos].pipelines) !=
- self.cores[self.pos].n_pipelines):
- continue
-
- overlap = 0
- pos = 0
- while (pos < self.pos):
- if ((self.cores[self.pos].pipelines) &
- (self.cores[pos].pipelines)):
- overlap = 1
- break
- pos += 1
-
- if (overlap):
- continue
-
- if ((self.pos > 0) and
- ((self.cores[self.pos].n_pipelines) ==
- (self.cores[self.pos - 1].n_pipelines)) and
- ((self.cores[self.pos].pipelines) <
- (self.cores[self.pos - 1].pipelines))):
- continue
-
- if (self.pos == self.n_cores - 1):
- self.stage1_log()
- self.ctx2.stage2_init(self)
- self.ctx2.stage2_process()
-
- if (self.pos == 0):
- return
-
- self.cores[self.pos].pipelines = 0
- self.pos -= 1
- continue
-
- self.pos += 1
-
- def stage1_log(self):
- tmp_file_comment = ""
- if(enable_stage1_traceout == 1):
- print('STAGE1: ', end='')
- tmp_file_comment += 'STAGE1: '
- i = 0
- while (i < self.n_cores):
- print('C%d = [' % i, end='')
- tmp_file_comment += "C{} = [".format(i)
-
- j = self.n_pipelines - 1
- while (j >= 0):
- cond = ((self.cores[i].pipelines) & (1 << j))
- if (cond):
- print('1', end='')
- tmp_file_comment += '1'
- else:
- print('0', end='')
- tmp_file_comment += '0'
- j -= 1
-
- print(']\t', end='')
- tmp_file_comment += ']\t'
- i += 1
-
- print('\n', end='')
- self.stage1_file_comment = tmp_file_comment
- self.ctx2.stage1_file_comment = tmp_file_comment
-
- # check if file traceing is enabled
- if(enable_stage1_fileout != 1):
- return
-
- # spit out the combination to file
- self.stage1_process_file()
-
- def stage1_updateCoresInBuf(self, nPipeline, sCore):
- rePipeline = self._fileTrace.arr_pipelines[nPipeline]
- rePipeline = rePipeline.replace("[", "\[").replace("]", "\]")
- reCore = 'core\s*=\s*((\d*)|(((s|S)\d)?(c|C)[1-9][0-9]*)).*\n'
- sSubs = 'core = ' + sCore + '\n'
-
- reg_pipeline = re.compile(rePipeline)
- search_match = reg_pipeline.search(self._fileTrace.in_buf)
-
- if(search_match):
- pos = search_match.start()
- substr1 = self._fileTrace.in_buf[:pos]
- substr2 = self._fileTrace.in_buf[pos:]
- substr2 = re.sub(reCore, sSubs, substr2, 1)
- self._fileTrace.in_buf = substr1 + substr2
-
- def stage1_process_file(self):
- outFileName = os.path.join(self._fileTrace.out_path,
- self._fileTrace.prefix_outfile)
- outFileName += "_{}CoReS".format(self.n_cores)
-
- i = 0 # represents core number
- while (i < self.n_cores):
- j = self.n_pipelines - 1
- pipeline_idx = 0
- while(j >= 0):
- cond = ((self.cores[i].pipelines) & (1 << j))
- if (cond):
- # update the pipelines array to match the core
- # only in case of cond match
- self.arr_pipelines2cores[
- pipeline_idx] = fileTrace.in_physical_cores[i]
-
- j -= 1
- pipeline_idx += 1
-
- i += 1
-
- # update the in_buf as per the arr_pipelines2cores
- for pipeline_idx in range(len(self.arr_pipelines2cores)):
- outFileName += "_{}".format(self.arr_pipelines2cores[pipeline_idx])
- self.stage1_updateCoresInBuf(
- pipeline_idx, self.arr_pipelines2cores[pipeline_idx])
-
- # by now the in_buf is all set to be written to file
- outFileName += self._fileTrace.suffix_outfile
- outputFile = open(outFileName, "w")
-
- # write out the comments
- strTruncated = ("", "(Truncated)")[self._fileTrace.ncores_truncated]
- outputFile.write(
- "; =============== Pipeline-to-Core Mapping ================\n"
- "; Generated from file {}\n"
- "; Input pipelines = {}\n"
- "; Input cores = {}\n"
- "; N_PIPELINES = {} N_CORES = {} {} hyper_thread = {}\n"
- .format(
- self._fileTrace.in_file_namepath,
- fileTrace.arr_pipelines,
- fileTrace.in_physical_cores,
- self._fileTrace.n_pipelines,
- self._fileTrace.n_cores,
- strTruncated,
- self._fileTrace.hyper_thread))
-
- outputFile.write(
- "; {stg0cmt}\n"
- "; {stg1cmt}\n"
- "; ========================================================\n"
- "; \n"
- .format(
- stg0cmt=self.stage0_file_comment,
- stg1cmt=self.stage1_file_comment))
-
- # write buffer contents
- outputFile.write(self._fileTrace.in_buf)
- outputFile.flush()
- outputFile.close()
-
-
-class Context2:
- _fileTrace = None
-
- def __init__(self):
- self.cores = [Cores2() for i in range(constants.MAX_CORES)]
- self.n_cores = 0
- self.n_pipelines = 0
- self.pos = 0
- self.stage0_file_comment = ""
- self.stage1_file_comment = ""
- self.stage2_file_comment = ""
-
- # each array entry is a pipeline mapped to core stored as string
- # pipeline ranging from 1 to n, however stored in zero based array
- self.arr2_pipelines2cores = []
-
- def stage2_print(self):
- print('printing Context2 obj')
- print('ctx2.cores(pipelines, n_pipelines, counter, counter_max) =')
- for cores_count in range(0, constants.MAX_CORES):
- print('core[%d] = (%d,%d,%d,%d)' % (
- cores_count,
- self.cores[cores_count].pipelines,
- self.cores[cores_count].n_pipelines,
- self.cores[cores_count].counter,
- self.cores[cores_count].counter_max))
-
- print('ctx2.n_cores = %d' % self.n_cores, end='')
- print('ctx2.n_pipelines = %d' % self.n_pipelines, end='')
- print('ctx2.pos = %d' % self.pos)
- print('ctx2.stage0_file_comment = %s' %
- self.self.stage0_file_comment)
- print('ctx2.stage1_file_comment = %s' %
- self.self.stage1_file_comment)
- print('ctx2.stage2_file_comment = %s' %
- self.self.stage2_file_comment)
-
- def stage2_reset(self):
- for i in range(0, constants.MAX_CORES):
- self.cores[i].pipelines = 0
- self.cores[i].n_pipelines = 0
- self.cores[i].counter = 0
- self.cores[i].counter_max = 0
-
- for idx in range(0, constants.MAX_PIPELINES):
- self.cores[i].bitpos[idx] = 0
-
- self.n_cores = 0
- self.n_pipelines = 0
- self.pos = 0
- # clear list
- del self.arr2_pipelines2cores[:]
-
- def bitpos_load(self, coreidx):
- i = j = 0
- while (i < self.n_pipelines):
- if ((self.cores[coreidx].pipelines) &
- (1 << i)):
- self.cores[coreidx].bitpos[j] = i
- j += 1
- i += 1
- self.cores[coreidx].n_pipelines = j
-
- def bitpos_apply(self, in_buf, pos, n_pos):
- out = 0
- for i in range(0, n_pos):
- out |= (in_buf & (1 << i)) << (pos[i] - i)
-
- return out
-
- def stage2_init(self, ctx1):
- self.stage2_reset()
- self.n_cores = ctx1.n_cores
- self.n_pipelines = ctx1.n_pipelines
-
- self.arr2_pipelines2cores = [''] * self.n_pipelines
-
- core_idx = 0
- while (core_idx < self.n_cores):
- self.cores[core_idx].pipelines = ctx1.cores[core_idx].pipelines
-
- self.bitpos_load(core_idx)
- core_idx += 1
-
- def stage2_log(self):
- tmp_file_comment = ""
- if(enable_stage2_traceout == 1):
- print('STAGE2: ', end='')
- tmp_file_comment += 'STAGE2: '
-
- for i in range(0, self.n_cores):
- mask = len2mask(self.cores[i].n_pipelines)
- pipelines_ht0 = self.bitpos_apply(
- (~self.cores[i].counter) & mask,
- self.cores[i].bitpos,
- self.cores[i].n_pipelines)
-
- pipelines_ht1 = self.bitpos_apply(
- self.cores[i].counter,
- self.cores[i].bitpos,
- self.cores[i].n_pipelines)
-
- print('C%dHT0 = [' % i, end='')
- tmp_file_comment += "C{}HT0 = [".format(i)
- tmp_file_comment += bitstring_write(
- pipelines_ht0, self.n_pipelines)
-
- print(']\tC%dHT1 = [' % i, end='')
- tmp_file_comment += "]\tC{}HT1 = [".format(i)
- tmp_file_comment += bitstring_write(
- pipelines_ht1, self.n_pipelines)
- print(']\t', end='')
- tmp_file_comment += ']\t'
-
- print('')
- self.stage2_file_comment = tmp_file_comment
-
- # check if file traceing is enabled
- if(enable_stage2_fileout != 1):
- return
- # spit out the combination to file
- self.stage2_process_file()
-
- def stage2_updateCoresInBuf(self, nPipeline, sCore):
- rePipeline = self._fileTrace.arr_pipelines[nPipeline]
- rePipeline = rePipeline.replace("[", "\[").replace("]", "\]")
- reCore = 'core\s*=\s*((\d*)|(((s|S)\d)?(c|C)[1-9][0-9]*)).*\n'
- sSubs = 'core = ' + sCore + '\n'
-
- reg_pipeline = re.compile(rePipeline)
- search_match = reg_pipeline.search(self._fileTrace.in_buf)
-
- if(search_match):
- pos = search_match.start()
- substr1 = self._fileTrace.in_buf[:pos]
- substr2 = self._fileTrace.in_buf[pos:]
- substr2 = re.sub(reCore, sSubs, substr2, 1)
- self._fileTrace.in_buf = substr1 + substr2
-
- def pipelines2cores(self, n, n_bits, nCore, bHT):
- if (n_bits > 64):
- return
-
- i = n_bits - 1
- pipeline_idx = 0
- while (i >= 0):
- cond = (n & (1 << i))
- if (cond):
- # update the pipelines array to match the core
- # only in case of cond match
- # PIPELINE0 and core 0 are reserved
- if(bHT):
- tmpCore = fileTrace.in_physical_cores[nCore] + 'h'
- self.arr2_pipelines2cores[pipeline_idx] = tmpCore
- else:
- self.arr2_pipelines2cores[pipeline_idx] = \
- fileTrace.in_physical_cores[nCore]
-
- i -= 1
- pipeline_idx += 1
-
- def stage2_process_file(self):
- outFileName = os.path.join(self._fileTrace.out_path,
- self._fileTrace.prefix_outfile)
- outFileName += "_{}CoReS".format(self.n_cores)
-
- for i in range(0, self.n_cores):
- mask = len2mask(self.cores[i].n_pipelines)
- pipelines_ht0 = self.bitpos_apply((~self.cores[i].counter) & mask,
- self.cores[i].bitpos,
- self.cores[i].n_pipelines)
-
- pipelines_ht1 = self.bitpos_apply(self.cores[i].counter,
- self.cores[i].bitpos,
- self.cores[i].n_pipelines)
-
- # update pipelines to core mapping
- self.pipelines2cores(pipelines_ht0, self.n_pipelines, i, False)
- self.pipelines2cores(pipelines_ht1, self.n_pipelines, i, True)
-
- # update the in_buf as per the arr_pipelines2cores
- for pipeline_idx in range(len(self.arr2_pipelines2cores)):
- outFileName += "_{}".format(
- self.arr2_pipelines2cores[pipeline_idx])
- self.stage2_updateCoresInBuf(
- pipeline_idx, self.arr2_pipelines2cores[pipeline_idx])
-
- # by now the in_buf is all set to be written to file
- outFileName += self._fileTrace.suffix_outfile
- outputFile = open(outFileName, "w")
-
- # write the file comments
- strTruncated = ("", "(Truncated)")[self._fileTrace.ncores_truncated]
- outputFile.write(
- "; =============== Pipeline-to-Core Mapping ================\n"
- "; Generated from file {}\n"
- "; Input pipelines = {}\n"
- "; Input cores = {}\n"
- "; N_PIPELINES = {} N_CORES = {} {} hyper_thread = {} \n"
- .format(
- self._fileTrace.in_file_namepath,
- fileTrace.arr_pipelines,
- fileTrace.in_physical_cores,
- self._fileTrace.n_pipelines,
- self._fileTrace.n_cores,
- strTruncated,
- self._fileTrace.hyper_thread))
-
- outputFile.write(
- "; {stg0cmt}\n"
- "; {stg1cmt}\n"
- "; {stg2cmt}\n"
- "; ========================================================\n"
- "; \n"
- .format(
- stg0cmt=self.stage0_file_comment,
- stg1cmt=self.stage1_file_comment,
- stg2cmt=self.stage2_file_comment))
-
- # write the buffer contents
- outputFile.write(self._fileTrace.in_buf)
- outputFile.flush()
- outputFile.close()
-
- def stage2_process(self):
- i = 0
- while(i < self.n_cores):
- self.cores[i].counter_max = len2mask(
- self.cores[i].n_pipelines - 1)
- i += 1
-
- self.pos = self.n_cores - 1
- while True:
- if (self.pos == self.n_cores - 1):
- self.stage2_log()
-
- if (self.cores[self.pos].counter ==
- self.cores[self.pos].counter_max):
- if (self.pos == 0):
- return
-
- self.cores[self.pos].counter = 0
- self.pos -= 1
- continue
-
- self.cores[self.pos].counter += 1
- if(self.pos < self.n_cores - 1):
- self.pos += 1
-
-
-class FileTrace:
-
- def __init__(self, filenamepath):
- self.in_file_namepath = os.path.abspath(filenamepath)
- self.in_filename = os.path.basename(self.in_file_namepath)
- self.in_path = os.path.dirname(self.in_file_namepath)
-
- filenamesplit = self.in_filename.split('.')
- self.prefix_outfile = filenamesplit[0]
- self.suffix_outfile = ".cfg"
-
- # output folder: in the same folder as input file
- # create new folder in the name of input file
- self.out_path = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- self.prefix_outfile)
-
- try:
- os.makedirs(self.out_path)
- except OSError as excep:
- if excep.errno == errno.EEXIST and os.path.isdir(self.out_path):
- pass
- else:
- raise
-
- self.in_buf = None
- self.arr_pipelines = [] # holds the positions of search
-
- self.max_cores = 15
- self.max_pipelines = 15
-
- self.in_physical_cores = None
- self.hyper_thread = None
-
- # save the num of pipelines determined from input file
- self.n_pipelines = 0
- # save the num of cores input (or the truncated value)
- self.n_cores = 0
- self.ncores_truncated = False
-
- def print_TraceFile(self):
- print("self.in_file_namepath = ", self.in_file_namepath)
- print("self.in_filename = ", self.in_filename)
- print("self.in_path = ", self.in_path)
- print("self.out_path = ", self.out_path)
- print("self.prefix_outfile = ", self.prefix_outfile)
- print("self.suffix_outfile = ", self.suffix_outfile)
- print("self.in_buf = ", self.in_buf)
- print("self.arr_pipelines =", self.arr_pipelines)
- print("self.in_physical_cores", self.in_physical_cores)
- print("self.hyper_thread", self.hyper_thread)
-
-
-def process(n_cores, n_pipelines, fileTrace):
- '''process and map pipelines, cores.'''
- if (n_cores == 0):
- sys.exit('N_CORES is 0, exiting')
-
- if (n_pipelines == 0):
- sys.exit('N_PIPELINES is 0, exiting')
-
- if (n_cores > n_pipelines):
- print('\nToo many cores, truncating N_CORES to N_PIPELINES')
- n_cores = n_pipelines
- fileTrace.ncores_truncated = True
-
- fileTrace.n_pipelines = n_pipelines
- fileTrace.n_cores = n_cores
-
- strTruncated = ("", "(Truncated)")[fileTrace.ncores_truncated]
- print("N_PIPELINES = {}, N_CORES = {} {}"
- .format(n_pipelines, n_cores, strTruncated))
- print("---------------------------------------------------------------")
-
- ctx0_inst = Context0()
- ctx1_inst = Context1()
- ctx2_inst = Context2()
-
- # initialize the class variables
- ctx1_inst._fileTrace = fileTrace
- ctx2_inst._fileTrace = fileTrace
-
- ctx0_inst.stage0_init(n_cores, n_pipelines, ctx1_inst, ctx2_inst)
- ctx0_inst.stage0_process()
-
-
-def validate_core(core):
- match = reg_phycore.match(core)
- if(match):
- return True
- else:
- return False
-
-
-def validate_phycores(phy_cores):
- '''validate physical cores, check if unique.'''
- # eat up whitespaces
- phy_cores = phy_cores.strip().split(',')
-
- # check if the core list is unique
- if(len(phy_cores) != len(set(phy_cores))):
- print('list of physical cores has duplicates')
- return None
-
- for core in phy_cores:
- if not validate_core(core):
- print('invalid physical core specified.')
- return None
- return phy_cores
-
-
-def scanconfigfile(fileTrace):
- '''scan input file for pipelines, validate then process.'''
- # open file
- filetoscan = open(fileTrace.in_file_namepath, 'r')
- fileTrace.in_buf = filetoscan.read()
-
- # reset iterator on open file
- filetoscan.seek(0)
-
- # scan input file for pipelines
- # master pipelines to be ignored
- pattern_pipeline = r'\[PIPELINE\d*\]'
- pattern_mastertype = r'type\s*=\s*MASTER'
-
- pending_pipeline = False
- for line in filetoscan:
- match_pipeline = re.search(pattern_pipeline, line)
- match_type = re.search('type\s*=', line)
- match_mastertype = re.search(pattern_mastertype, line)
-
- if(match_pipeline):
- sPipeline = line[match_pipeline.start():match_pipeline.end()]
- pending_pipeline = True
- elif(match_type):
- # found a type definition...
- if(match_mastertype is None):
- # and this is not a master pipeline...
- if(pending_pipeline):
- # add it to the list of pipelines to be mapped
- fileTrace.arr_pipelines.append(sPipeline)
- pending_pipeline = False
- else:
- # and this is a master pipeline...
- # ignore the current and move on to next
- sPipeline = ""
- pending_pipeline = False
- filetoscan.close()
-
- # validate if pipelines are unique
- if(len(fileTrace.arr_pipelines) != len(set(fileTrace.arr_pipelines))):
- sys.exit('Error: duplicate pipelines in input file')
-
- num_pipelines = len(fileTrace.arr_pipelines)
- num_cores = len(fileTrace.in_physical_cores)
-
- print("-------------------Pipeline-to-core mapping--------------------")
- print("Input pipelines = {}\nInput cores = {}"
- .format(fileTrace.arr_pipelines, fileTrace.in_physical_cores))
-
- # input configuration file validations goes here
- if (num_cores > fileTrace.max_cores):
- sys.exit('Error: number of cores specified > max_cores (%d)' %
- fileTrace.max_cores)
-
- if (num_pipelines > fileTrace.max_pipelines):
- sys.exit('Error: number of pipelines in input \
- cfg file > max_pipelines (%d)' % fileTrace.max_pipelines)
-
- # call process to generate pipeline-to-core mapping, trace and log
- process(num_cores, num_pipelines, fileTrace)
-
-
-if __name__ == "__main__":
- parser = argparse.ArgumentParser(description='mappipelines')
-
- reqNamedGrp = parser.add_argument_group('required named args')
- reqNamedGrp.add_argument(
- '-i',
- '--input-file',
- type=argparse.FileType('r'),
- help='Input config file',
- required=True)
-
- reqNamedGrp.add_argument(
- '-pc',
- '--physical-cores',
- type=validate_phycores,
- help='''Enter available CPU cores in
- format:\"<core>,<core>,...\"
- where each core format: \"s<SOCKETID>c<COREID>\"
- where SOCKETID={0..9}, COREID={1-99}''',
- required=True)
-
- # add optional arguments
- parser.add_argument(
- '-ht',
- '--hyper-thread',
- help='enable/disable hyper threading. default is ON',
- default='ON',
- choices=['ON', 'OFF'])
-
- parser.add_argument(
- '-nO',
- '--no-output-file',
- help='''disable output config file generation.
- Output file generation is enabled by default''',
- action="store_true")
-
- args = parser.parse_args()
-
- if(args.physical_cores is None):
- parser.error("invalid physical_cores specified")
-
- # create object of FileTrace and initialise
- fileTrace = FileTrace(args.input_file.name)
- fileTrace.in_physical_cores = args.physical_cores
- fileTrace.hyper_thread = args.hyper_thread
-
- if(fileTrace.hyper_thread == 'OFF'):
- print("!!!!disabling stage2 HT!!!!")
- enable_stage2_traceout = 0
- enable_stage2_fileout = 0
- elif(fileTrace.hyper_thread == 'ON'):
- print("!!!!HT enabled. disabling stage1 file generation.!!!!")
- enable_stage1_fileout = 0
-
- if(args.no_output_file is True):
- print("!!!!disabling stage1 and stage2 fileout!!!!")
- enable_stage1_fileout = 0
- enable_stage2_fileout = 0
-
- scanconfigfile(fileTrace)
diff --git a/examples/ip_pipeline/config/tap.cfg b/examples/ip_pipeline/config/tap.cfg
deleted file mode 100644
index 10d35ebb..00000000
--- a/examples/ip_pipeline/config/tap.cfg
+++ /dev/null
@@ -1,64 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2016 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; ______________ ______________________
-; | | TAP0 | |
-; RXQ0.0 --->| |------->|--+ |
-; | | TAP1 | | br0 |
-; TXQ1.0 <---| |<-------|<-+ |
-; | Pass-through | | Linux Kernel |
-; | (P1) | | Network Stack |
-; | | TAP1 | |
-; RXQ1.0 --->| |------->|--+ |
-; | | TAP0 | | br0 |
-; TXQ0.0 <---| |<-------|<-+ |
-; |______________| |______________________|
-;
-; Configure Linux kernel bridge between TAP0 and TAP1 interfaces:
-; [Linux]$ ifconfig TAP0 up
-; [Linux]$ ifconfig TAP1 up
-; [Linux]$ brctl addbr "br0"
-; [Linux]$ brctl addif br0 TAP0
-; [Linux]$ brctl addif br0 TAP1
-; [Linux]$ ifconfig br0 up
-
-[EAL]
-log_level = 0
-
-[PIPELINE0]
-type = MASTER
-core = 0
-
-[PIPELINE1]
-type = PASS-THROUGH
-core = 1
-pktq_in = RXQ0.0 TAP1 RXQ1.0 TAP0
-pktq_out = TAP0 TXQ1.0 TAP1 TXQ0.0
diff --git a/examples/ip_pipeline/config/tm_profile.cfg b/examples/ip_pipeline/config/tm_profile.cfg
deleted file mode 100644
index 2dfb215e..00000000
--- a/examples/ip_pipeline/config/tm_profile.cfg
+++ /dev/null
@@ -1,105 +0,0 @@
-; BSD LICENSE
-;
-; Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-; All rights reserved.
-;
-; Redistribution and use in source and binary forms, with or without
-; modification, are permitted provided that the following conditions
-; are met:
-;
-; * Redistributions of source code must retain the above copyright
-; notice, this list of conditions and the following disclaimer.
-; * Redistributions in binary form must reproduce the above copyright
-; notice, this list of conditions and the following disclaimer in
-; the documentation and/or other materials provided with the
-; distribution.
-; * Neither the name of Intel Corporation nor the names of its
-; contributors may be used to endorse or promote products derived
-; from this software without specific prior written permission.
-;
-; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-; LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-; DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-; THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-; This file enables the following hierarchical scheduler configuration for each
-; 10GbE output port:
-; * Single subport (subport 0):
-; - Subport rate set to 100% of port rate
-; - Each of the 4 traffic classes has rate set to 100% of port rate
-; * 4K pipes per subport 0 (pipes 0 .. 4095) with identical configuration:
-; - Pipe rate set to 1/4K of port rate
-; - Each of the 4 traffic classes has rate set to 100% of pipe rate
-; - Within each traffic class, the byte-level WRR weights for the 4 queues
-; are set to 1:1:1:1
-;
-; For more details, please refer to chapter "Quality of Service (QoS) Framework"
-; of Data Plane Development Kit (DPDK) Programmer's Guide.
-
-; Port configuration
-[port]
-frame overhead = 24 ; frame overhead = Preamble (7) + SFD (1) + FCS (4) + IFG (12)
-mtu = 1522; mtu = Q-in-Q MTU (FCS not included)
-number of subports per port = 1
-number of pipes per subport = 4096
-queue sizes = 64 64 64 64
-
-; Subport configuration
-[subport 0]
-tb rate = 1250000000 ; Bytes per second
-tb size = 1000000 ; Bytes
-
-tc 0 rate = 1250000000 ; Bytes per second
-tc 1 rate = 1250000000 ; Bytes per second
-tc 2 rate = 1250000000 ; Bytes per second
-tc 3 rate = 1250000000 ; Bytes per second
-tc period = 10 ; Milliseconds
-
-pipe 0-4095 = 0 ; These pipes are configured with pipe profile 0
-
-; Pipe configuration
-[pipe profile 0]
-tb rate = 305175 ; Bytes per second
-tb size = 1000000 ; Bytes
-
-tc 0 rate = 305175 ; Bytes per second
-tc 1 rate = 305175 ; Bytes per second
-tc 2 rate = 305175 ; Bytes per second
-tc 3 rate = 305175 ; Bytes per second
-tc period = 40 ; Milliseconds
-
-tc 3 oversubscription weight = 1
-
-tc 0 wrr weights = 1 1 1 1
-tc 1 wrr weights = 1 1 1 1
-tc 2 wrr weights = 1 1 1 1
-tc 3 wrr weights = 1 1 1 1
-
-; RED params per traffic class and color (Green / Yellow / Red)
-[red]
-tc 0 wred min = 48 40 32
-tc 0 wred max = 64 64 64
-tc 0 wred inv prob = 10 10 10
-tc 0 wred weight = 9 9 9
-
-tc 1 wred min = 48 40 32
-tc 1 wred max = 64 64 64
-tc 1 wred inv prob = 10 10 10
-tc 1 wred weight = 9 9 9
-
-tc 2 wred min = 48 40 32
-tc 2 wred max = 64 64 64
-tc 2 wred inv prob = 10 10 10
-tc 2 wred weight = 9 9 9
-
-tc 3 wred min = 48 40 32
-tc 3 wred max = 64 64 64
-tc 3 wred inv prob = 10 10 10
-tc 3 wred weight = 9 9 9
diff --git a/examples/ip_pipeline/config_check.c b/examples/ip_pipeline/config_check.c
deleted file mode 100644
index 86d1191a..00000000
--- a/examples/ip_pipeline/config_check.c
+++ /dev/null
@@ -1,488 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-
-#include <rte_ip.h>
-
-#include "app.h"
-
-static void
-check_mempools(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_mempools; i++) {
- struct app_mempool_params *p = &app->mempool_params[i];
-
- APP_CHECK((p->pool_size > 0),
- "Mempool %s size is 0\n", p->name);
-
- APP_CHECK((p->cache_size > 0),
- "Mempool %s cache size is 0\n", p->name);
-
- APP_CHECK(rte_is_power_of_2(p->cache_size),
- "Mempool %s cache size not a power of 2\n", p->name);
- }
-}
-
-static inline uint32_t
-link_rxq_used(struct app_link_params *link, uint32_t q_id)
-{
- uint32_t i;
-
- if ((link->arp_q == q_id) ||
- (link->tcp_syn_q == q_id) ||
- (link->ip_local_q == q_id) ||
- (link->tcp_local_q == q_id) ||
- (link->udp_local_q == q_id) ||
- (link->sctp_local_q == q_id))
- return 1;
-
- for (i = 0; i < link->n_rss_qs; i++)
- if (link->rss_qs[i] == q_id)
- return 1;
-
- return 0;
-}
-
-static void
-check_links(struct app_params *app)
-{
- uint32_t i;
-
- /* Check that number of links matches the port mask */
- if (app->port_mask) {
- uint32_t n_links_port_mask =
- __builtin_popcountll(app->port_mask);
-
- APP_CHECK((app->n_links == n_links_port_mask),
- "Not enough links provided in the PORT_MASK\n");
- }
-
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *link = &app->link_params[i];
- uint32_t rxq_max, n_rxq, n_txq, link_id, i;
-
- APP_PARAM_GET_ID(link, "LINK", link_id);
-
- /* Check that link RXQs are contiguous */
- rxq_max = 0;
- if (link->arp_q > rxq_max)
- rxq_max = link->arp_q;
- if (link->tcp_syn_q > rxq_max)
- rxq_max = link->tcp_syn_q;
- if (link->ip_local_q > rxq_max)
- rxq_max = link->ip_local_q;
- if (link->tcp_local_q > rxq_max)
- rxq_max = link->tcp_local_q;
- if (link->udp_local_q > rxq_max)
- rxq_max = link->udp_local_q;
- if (link->sctp_local_q > rxq_max)
- rxq_max = link->sctp_local_q;
- for (i = 0; i < link->n_rss_qs; i++)
- if (link->rss_qs[i] > rxq_max)
- rxq_max = link->rss_qs[i];
-
- for (i = 1; i <= rxq_max; i++)
- APP_CHECK((link_rxq_used(link, i)),
- "%s RXQs are not contiguous (A)\n", link->name);
-
- n_rxq = app_link_get_n_rxq(app, link);
-
- APP_CHECK((n_rxq), "%s does not have any RXQ\n", link->name);
-
- APP_CHECK((n_rxq == rxq_max + 1),
- "%s RXQs are not contiguous (B)\n", link->name);
-
- for (i = 0; i < n_rxq; i++) {
- char name[APP_PARAM_NAME_SIZE];
- int pos;
-
- sprintf(name, "RXQ%" PRIu32 ".%" PRIu32,
- link_id, i);
- pos = APP_PARAM_FIND(app->hwq_in_params, name);
- APP_CHECK((pos >= 0),
- "%s RXQs are not contiguous (C)\n", link->name);
- }
-
- /* Check that link TXQs are contiguous */
- n_txq = app_link_get_n_txq(app, link);
-
- APP_CHECK((n_txq), "%s does not have any TXQ\n", link->name);
-
- for (i = 0; i < n_txq; i++) {
- char name[APP_PARAM_NAME_SIZE];
- int pos;
-
- sprintf(name, "TXQ%" PRIu32 ".%" PRIu32,
- link_id, i);
- pos = APP_PARAM_FIND(app->hwq_out_params, name);
- APP_CHECK((pos >= 0),
- "%s TXQs are not contiguous\n", link->name);
- }
- }
-}
-
-static void
-check_rxqs(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_hwq_in; i++) {
- struct app_pktq_hwq_in_params *p = &app->hwq_in_params[i];
- uint32_t n_readers = app_rxq_get_readers(app, p);
-
- APP_CHECK((p->size > 0),
- "%s size is 0\n", p->name);
-
- APP_CHECK((rte_is_power_of_2(p->size)),
- "%s size is not a power of 2\n", p->name);
-
- APP_CHECK((p->burst > 0),
- "%s burst size is 0\n", p->name);
-
- APP_CHECK((p->burst <= p->size),
- "%s burst size is bigger than its size\n", p->name);
-
- APP_CHECK((n_readers != 0),
- "%s has no reader\n", p->name);
-
- APP_CHECK((n_readers == 1),
- "%s has more than one reader\n", p->name);
- }
-}
-
-static void
-check_txqs(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_hwq_out; i++) {
- struct app_pktq_hwq_out_params *p = &app->hwq_out_params[i];
- uint32_t n_writers = app_txq_get_writers(app, p);
-
- APP_CHECK((p->size > 0),
- "%s size is 0\n", p->name);
-
- APP_CHECK((rte_is_power_of_2(p->size)),
- "%s size is not a power of 2\n", p->name);
-
- APP_CHECK((p->burst > 0),
- "%s burst size is 0\n", p->name);
-
- APP_CHECK((p->burst <= p->size),
- "%s burst size is bigger than its size\n", p->name);
-
- APP_CHECK((n_writers != 0),
- "%s has no writer\n", p->name);
-
- APP_CHECK((n_writers == 1),
- "%s has more than one writer\n", p->name);
- }
-}
-
-static void
-check_swqs(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_swq; i++) {
- struct app_pktq_swq_params *p = &app->swq_params[i];
- uint32_t n_readers = app_swq_get_readers(app, p);
- uint32_t n_writers = app_swq_get_writers(app, p);
- uint32_t n_flags;
-
- APP_CHECK((p->size > 0),
- "%s size is 0\n", p->name);
-
- APP_CHECK((rte_is_power_of_2(p->size)),
- "%s size is not a power of 2\n", p->name);
-
- APP_CHECK((p->burst_read > 0),
- "%s read burst size is 0\n", p->name);
-
- APP_CHECK((p->burst_read <= p->size),
- "%s read burst size is bigger than its size\n",
- p->name);
-
- APP_CHECK((p->burst_write > 0),
- "%s write burst size is 0\n", p->name);
-
- APP_CHECK((p->burst_write <= p->size),
- "%s write burst size is bigger than its size\n",
- p->name);
-
- APP_CHECK((n_readers != 0),
- "%s has no reader\n", p->name);
-
- if (n_readers > 1)
- APP_LOG(app, LOW, "%s has more than one reader", p->name);
-
- APP_CHECK((n_writers != 0),
- "%s has no writer\n", p->name);
-
- if (n_writers > 1)
- APP_LOG(app, LOW, "%s has more than one writer", p->name);
-
- n_flags = p->ipv4_frag + p->ipv6_frag + p->ipv4_ras + p->ipv6_ras;
-
- APP_CHECK((n_flags < 2),
- "%s has more than one fragmentation or reassembly mode enabled\n",
- p->name);
-
- APP_CHECK((!((n_readers > 1) && (n_flags == 1))),
- "%s has more than one reader when fragmentation or reassembly"
- " mode enabled\n",
- p->name);
-
- APP_CHECK((!((n_writers > 1) && (n_flags == 1))),
- "%s has more than one writer when fragmentation or reassembly"
- " mode enabled\n",
- p->name);
-
- n_flags = p->ipv4_ras + p->ipv6_ras;
-
- APP_CHECK((!((p->dropless == 1) && (n_flags == 1))),
- "%s has dropless when reassembly mode enabled\n", p->name);
-
- n_flags = p->ipv4_frag + p->ipv6_frag;
-
- if (n_flags == 1) {
- uint16_t ip_hdr_size = (p->ipv4_frag) ? sizeof(struct ipv4_hdr) :
- sizeof(struct ipv6_hdr);
-
- APP_CHECK((p->mtu > ip_hdr_size),
- "%s mtu size is smaller than ip header\n", p->name);
-
- APP_CHECK((!((p->mtu - ip_hdr_size) % 8)),
- "%s mtu size is incorrect\n", p->name);
- }
- }
-}
-
-static void
-check_tms(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_tm; i++) {
- struct app_pktq_tm_params *p = &app->tm_params[i];
- uint32_t n_readers = app_tm_get_readers(app, p);
- uint32_t n_writers = app_tm_get_writers(app, p);
-
- APP_CHECK((n_readers != 0),
- "%s has no reader\n", p->name);
-
- APP_CHECK((n_readers == 1),
- "%s has more than one reader\n", p->name);
-
- APP_CHECK((n_writers != 0),
- "%s has no writer\n", p->name);
-
- APP_CHECK((n_writers == 1),
- "%s has more than one writer\n", p->name);
- }
-}
-
-static void
-check_taps(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_tap; i++) {
- struct app_pktq_tap_params *p = &app->tap_params[i];
- uint32_t n_readers = app_tap_get_readers(app, p);
- uint32_t n_writers = app_tap_get_writers(app, p);
-
- APP_CHECK((n_readers != 0),
- "%s has no reader\n", p->name);
-
- APP_CHECK((n_readers == 1),
- "%s has more than one reader\n", p->name);
-
- APP_CHECK((n_writers != 0),
- "%s has no writer\n", p->name);
-
- APP_CHECK((n_writers == 1),
- "%s has more than one writer\n", p->name);
-
- APP_CHECK((p->burst_read > 0),
- "%s read burst size is 0\n", p->name);
-
- APP_CHECK((p->burst_write > 0),
- "%s write burst size is 0\n", p->name);
- }
-}
-
-static void
-check_knis(struct app_params *app) {
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_kni; i++) {
- struct app_pktq_kni_params *p = &app->kni_params[i];
- uint32_t n_readers = app_kni_get_readers(app, p);
- uint32_t n_writers = app_kni_get_writers(app, p);
-
- APP_CHECK((n_readers != 0),
- "%s has no reader\n", p->name);
-
- APP_CHECK((n_readers == 1),
- "%s has more than one reader\n", p->name);
-
- APP_CHECK((n_writers != 0),
- "%s has no writer\n", p->name);
-
- APP_CHECK((n_writers == 1),
- "%s has more than one writer\n", p->name);
- }
-}
-
-static void
-check_sources(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_source; i++) {
- struct app_pktq_source_params *p = &app->source_params[i];
- uint32_t n_readers = app_source_get_readers(app, p);
-
- APP_CHECK((n_readers != 0),
- "%s has no reader\n", p->name);
-
- APP_CHECK((n_readers == 1),
- "%s has more than one reader\n", p->name);
- }
-}
-
-static void
-check_sinks(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_sink; i++) {
- struct app_pktq_sink_params *p = &app->sink_params[i];
- uint32_t n_writers = app_sink_get_writers(app, p);
-
- APP_CHECK((n_writers != 0),
- "%s has no writer\n", p->name);
-
- APP_CHECK((n_writers == 1),
- "%s has more than one writer\n", p->name);
- }
-}
-
-static void
-check_msgqs(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_msgq; i++) {
- struct app_msgq_params *p = &app->msgq_params[i];
- uint32_t n_readers = app_msgq_get_readers(app, p);
- uint32_t n_writers = app_msgq_get_writers(app, p);
- uint32_t msgq_req_pipeline, msgq_rsp_pipeline;
- uint32_t msgq_req_core, msgq_rsp_core;
-
- APP_CHECK((p->size > 0),
- "%s size is 0\n", p->name);
-
- APP_CHECK((rte_is_power_of_2(p->size)),
- "%s size is not a power of 2\n", p->name);
-
- msgq_req_pipeline = (strncmp(p->name, "MSGQ-REQ-PIPELINE",
- strlen("MSGQ-REQ-PIPELINE")) == 0);
-
- msgq_rsp_pipeline = (strncmp(p->name, "MSGQ-RSP-PIPELINE",
- strlen("MSGQ-RSP-PIPELINE")) == 0);
-
- msgq_req_core = (strncmp(p->name, "MSGQ-REQ-CORE",
- strlen("MSGQ-REQ-CORE")) == 0);
-
- msgq_rsp_core = (strncmp(p->name, "MSGQ-RSP-CORE",
- strlen("MSGQ-RSP-CORE")) == 0);
-
- if ((msgq_req_pipeline == 0) &&
- (msgq_rsp_pipeline == 0) &&
- (msgq_req_core == 0) &&
- (msgq_rsp_core == 0)) {
- APP_CHECK((n_readers != 0),
- "%s has no reader\n", p->name);
-
- APP_CHECK((n_readers == 1),
- "%s has more than one reader\n", p->name);
-
- APP_CHECK((n_writers != 0),
- "%s has no writer\n", p->name);
-
- APP_CHECK((n_writers == 1),
- "%s has more than one writer\n", p->name);
- }
-
- if (msgq_req_pipeline) {
- struct app_pipeline_params *pipeline;
- uint32_t pipeline_id;
-
- APP_PARAM_GET_ID(p, "MSGQ-REQ-PIPELINE", pipeline_id);
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params,
- "PIPELINE",
- pipeline_id,
- pipeline);
-
- APP_CHECK((pipeline != NULL),
- "%s is not associated with a valid pipeline\n",
- p->name);
- }
-
- if (msgq_rsp_pipeline) {
- struct app_pipeline_params *pipeline;
- uint32_t pipeline_id;
-
- APP_PARAM_GET_ID(p, "MSGQ-RSP-PIPELINE", pipeline_id);
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params,
- "PIPELINE",
- pipeline_id,
- pipeline);
-
- APP_CHECK((pipeline != NULL),
- "%s is not associated with a valid pipeline\n",
- p->name);
- }
- }
-}
-
-static void
-check_pipelines(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
-
- APP_CHECK((p->n_msgq_in == p->n_msgq_out),
- "%s number of input MSGQs does not match "
- "the number of output MSGQs\n", p->name);
- }
-}
-
-int
-app_config_check(struct app_params *app)
-{
- check_mempools(app);
- check_links(app);
- check_rxqs(app);
- check_txqs(app);
- check_swqs(app);
- check_tms(app);
- check_taps(app);
- check_knis(app);
- check_sources(app);
- check_sinks(app);
- check_msgqs(app);
- check_pipelines(app);
-
- return 0;
-}
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
deleted file mode 100644
index e90499e7..00000000
--- a/examples/ip_pipeline/config_parse.c
+++ /dev/null
@@ -1,3395 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#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 <rte_errno.h>
-#include <rte_cfgfile.h>
-#include <rte_string_fns.h>
-
-#include "app.h"
-#include "parser.h"
-
-/**
- * Default config values
- **/
-
-static struct app_params app_params_default = {
- .config_file = "./config/ip_pipeline.cfg",
- .log_level = APP_LOG_LEVEL_HIGH,
- .port_mask = 0,
-
- .eal_params = {
- .channels = 4,
- },
-};
-
-static const struct app_mempool_params mempool_params_default = {
- .parsed = 0,
- .buffer_size = 2048 + sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM,
- .pool_size = 32 * 1024,
- .cache_size = 256,
- .cpu_socket_id = 0,
-};
-
-static const struct app_link_params link_params_default = {
- .parsed = 0,
- .pmd_id = 0,
- .arp_q = 0,
- .tcp_syn_q = 0,
- .ip_local_q = 0,
- .tcp_local_q = 0,
- .udp_local_q = 0,
- .sctp_local_q = 0,
- .rss_qs = {0},
- .n_rss_qs = 0,
- .rss_proto_ipv4 = ETH_RSS_IPV4,
- .rss_proto_ipv6 = ETH_RSS_IPV6,
- .rss_proto_l2 = 0,
- .state = 0,
- .ip = 0,
- .depth = 0,
- .mac_addr = 0,
- .pci_bdf = {0},
-
- .conf = {
- .link_speeds = 0,
- .rxmode = {
- .mq_mode = ETH_MQ_RX_NONE,
-
- .ignore_offload_bitfield = 1,
- .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
-
- .max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
- .split_hdr_size = 0, /* Header split buffer size */
- },
- .rx_adv_conf = {
- .rss_conf = {
- .rss_key = NULL,
- .rss_key_len = 40,
- .rss_hf = 0,
- },
- },
- .txmode = {
- .mq_mode = ETH_MQ_TX_NONE,
- },
- .lpbk_mode = 0,
- },
-
- .promisc = 1,
-};
-
-static const struct app_pktq_hwq_in_params default_hwq_in_params = {
- .parsed = 0,
- .mempool_id = 0,
- .size = 128,
- .burst = 32,
-
- .conf = {
- .rx_thresh = {
- .pthresh = 8,
- .hthresh = 8,
- .wthresh = 4,
- },
- .rx_free_thresh = 64,
- .rx_drop_en = 0,
- .rx_deferred_start = 0,
- }
-};
-
-static const struct app_pktq_hwq_out_params default_hwq_out_params = {
- .parsed = 0,
- .size = 512,
- .burst = 32,
- .dropless = 0,
- .n_retries = 0,
-
- .conf = {
- .tx_thresh = {
- .pthresh = 36,
- .hthresh = 0,
- .wthresh = 0,
- },
- .tx_rs_thresh = 0,
- .tx_free_thresh = 0,
- .txq_flags = ETH_TXQ_FLAGS_IGNORE,
- .tx_deferred_start = 0,
- }
-};
-
-static const struct app_pktq_swq_params default_swq_params = {
- .parsed = 0,
- .size = 256,
- .burst_read = 32,
- .burst_write = 32,
- .dropless = 0,
- .n_retries = 0,
- .cpu_socket_id = 0,
- .ipv4_frag = 0,
- .ipv6_frag = 0,
- .ipv4_ras = 0,
- .ipv6_ras = 0,
- .mtu = 0,
- .metadata_size = 0,
- .mempool_direct_id = 0,
- .mempool_indirect_id = 0,
-};
-
-struct app_pktq_tm_params default_tm_params = {
- .parsed = 0,
- .file_name = "./config/tm_profile.cfg",
- .burst_read = 24,
- .burst_write = 32,
-};
-
-struct app_pktq_tap_params default_tap_params = {
- .parsed = 0,
- .burst_read = 32,
- .burst_write = 32,
- .dropless = 0,
- .n_retries = 0,
- .mempool_id = 0,
-};
-
-struct app_pktq_kni_params default_kni_params = {
- .parsed = 0,
- .socket_id = 0,
- .core_id = 0,
- .hyper_th_id = 0,
- .force_bind = 0,
-
- .mempool_id = 0,
- .burst_read = 32,
- .burst_write = 32,
- .dropless = 0,
- .n_retries = 0,
-};
-
-struct app_pktq_source_params default_source_params = {
- .parsed = 0,
- .mempool_id = 0,
- .burst = 32,
- .file_name = "./config/packets.pcap",
- .n_bytes_per_pkt = 0,
-};
-
-struct app_pktq_sink_params default_sink_params = {
- .parsed = 0,
- .file_name = NULL,
- .n_pkts_to_dump = 0,
-};
-
-struct app_msgq_params default_msgq_params = {
- .parsed = 0,
- .size = 64,
- .cpu_socket_id = 0,
-};
-
-struct app_pipeline_params default_pipeline_params = {
- .parsed = 0,
- .socket_id = 0,
- .core_id = 0,
- .hyper_th_id = 0,
- .n_pktq_in = 0,
- .n_pktq_out = 0,
- .n_msgq_in = 0,
- .n_msgq_out = 0,
- .timer_period = 1,
- .n_args = 0,
-};
-
-static const char app_usage[] =
- "Usage: %s [-f CONFIG_FILE] [-s SCRIPT_FILE] [-p PORT_MASK] "
- "[-l LOG_LEVEL] [--preproc PREPROCESSOR] [--preproc-args ARGS]\n"
- "\n"
- "Arguments:\n"
- "\t-f CONFIG_FILE: Default config file is %s\n"
- "\t-p PORT_MASK: Mask of NIC port IDs in hex format (generated from "
- "config file when not provided)\n"
- "\t-s SCRIPT_FILE: No CLI script file is run when not specified\n"
- "\t-l LOG_LEVEL: 0 = NONE, 1 = HIGH PRIO (default), 2 = LOW PRIO\n"
- "\t--preproc PREPROCESSOR: Configuration file pre-processor\n"
- "\t--preproc-args ARGS: Arguments to be passed to pre-processor\n"
- "\n";
-
-static void
-app_print_usage(char *prgname)
-{
- rte_exit(0, app_usage, prgname, app_params_default.config_file);
-}
-
-#define APP_PARAM_ADD(set, key) \
-({ \
- ssize_t pos = APP_PARAM_FIND(set, key); \
- ssize_t size = RTE_DIM(set); \
- \
- if (pos < 0) { \
- for (pos = 0; pos < size; pos++) { \
- if (!APP_PARAM_VALID(&((set)[pos]))) \
- break; \
- } \
- \
- APP_CHECK((pos < size), \
- "Parse error: size of %s is limited to %u elements",\
- #set, (uint32_t) size); \
- \
- (set)[pos].name = strdup(key); \
- APP_CHECK(((set)[pos].name), \
- "Parse error: no free memory"); \
- } \
- pos; \
-})
-
-#define APP_PARAM_ADD_LINK_FOR_RXQ(app, rxq_name) \
-({ \
- char link_name[APP_PARAM_NAME_SIZE]; \
- ssize_t link_param_pos; \
- uint32_t link_id, queue_id; \
- \
- sscanf((rxq_name), "RXQ%" SCNu32 ".%" SCNu32, &link_id, &queue_id);\
- sprintf(link_name, "LINK%" PRIu32, link_id); \
- link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
- link_param_pos; \
-})
-
-#define APP_PARAM_ADD_LINK_FOR_TXQ(app, txq_name) \
-({ \
- char link_name[APP_PARAM_NAME_SIZE]; \
- ssize_t link_param_pos; \
- uint32_t link_id, queue_id; \
- \
- sscanf((txq_name), "TXQ%" SCNu32 ".%" SCNu32, &link_id, &queue_id);\
- sprintf(link_name, "LINK%" PRIu32, link_id); \
- link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
- link_param_pos; \
-})
-
-#define APP_PARAM_ADD_LINK_FOR_TM(app, tm_name) \
-({ \
- char link_name[APP_PARAM_NAME_SIZE]; \
- ssize_t link_param_pos; \
- uint32_t link_id; \
- \
- sscanf((tm_name), "TM%" SCNu32, &link_id); \
- sprintf(link_name, "LINK%" PRIu32, link_id); \
- link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
- link_param_pos; \
-})
-
-#define APP_PARAM_ADD_LINK_FOR_KNI(app, kni_name) \
-({ \
- char link_name[APP_PARAM_NAME_SIZE]; \
- ssize_t link_param_pos; \
- uint32_t link_id; \
- \
- sscanf((kni_name), "KNI%" SCNu32, &link_id); \
- sprintf(link_name, "LINK%" PRIu32, link_id); \
- link_param_pos = APP_PARAM_ADD((app)->link_params, link_name); \
- link_param_pos; \
-})
-
-#define PARSE_CHECK_DUPLICATE_SECTION(obj) \
-do { \
- APP_CHECK(((obj)->parsed == 0), \
- "Parse error: duplicate \"%s\" section", (obj)->name); \
- (obj)->parsed++; \
-} while (0)
-
-#define PARSE_CHECK_DUPLICATE_SECTION_EAL(obj) \
-do { \
- APP_CHECK(((obj)->parsed == 0), \
- "Parse error: duplicate \"%s\" section", "EAL"); \
- (obj)->parsed++; \
-} while (0)
-
-#define PARSE_ERROR(exp, section, entry) \
-APP_CHECK(exp, "Parse error in section \"%s\": entry \"%s\"", section, entry)
-
-#define PARSE_ERROR_MESSAGE(exp, section, entry, message) \
-APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": %s", \
- section, entry, message)
-
-#define PARSE_ERROR_NO_ELEMENTS(exp, section, entry) \
-APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \
- "no elements detected", \
- section, entry)
-
-#define PARSE_ERROR_TOO_MANY_ELEMENTS(exp, section, entry, max) \
-APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \
- "maximum number of elements allowed is %u", \
- section, entry, max)
-
-#define PARSE_ERROR_INVALID_ELEMENT(exp, section, entry, value) \
-APP_CHECK(exp, "Parse error in section \"%s\", entry \"%s\": " \
- "Invalid element value \"%s\"", \
- section, entry, value)
-
-#define PARSE_ERROR_MALLOC(exp) \
-APP_CHECK(exp, "Parse error: no free memory")
-
-#define PARSE_ERROR_SECTION(exp, section) \
-APP_CHECK(exp, "Parse error in section \"%s\"", section)
-
-#define PARSE_ERROR_SECTION_NO_ENTRIES(exp, section) \
-APP_CHECK(exp, "Parse error in section \"%s\": no entries", section)
-
-#define PARSE_WARNING_IGNORED(exp, section, entry) \
-do \
-if (!(exp)) \
- fprintf(stderr, "Parse warning in section \"%s\": " \
- "entry \"%s\" is ignored", section, entry); \
-while (0)
-
-#define PARSE_ERROR_INVALID(exp, section, entry) \
-APP_CHECK(exp, "Parse error in section \"%s\": unrecognized entry \"%s\"",\
- section, entry)
-
-#define PARSE_ERROR_DUPLICATE(exp, section, entry) \
-APP_CHECK(exp, "Parse error in section \"%s\": duplicate entry \"%s\"", \
- section, entry)
-
-static int
-validate_name(const char *name, const char *prefix, int num)
-{
- size_t i, j;
-
- for (i = 0; (name[i] != '\0') && (prefix[i] != '\0'); i++) {
- if (name[i] != prefix[i])
- return -1;
- }
-
- if (prefix[i] != '\0')
- return -1;
-
- if (!num) {
- if (name[i] != '\0')
- return -1;
- else
- return 0;
- }
-
- if (num == 2) {
- j = skip_digits(&name[i]);
- i += j;
- if ((j == 0) || (name[i] != '.'))
- return -1;
- i++;
- }
-
- if (num == 1) {
- j = skip_digits(&name[i]);
- i += j;
- if ((j == 0) || (name[i] != '\0'))
- return -1;
- }
-
- return 0;
-}
-
-static void
-parse_eal(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_eal_params *p = &app->eal_params;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- PARSE_CHECK_DUPLICATE_SECTION_EAL(p);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *entry = &entries[i];
-
- /* coremask */
- if (strcmp(entry->name, "c") == 0) {
- PARSE_WARNING_IGNORED(0, section_name, entry->name);
- continue;
- }
-
- /* corelist */
- if (strcmp(entry->name, "l") == 0) {
- PARSE_WARNING_IGNORED(0, section_name, entry->name);
- continue;
- }
-
- /* coremap */
- if (strcmp(entry->name, "lcores") == 0) {
- PARSE_ERROR_DUPLICATE((p->coremap == NULL),
- section_name,
- entry->name);
- p->coremap = strdup(entry->value);
- continue;
- }
-
- /* master_lcore */
- if (strcmp(entry->name, "master_lcore") == 0) {
- int status;
-
- PARSE_ERROR_DUPLICATE((p->master_lcore_present == 0),
- section_name,
- entry->name);
- p->master_lcore_present = 1;
-
- status = parser_read_uint32(&p->master_lcore,
- entry->value);
- PARSE_ERROR((status == 0), section_name, entry->name);
- continue;
- }
-
- /* channels */
- if (strcmp(entry->name, "n") == 0) {
- int status;
-
- PARSE_ERROR_DUPLICATE((p->channels_present == 0),
- section_name,
- entry->name);
- p->channels_present = 1;
-
- status = parser_read_uint32(&p->channels, entry->value);
- PARSE_ERROR((status == 0), section_name, entry->name);
- continue;
- }
-
- /* memory */
- if (strcmp(entry->name, "m") == 0) {
- int status;
-
- PARSE_ERROR_DUPLICATE((p->memory_present == 0),
- section_name,
- entry->name);
- p->memory_present = 1;
-
- status = parser_read_uint32(&p->memory, entry->value);
- PARSE_ERROR((status == 0), section_name, entry->name);
- continue;
- }
-
- /* ranks */
- if (strcmp(entry->name, "r") == 0) {
- int status;
-
- PARSE_ERROR_DUPLICATE((p->ranks_present == 0),
- section_name,
- entry->name);
- p->ranks_present = 1;
-
- status = parser_read_uint32(&p->ranks, entry->value);
- PARSE_ERROR((status == 0), section_name, entry->name);
- continue;
- }
-
- /* pci_blacklist */
- if ((strcmp(entry->name, "pci_blacklist") == 0) ||
- (strcmp(entry->name, "b") == 0)) {
- uint32_t i;
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->pci_blacklist[i])
- continue;
-
- p->pci_blacklist[i] =
- strdup(entry->value);
- PARSE_ERROR_MALLOC(p->pci_blacklist[i]);
-
- break;
- }
-
- PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
- section_name, entry->name,
- "too many elements");
- continue;
- }
-
- /* pci_whitelist */
- if ((strcmp(entry->name, "pci_whitelist") == 0) ||
- (strcmp(entry->name, "w") == 0)) {
- uint32_t i;
-
- PARSE_ERROR_MESSAGE((app->port_mask != 0),
- section_name, entry->name, "entry to be "
- "generated by the application (port_mask "
- "not provided)");
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->pci_whitelist[i])
- continue;
-
- p->pci_whitelist[i] = strdup(entry->value);
- PARSE_ERROR_MALLOC(p->pci_whitelist[i]);
-
- break;
- }
-
- PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
- section_name, entry->name,
- "too many elements");
- continue;
- }
-
- /* vdev */
- if (strcmp(entry->name, "vdev") == 0) {
- uint32_t i;
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->vdev[i])
- continue;
-
- p->vdev[i] = strdup(entry->value);
- PARSE_ERROR_MALLOC(p->vdev[i]);
-
- break;
- }
-
- PARSE_ERROR_MESSAGE((i < APP_MAX_LINKS),
- section_name, entry->name,
- "too many elements");
- continue;
- }
-
- /* vmware_tsc_map */
- if (strcmp(entry->name, "vmware_tsc_map") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->vmware_tsc_map_present == 0),
- section_name,
- entry->name);
- p->vmware_tsc_map_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->vmware_tsc_map = val;
- continue;
- }
-
- /* proc_type */
- if (strcmp(entry->name, "proc_type") == 0) {
- PARSE_ERROR_DUPLICATE((p->proc_type == NULL),
- section_name,
- entry->name);
- p->proc_type = strdup(entry->value);
- continue;
- }
-
- /* syslog */
- if (strcmp(entry->name, "syslog") == 0) {
- PARSE_ERROR_DUPLICATE((p->syslog == NULL),
- section_name,
- entry->name);
- p->syslog = strdup(entry->value);
- continue;
- }
-
- /* log_level */
- if (strcmp(entry->name, "log_level") == 0) {
- int status;
-
- PARSE_ERROR_DUPLICATE((p->log_level_present == 0),
- section_name,
- entry->name);
- p->log_level_present = 1;
-
- status = parser_read_uint32(&p->log_level,
- entry->value);
- PARSE_ERROR((status == 0), section_name, entry->name);
- continue;
- }
-
- /* version */
- if (strcmp(entry->name, "v") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->version_present == 0),
- section_name,
- entry->name);
- p->version_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->version = val;
- continue;
- }
-
- /* help */
- if ((strcmp(entry->name, "help") == 0) ||
- (strcmp(entry->name, "h") == 0)) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->help_present == 0),
- section_name,
- entry->name);
- p->help_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->help = val;
- continue;
- }
-
- /* no_huge */
- if (strcmp(entry->name, "no_huge") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->no_huge_present == 0),
- section_name,
- entry->name);
- p->no_huge_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->no_huge = val;
- continue;
- }
-
- /* no_pci */
- if (strcmp(entry->name, "no_pci") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->no_pci_present == 0),
- section_name,
- entry->name);
- p->no_pci_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->no_pci = val;
- continue;
- }
-
- /* no_hpet */
- if (strcmp(entry->name, "no_hpet") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->no_hpet_present == 0),
- section_name,
- entry->name);
- p->no_hpet_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->no_hpet = val;
- continue;
- }
-
- /* no_shconf */
- if (strcmp(entry->name, "no_shconf") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->no_shconf_present == 0),
- section_name,
- entry->name);
- p->no_shconf_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->no_shconf = val;
- continue;
- }
-
- /* add_driver */
- if (strcmp(entry->name, "d") == 0) {
- PARSE_ERROR_DUPLICATE((p->add_driver == NULL),
- section_name,
- entry->name);
- p->add_driver = strdup(entry->value);
- continue;
- }
-
- /* socket_mem */
- if (strcmp(entry->name, "socket_mem") == 0) {
- PARSE_ERROR_DUPLICATE((p->socket_mem == NULL),
- section_name,
- entry->name);
- p->socket_mem = strdup(entry->value);
- continue;
- }
-
- /* huge_dir */
- if (strcmp(entry->name, "huge_dir") == 0) {
- PARSE_ERROR_DUPLICATE((p->huge_dir == NULL),
- section_name,
- entry->name);
- p->huge_dir = strdup(entry->value);
- continue;
- }
-
- /* file_prefix */
- if (strcmp(entry->name, "file_prefix") == 0) {
- PARSE_ERROR_DUPLICATE((p->file_prefix == NULL),
- section_name,
- entry->name);
- p->file_prefix = strdup(entry->value);
- continue;
- }
-
- /* base_virtaddr */
- if (strcmp(entry->name, "base_virtaddr") == 0) {
- PARSE_ERROR_DUPLICATE((p->base_virtaddr == NULL),
- section_name,
- entry->name);
- p->base_virtaddr = strdup(entry->value);
- continue;
- }
-
- /* create_uio_dev */
- if (strcmp(entry->name, "create_uio_dev") == 0) {
- int val;
-
- PARSE_ERROR_DUPLICATE((p->create_uio_dev_present == 0),
- section_name,
- entry->name);
- p->create_uio_dev_present = 1;
-
- val = parser_read_arg_bool(entry->value);
- PARSE_ERROR((val >= 0), section_name, entry->name);
- p->create_uio_dev = val;
- continue;
- }
-
- /* vfio_intr */
- if (strcmp(entry->name, "vfio_intr") == 0) {
- PARSE_ERROR_DUPLICATE((p->vfio_intr == NULL),
- section_name,
- entry->name);
- p->vfio_intr = strdup(entry->value);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, entry->name);
- }
-
- free(entries);
-}
-
-static void
-parse_pipeline_pktq_in(struct app_params *app,
- struct app_pipeline_params *p,
- char *value)
-{
- p->n_pktq_in = 0;
-
- while (1) {
- enum app_pktq_in_type type;
- int id;
- char *name = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (name == NULL)
- break;
-
- PARSE_ERROR_TOO_MANY_ELEMENTS(
- (p->n_pktq_in < RTE_DIM(p->pktq_in)),
- p->name, "pktq_in", (uint32_t)RTE_DIM(p->pktq_in));
-
- if (validate_name(name, "RXQ", 2) == 0) {
- type = APP_PKTQ_IN_HWQ;
- id = APP_PARAM_ADD(app->hwq_in_params, name);
- APP_PARAM_ADD_LINK_FOR_RXQ(app, name);
- } else if (validate_name(name, "SWQ", 1) == 0) {
- type = APP_PKTQ_IN_SWQ;
- id = APP_PARAM_ADD(app->swq_params, name);
- } else if (validate_name(name, "TM", 1) == 0) {
- type = APP_PKTQ_IN_TM;
- id = APP_PARAM_ADD(app->tm_params, name);
- APP_PARAM_ADD_LINK_FOR_TM(app, name);
- } else if (validate_name(name, "TAP", 1) == 0) {
- type = APP_PKTQ_IN_TAP;
- id = APP_PARAM_ADD(app->tap_params, name);
- } else if (validate_name(name, "KNI", 1) == 0) {
- type = APP_PKTQ_IN_KNI;
- id = APP_PARAM_ADD(app->kni_params, name);
- APP_PARAM_ADD_LINK_FOR_KNI(app, name);
- } else if (validate_name(name, "SOURCE", 1) == 0) {
- type = APP_PKTQ_IN_SOURCE;
- id = APP_PARAM_ADD(app->source_params, name);
- } else
- PARSE_ERROR_INVALID_ELEMENT(0,
- p->name, "pktq_in", name);
-
- p->pktq_in[p->n_pktq_in].type = type;
- p->pktq_in[p->n_pktq_in].id = (uint32_t) id;
- p->n_pktq_in++;
- }
-
- PARSE_ERROR_NO_ELEMENTS((p->n_pktq_in > 0), p->name, "pktq_in");
-}
-
-static void
-parse_pipeline_pktq_out(struct app_params *app,
- struct app_pipeline_params *p,
- char *value)
-{
- p->n_pktq_out = 0;
-
- while (1) {
- enum app_pktq_out_type type;
- int id;
- char *name = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (name == NULL)
- break;
-
- PARSE_ERROR_TOO_MANY_ELEMENTS(
- (p->n_pktq_out < RTE_DIM(p->pktq_out)),
- p->name, "pktq_out", (uint32_t)RTE_DIM(p->pktq_out));
-
- if (validate_name(name, "TXQ", 2) == 0) {
- type = APP_PKTQ_OUT_HWQ;
- id = APP_PARAM_ADD(app->hwq_out_params, name);
- APP_PARAM_ADD_LINK_FOR_TXQ(app, name);
- } else if (validate_name(name, "SWQ", 1) == 0) {
- type = APP_PKTQ_OUT_SWQ;
- id = APP_PARAM_ADD(app->swq_params, name);
- } else if (validate_name(name, "TM", 1) == 0) {
- type = APP_PKTQ_OUT_TM;
- id = APP_PARAM_ADD(app->tm_params, name);
- APP_PARAM_ADD_LINK_FOR_TM(app, name);
- } else if (validate_name(name, "TAP", 1) == 0) {
- type = APP_PKTQ_OUT_TAP;
- id = APP_PARAM_ADD(app->tap_params, name);
- } else if (validate_name(name, "KNI", 1) == 0) {
- type = APP_PKTQ_OUT_KNI;
- id = APP_PARAM_ADD(app->kni_params, name);
- APP_PARAM_ADD_LINK_FOR_KNI(app, name);
- } else if (validate_name(name, "SINK", 1) == 0) {
- type = APP_PKTQ_OUT_SINK;
- id = APP_PARAM_ADD(app->sink_params, name);
- } else
- PARSE_ERROR_INVALID_ELEMENT(0,
- p->name, "pktq_out", name);
-
- p->pktq_out[p->n_pktq_out].type = type;
- p->pktq_out[p->n_pktq_out].id = id;
- p->n_pktq_out++;
- }
-
- PARSE_ERROR_NO_ELEMENTS((p->n_pktq_out > 0), p->name, "pktq_out");
-}
-
-static void
-parse_pipeline_msgq_in(struct app_params *app,
- struct app_pipeline_params *p,
- char *value)
-{
- p->n_msgq_in = 0;
-
- while (1) {
- int idx;
- char *name = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (name == NULL)
- break;
-
- PARSE_ERROR_TOO_MANY_ELEMENTS(
- (p->n_msgq_in < RTE_DIM(p->msgq_in)),
- p->name, "msgq_in", (uint32_t)(RTE_DIM(p->msgq_in)));
-
- PARSE_ERROR_INVALID_ELEMENT(
- (validate_name(name, "MSGQ", 1) == 0),
- p->name, "msgq_in", name);
-
- idx = APP_PARAM_ADD(app->msgq_params, name);
- p->msgq_in[p->n_msgq_in] = idx;
- p->n_msgq_in++;
- }
-
- PARSE_ERROR_NO_ELEMENTS((p->n_msgq_in > 0), p->name, "msgq_in");
-}
-
-static void
-parse_pipeline_msgq_out(struct app_params *app,
- struct app_pipeline_params *p,
- char *value)
-{
- p->n_msgq_out = 0;
-
- while (1) {
- int idx;
- char *name = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (name == NULL)
- break;
-
- PARSE_ERROR_TOO_MANY_ELEMENTS(
- (p->n_msgq_out < RTE_DIM(p->msgq_out)),
- p->name, "msgq_out", (uint32_t)RTE_DIM(p->msgq_out));
-
- PARSE_ERROR_INVALID_ELEMENT(
- (validate_name(name, "MSGQ", 1) == 0),
- p->name, "msgq_out", name);
-
- idx = APP_PARAM_ADD(app->msgq_params, name);
- p->msgq_out[p->n_msgq_out] = idx;
- p->n_msgq_out++;
- }
-
- PARSE_ERROR_NO_ELEMENTS((p->n_msgq_out > 0), p->name, "msgq_out");
-}
-
-static void
-parse_pipeline(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- char name[CFG_NAME_LEN];
- struct app_pipeline_params *param;
- struct rte_cfgfile_entry *entries;
- ssize_t param_idx;
- int n_entries, i;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->pipeline_params, section_name);
- param = &app->pipeline_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "type") == 0) {
- int w_size = snprintf(param->type, RTE_DIM(param->type),
- "%s", ent->value);
-
- PARSE_ERROR(((w_size > 0) &&
- (w_size < (int)RTE_DIM(param->type))),
- section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "core") == 0) {
- int status = parse_pipeline_core(
- &param->socket_id, &param->core_id,
- &param->hyper_th_id, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "pktq_in") == 0) {
- parse_pipeline_pktq_in(app, param, ent->value);
-
- continue;
- }
-
- if (strcmp(ent->name, "pktq_out") == 0) {
- parse_pipeline_pktq_out(app, param, ent->value);
-
- continue;
- }
-
- if (strcmp(ent->name, "msgq_in") == 0) {
- parse_pipeline_msgq_in(app, param, ent->value);
-
- continue;
- }
-
- if (strcmp(ent->name, "msgq_out") == 0) {
- parse_pipeline_msgq_out(app, param, ent->value);
-
- continue;
- }
-
- if (strcmp(ent->name, "timer_period") == 0) {
- int status = parser_read_uint32(
- &param->timer_period,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* pipeline type specific items */
- APP_CHECK((param->n_args < APP_MAX_PIPELINE_ARGS),
- "Parse error in section \"%s\": too many "
- "pipeline specified parameters", section_name);
-
- param->args_name[param->n_args] = strdup(ent->name);
- param->args_value[param->n_args] = strdup(ent->value);
-
- APP_CHECK((param->args_name[param->n_args] != NULL) &&
- (param->args_value[param->n_args] != NULL),
- "Parse error: no free memory");
-
- param->n_args++;
- }
-
- snprintf(name, sizeof(name), "MSGQ-REQ-%s", section_name);
- param_idx = APP_PARAM_ADD(app->msgq_params, name);
- app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
- param->msgq_in[param->n_msgq_in++] = param_idx;
-
- snprintf(name, sizeof(name), "MSGQ-RSP-%s", section_name);
- param_idx = APP_PARAM_ADD(app->msgq_params, name);
- app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
- param->msgq_out[param->n_msgq_out++] = param_idx;
-
- snprintf(name, sizeof(name), "MSGQ-REQ-CORE-s%" PRIu32 "c%" PRIu32 "%s",
- param->socket_id,
- param->core_id,
- (param->hyper_th_id) ? "h" : "");
- param_idx = APP_PARAM_ADD(app->msgq_params, name);
- app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
-
- snprintf(name, sizeof(name), "MSGQ-RSP-CORE-s%" PRIu32 "c%" PRIu32 "%s",
- param->socket_id,
- param->core_id,
- (param->hyper_th_id) ? "h" : "");
- param_idx = APP_PARAM_ADD(app->msgq_params, name);
- app->msgq_params[param_idx].cpu_socket_id = param->socket_id;
-
- free(entries);
-}
-
-static void
-parse_mempool(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_mempool_params *param;
- struct rte_cfgfile_entry *entries;
- ssize_t param_idx;
- int n_entries, i;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->mempool_params, section_name);
- param = &app->mempool_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "buffer_size") == 0) {
- int status = parser_read_uint32(
- &param->buffer_size, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "pool_size") == 0) {
- int status = parser_read_uint32(
- &param->pool_size, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "cache_size") == 0) {
- int status = parser_read_uint32(
- &param->cache_size, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "cpu") == 0) {
- int status = parser_read_uint32(
- &param->cpu_socket_id, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static int
-parse_link_rss_qs(struct app_link_params *p,
- char *value)
-{
- p->n_rss_qs = 0;
-
- while (1) {
- char *token = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (token == NULL)
- break;
-
- if (p->n_rss_qs == RTE_DIM(p->rss_qs))
- return -ENOMEM;
-
- if (parser_read_uint32(&p->rss_qs[p->n_rss_qs++], token))
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int
-parse_link_rss_proto_ipv4(struct app_link_params *p,
- char *value)
-{
- uint64_t mask = 0;
-
- while (1) {
- char *token = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (token == NULL)
- break;
-
- if (strcmp(token, "IP") == 0) {
- mask |= ETH_RSS_IPV4;
- continue;
- }
- if (strcmp(token, "FRAG") == 0) {
- mask |= ETH_RSS_FRAG_IPV4;
- continue;
- }
- if (strcmp(token, "TCP") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV4_TCP;
- continue;
- }
- if (strcmp(token, "UDP") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV4_UDP;
- continue;
- }
- if (strcmp(token, "SCTP") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV4_SCTP;
- continue;
- }
- if (strcmp(token, "OTHER") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV4_OTHER;
- continue;
- }
- return -EINVAL;
- }
-
- p->rss_proto_ipv4 = mask;
- return 0;
-}
-
-static int
-parse_link_rss_proto_ipv6(struct app_link_params *p,
- char *value)
-{
- uint64_t mask = 0;
-
- while (1) {
- char *token = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (token == NULL)
- break;
-
- if (strcmp(token, "IP") == 0) {
- mask |= ETH_RSS_IPV6;
- continue;
- }
- if (strcmp(token, "FRAG") == 0) {
- mask |= ETH_RSS_FRAG_IPV6;
- continue;
- }
- if (strcmp(token, "TCP") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV6_TCP;
- continue;
- }
- if (strcmp(token, "UDP") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV6_UDP;
- continue;
- }
- if (strcmp(token, "SCTP") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV6_SCTP;
- continue;
- }
- if (strcmp(token, "OTHER") == 0) {
- mask |= ETH_RSS_NONFRAG_IPV6_OTHER;
- continue;
- }
- if (strcmp(token, "IP_EX") == 0) {
- mask |= ETH_RSS_IPV6_EX;
- continue;
- }
- if (strcmp(token, "TCP_EX") == 0) {
- mask |= ETH_RSS_IPV6_TCP_EX;
- continue;
- }
- if (strcmp(token, "UDP_EX") == 0) {
- mask |= ETH_RSS_IPV6_UDP_EX;
- continue;
- }
- return -EINVAL;
- }
-
- p->rss_proto_ipv6 = mask;
- return 0;
-}
-
-static int
-parse_link_rss_proto_l2(struct app_link_params *p,
- char *value)
-{
- uint64_t mask = 0;
-
- while (1) {
- char *token = strtok_r(value, PARSE_DELIMITER, &value);
-
- if (token == NULL)
- break;
-
- if (strcmp(token, "L2") == 0) {
- mask |= ETH_RSS_L2_PAYLOAD;
- continue;
- }
- return -EINVAL;
- }
-
- p->rss_proto_l2 = mask;
- return 0;
-}
-
-static void
-parse_link(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_link_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- int rss_qs_present = 0;
- int rss_proto_ipv4_present = 0;
- int rss_proto_ipv6_present = 0;
- int rss_proto_l2_present = 0;
- int pci_bdf_present = 0;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->link_params, section_name);
- param = &app->link_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "promisc") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->promisc = status;
- continue;
- }
-
- if (strcmp(ent->name, "arp_q") == 0) {
- int status = parser_read_uint32(&param->arp_q,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "tcp_syn_q") == 0) {
- int status = parser_read_uint32(
- &param->tcp_syn_q, ent->value);
-
- PARSE_ERROR((status == 0), section_name, ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "ip_local_q") == 0) {
- int status = parser_read_uint32(
- &param->ip_local_q, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "tcp_local_q") == 0) {
- int status = parser_read_uint32(
- &param->tcp_local_q, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "udp_local_q") == 0) {
- int status = parser_read_uint32(
- &param->udp_local_q, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "sctp_local_q") == 0) {
- int status = parser_read_uint32(
- &param->sctp_local_q, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "rss_qs") == 0) {
- int status = parse_link_rss_qs(param, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- rss_qs_present = 1;
- continue;
- }
-
- if (strcmp(ent->name, "rss_proto_ipv4") == 0) {
- int status =
- parse_link_rss_proto_ipv4(param, ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- rss_proto_ipv4_present = 1;
- continue;
- }
-
- if (strcmp(ent->name, "rss_proto_ipv6") == 0) {
- int status =
- parse_link_rss_proto_ipv6(param, ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- rss_proto_ipv6_present = 1;
- continue;
- }
-
- if (strcmp(ent->name, "rss_proto_l2") == 0) {
- int status = parse_link_rss_proto_l2(param, ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- rss_proto_l2_present = 1;
- continue;
- }
-
- if (strcmp(ent->name, "pci_bdf") == 0) {
- PARSE_ERROR_DUPLICATE((pci_bdf_present == 0),
- section_name, ent->name);
-
- snprintf(param->pci_bdf, APP_LINK_PCI_BDF_SIZE,
- "%s", ent->value);
- pci_bdf_present = 1;
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- /* Check for mandatory fields */
- if (app->port_mask)
- PARSE_ERROR_MESSAGE((pci_bdf_present == 0),
- section_name, "pci_bdf",
- "entry not allowed (port_mask is provided)");
- else
- PARSE_ERROR_MESSAGE((pci_bdf_present),
- section_name, "pci_bdf",
- "this entry is mandatory (port_mask is not "
- "provided)");
-
- if (rss_proto_ipv4_present)
- PARSE_ERROR_MESSAGE((rss_qs_present),
- section_name, "rss_proto_ipv4",
- "entry not allowed (rss_qs entry is not provided)");
- if (rss_proto_ipv6_present)
- PARSE_ERROR_MESSAGE((rss_qs_present),
- section_name, "rss_proto_ipv6",
- "entry not allowed (rss_qs entry is not provided)");
- if (rss_proto_l2_present)
- PARSE_ERROR_MESSAGE((rss_qs_present),
- section_name, "rss_proto_l2",
- "entry not allowed (rss_qs entry is not provided)");
- if (rss_proto_ipv4_present |
- rss_proto_ipv6_present |
- rss_proto_l2_present){
- if (rss_proto_ipv4_present == 0)
- param->rss_proto_ipv4 = 0;
- if (rss_proto_ipv6_present == 0)
- param->rss_proto_ipv6 = 0;
- if (rss_proto_l2_present == 0)
- param->rss_proto_l2 = 0;
- }
-
- free(entries);
-}
-
-static void
-parse_rxq(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_hwq_in_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->hwq_in_params, section_name);
- param = &app->hwq_in_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- APP_PARAM_ADD_LINK_FOR_RXQ(app, section_name);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "mempool") == 0) {
- int status = validate_name(ent->value,
- "MEMPOOL", 1);
- ssize_t idx;
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
-
- idx = APP_PARAM_ADD(app->mempool_params, ent->value);
- param->mempool_id = idx;
- continue;
- }
-
- if (strcmp(ent->name, "size") == 0) {
- int status = parser_read_uint32(&param->size,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "burst") == 0) {
- int status = parser_read_uint32(&param->burst,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_txq(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_hwq_out_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->hwq_out_params, section_name);
- param = &app->hwq_out_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- APP_PARAM_ADD_LINK_FOR_TXQ(app, section_name);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "size") == 0) {
- int status = parser_read_uint32(&param->size,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "burst") == 0) {
- int status = parser_read_uint32(&param->burst,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "dropless") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->dropless = status;
- continue;
- }
-
- if (strcmp(ent->name, "n_retries") == 0) {
- int status = parser_read_uint64(&param->n_retries,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_swq(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_swq_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- uint32_t mtu_present = 0;
- uint32_t metadata_size_present = 0;
- uint32_t mempool_direct_present = 0;
- uint32_t mempool_indirect_present = 0;
-
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->swq_params, section_name);
- param = &app->swq_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "size") == 0) {
- int status = parser_read_uint32(&param->size,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "burst_read") == 0) {
- int status = parser_read_uint32(&
- param->burst_read, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "burst_write") == 0) {
- int status = parser_read_uint32(
- &param->burst_write, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "dropless") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->dropless = status;
- continue;
- }
-
- if (strcmp(ent->name, "n_retries") == 0) {
- int status = parser_read_uint64(&param->n_retries,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "cpu") == 0) {
- int status = parser_read_uint32(
- &param->cpu_socket_id, ent->value);
-
- PARSE_ERROR((status == 0), section_name, ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "ipv4_frag") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
-
- param->ipv4_frag = status;
- if (param->mtu == 0)
- param->mtu = 1500;
-
- continue;
- }
-
- if (strcmp(ent->name, "ipv6_frag") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->ipv6_frag = status;
- if (param->mtu == 0)
- param->mtu = 1320;
- continue;
- }
-
- if (strcmp(ent->name, "ipv4_ras") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->ipv4_ras = status;
- continue;
- }
-
- if (strcmp(ent->name, "ipv6_ras") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->ipv6_ras = status;
- continue;
- }
-
- if (strcmp(ent->name, "mtu") == 0) {
- int status = parser_read_uint32(&param->mtu,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- mtu_present = 1;
- continue;
- }
-
- if (strcmp(ent->name, "metadata_size") == 0) {
- int status = parser_read_uint32(
- &param->metadata_size, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- metadata_size_present = 1;
- continue;
- }
-
- if (strcmp(ent->name, "mempool_direct") == 0) {
- int status = validate_name(ent->value,
- "MEMPOOL", 1);
- ssize_t idx;
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
-
- idx = APP_PARAM_ADD(app->mempool_params, ent->value);
- param->mempool_direct_id = idx;
-
- mempool_direct_present = 1;
- continue;
- }
-
- if (strcmp(ent->name, "mempool_indirect") == 0) {
- int status = validate_name(ent->value,
- "MEMPOOL", 1);
- ssize_t idx;
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
-
- idx = APP_PARAM_ADD(app->mempool_params, ent->value);
- param->mempool_indirect_id = idx;
-
- mempool_indirect_present = 1;
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- APP_CHECK(((mtu_present == 0) ||
- ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
- "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
- "is off, therefore entry \"mtu\" is not allowed",
- section_name);
-
- APP_CHECK(((metadata_size_present == 0) ||
- ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
- "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
- "is off, therefore entry \"metadata_size\" is "
- "not allowed", section_name);
-
- APP_CHECK(((mempool_direct_present == 0) ||
- ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
- "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
- "is off, therefore entry \"mempool_direct\" is "
- "not allowed", section_name);
-
- APP_CHECK(((mempool_indirect_present == 0) ||
- ((param->ipv4_frag == 1) || (param->ipv6_frag == 1))),
- "Parse error in section \"%s\": IPv4/IPv6 fragmentation "
- "is off, therefore entry \"mempool_indirect\" is "
- "not allowed", section_name);
-
- free(entries);
-}
-
-static void
-parse_tm(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_tm_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->tm_params, section_name);
- param = &app->tm_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- APP_PARAM_ADD_LINK_FOR_TM(app, section_name);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "cfg") == 0) {
- param->file_name = strdup(ent->value);
- PARSE_ERROR_MALLOC(param->file_name != NULL);
- continue;
- }
-
- if (strcmp(ent->name, "burst_read") == 0) {
- int status = parser_read_uint32(
- &param->burst_read, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "burst_write") == 0) {
- int status = parser_read_uint32(
- &param->burst_write, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_tap(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_tap_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->tap_params, section_name);
- param = &app->tap_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "burst_read") == 0) {
- int status = parser_read_uint32(
- &param->burst_read, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "burst_write") == 0) {
- int status = parser_read_uint32(
- &param->burst_write, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "dropless") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->dropless = status;
- continue;
- }
-
- if (strcmp(ent->name, "n_retries") == 0) {
- int status = parser_read_uint64(&param->n_retries,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "mempool") == 0) {
- int status = validate_name(ent->value,
- "MEMPOOL", 1);
- ssize_t idx;
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
-
- idx = APP_PARAM_ADD(app->mempool_params, ent->value);
- param->mempool_id = idx;
-
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_kni(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_kni_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->kni_params, section_name);
- param = &app->kni_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- APP_PARAM_ADD_LINK_FOR_KNI(app, section_name);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "core") == 0) {
- int status = parse_pipeline_core(
- &param->socket_id,
- &param->core_id,
- &param->hyper_th_id,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- param->force_bind = 1;
- continue;
- }
-
- if (strcmp(ent->name, "mempool") == 0) {
- int status = validate_name(ent->value,
- "MEMPOOL", 1);
- ssize_t idx;
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
-
- idx = APP_PARAM_ADD(app->mempool_params, ent->value);
- param->mempool_id = idx;
- continue;
- }
-
- if (strcmp(ent->name, "burst_read") == 0) {
- int status = parser_read_uint32(&param->burst_read,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "burst_write") == 0) {
- int status = parser_read_uint32(&param->burst_write,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "dropless") == 0) {
- int status = parser_read_arg_bool(ent->value);
-
- PARSE_ERROR((status != -EINVAL), section_name,
- ent->name);
- param->dropless = status;
- continue;
- }
-
- if (strcmp(ent->name, "n_retries") == 0) {
- int status = parser_read_uint64(&param->n_retries,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_source(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_source_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
- uint32_t pcap_file_present = 0;
- uint32_t pcap_size_present = 0;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->source_params, section_name);
- param = &app->source_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "mempool") == 0) {
- int status = validate_name(ent->value,
- "MEMPOOL", 1);
- ssize_t idx;
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
-
- idx = APP_PARAM_ADD(app->mempool_params, ent->value);
- param->mempool_id = idx;
- continue;
- }
-
- if (strcmp(ent->name, "burst") == 0) {
- int status = parser_read_uint32(&param->burst,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "pcap_file_rd") == 0) {
- PARSE_ERROR_DUPLICATE((pcap_file_present == 0),
- section_name, ent->name);
-
- param->file_name = strdup(ent->value);
-
- PARSE_ERROR_MALLOC(param->file_name != NULL);
- pcap_file_present = 1;
-
- continue;
- }
-
- if (strcmp(ent->name, "pcap_bytes_rd_per_pkt") == 0) {
- int status;
-
- PARSE_ERROR_DUPLICATE((pcap_size_present == 0),
- section_name, ent->name);
-
- status = parser_read_uint32(
- &param->n_bytes_per_pkt, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- pcap_size_present = 1;
-
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_sink(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_pktq_sink_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
- uint32_t pcap_file_present = 0;
- uint32_t pcap_n_pkt_present = 0;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->sink_params, section_name);
- param = &app->sink_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "pcap_file_wr") == 0) {
- PARSE_ERROR_DUPLICATE((pcap_file_present == 0),
- section_name, ent->name);
-
- param->file_name = strdup(ent->value);
-
- PARSE_ERROR_MALLOC((param->file_name != NULL));
-
- continue;
- }
-
- if (strcmp(ent->name, "pcap_n_pkt_wr") == 0) {
- int status;
-
- PARSE_ERROR_DUPLICATE((pcap_n_pkt_present == 0),
- section_name, ent->name);
-
- status = parser_read_uint32(
- &param->n_pkts_to_dump, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
-
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_msgq_req_pipeline(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_msgq_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
- param = &app->msgq_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "size") == 0) {
- int status = parser_read_uint32(&param->size,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_msgq_rsp_pipeline(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_msgq_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
- param = &app->msgq_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "size") == 0) {
- int status = parser_read_uint32(&param->size,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-static void
-parse_msgq(struct app_params *app,
- const char *section_name,
- struct rte_cfgfile *cfg)
-{
- struct app_msgq_params *param;
- struct rte_cfgfile_entry *entries;
- int n_entries, i;
- ssize_t param_idx;
-
- n_entries = rte_cfgfile_section_num_entries(cfg, section_name);
- PARSE_ERROR_SECTION_NO_ENTRIES((n_entries > 0), section_name);
-
- entries = malloc(n_entries * sizeof(struct rte_cfgfile_entry));
- PARSE_ERROR_MALLOC(entries != NULL);
-
- rte_cfgfile_section_entries(cfg, section_name, entries, n_entries);
-
- param_idx = APP_PARAM_ADD(app->msgq_params, section_name);
- param = &app->msgq_params[param_idx];
- PARSE_CHECK_DUPLICATE_SECTION(param);
-
- for (i = 0; i < n_entries; i++) {
- struct rte_cfgfile_entry *ent = &entries[i];
-
- if (strcmp(ent->name, "size") == 0) {
- int status = parser_read_uint32(&param->size,
- ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- if (strcmp(ent->name, "cpu") == 0) {
- int status = parser_read_uint32(
- &param->cpu_socket_id, ent->value);
-
- PARSE_ERROR((status == 0), section_name,
- ent->name);
- continue;
- }
-
- /* unrecognized */
- PARSE_ERROR_INVALID(0, section_name, ent->name);
- }
-
- free(entries);
-}
-
-typedef void (*config_section_load)(struct app_params *p,
- const char *section_name,
- struct rte_cfgfile *cfg);
-
-struct config_section {
- const char prefix[CFG_NAME_LEN];
- int numbers;
- config_section_load load;
-};
-
-static const struct config_section cfg_file_scheme[] = {
- {"EAL", 0, parse_eal},
- {"PIPELINE", 1, parse_pipeline},
- {"MEMPOOL", 1, parse_mempool},
- {"LINK", 1, parse_link},
- {"RXQ", 2, parse_rxq},
- {"TXQ", 2, parse_txq},
- {"SWQ", 1, parse_swq},
- {"TM", 1, parse_tm},
- {"TAP", 1, parse_tap},
- {"KNI", 1, parse_kni},
- {"SOURCE", 1, parse_source},
- {"SINK", 1, parse_sink},
- {"MSGQ-REQ-PIPELINE", 1, parse_msgq_req_pipeline},
- {"MSGQ-RSP-PIPELINE", 1, parse_msgq_rsp_pipeline},
- {"MSGQ", 1, parse_msgq},
-};
-
-static void
-create_implicit_mempools(struct app_params *app)
-{
- APP_PARAM_ADD(app->mempool_params, "MEMPOOL0");
-}
-
-static void
-create_implicit_links_from_port_mask(struct app_params *app,
- uint64_t port_mask)
-{
- uint32_t pmd_id, link_id;
-
- link_id = 0;
- for (pmd_id = 0; pmd_id < RTE_MAX_ETHPORTS; pmd_id++) {
- char name[APP_PARAM_NAME_SIZE];
- ssize_t idx;
-
- if ((port_mask & (1LLU << pmd_id)) == 0)
- continue;
-
- snprintf(name, sizeof(name), "LINK%" PRIu32, link_id);
- idx = APP_PARAM_ADD(app->link_params, name);
-
- app->link_params[idx].pmd_id = pmd_id;
- link_id++;
- }
-}
-
-static void
-assign_link_pmd_id_from_pci_bdf(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *link = &app->link_params[i];
-
- APP_CHECK((strlen(link->pci_bdf)),
- "Parse error: %s pci_bdf is not configured "
- "(port_mask is not provided)",
- link->name);
-
- link->pmd_id = i;
- }
-}
-
-int
-app_config_parse(struct app_params *app, const char *file_name)
-{
- struct rte_cfgfile *cfg;
- char **section_names;
- int i, j, sect_count;
-
- /* Implicit mempools */
- create_implicit_mempools(app);
-
- /* Port mask */
- if (app->port_mask)
- create_implicit_links_from_port_mask(app, app->port_mask);
-
- /* Load application configuration file */
- cfg = rte_cfgfile_load(file_name, 0);
- APP_CHECK((cfg != NULL), "Parse error: Unable to load config "
- "file %s", file_name);
-
- sect_count = rte_cfgfile_num_sections(cfg, NULL, 0);
- APP_CHECK((sect_count > 0), "Parse error: number of sections "
- "in file \"%s\" return %d", file_name,
- sect_count);
-
- section_names = malloc(sect_count * sizeof(char *));
- PARSE_ERROR_MALLOC(section_names != NULL);
-
- for (i = 0; i < sect_count; i++)
- section_names[i] = malloc(CFG_NAME_LEN);
-
- rte_cfgfile_sections(cfg, section_names, sect_count);
-
- for (i = 0; i < sect_count; i++) {
- const struct config_section *sch_s;
- int len, cfg_name_len;
-
- cfg_name_len = strlen(section_names[i]);
-
- /* Find section type */
- for (j = 0; j < (int)RTE_DIM(cfg_file_scheme); j++) {
- sch_s = &cfg_file_scheme[j];
- len = strlen(sch_s->prefix);
-
- if (cfg_name_len < len)
- continue;
-
- /* After section name we expect only '\0' or digit or
- * digit dot digit, so protect against false matching,
- * for example: "ABC" should match section name
- * "ABC0.0", but it should not match section_name
- * "ABCDEF".
- */
- if ((section_names[i][len] != '\0') &&
- !isdigit(section_names[i][len]))
- continue;
-
- if (strncmp(sch_s->prefix, section_names[i], len) == 0)
- break;
- }
-
- APP_CHECK(j < (int)RTE_DIM(cfg_file_scheme),
- "Parse error: unknown section %s",
- section_names[i]);
-
- APP_CHECK(validate_name(section_names[i],
- sch_s->prefix,
- sch_s->numbers) == 0,
- "Parse error: invalid section name \"%s\"",
- section_names[i]);
-
- sch_s->load(app, section_names[i], cfg);
- }
-
- for (i = 0; i < sect_count; i++)
- free(section_names[i]);
-
- free(section_names);
-
- rte_cfgfile_close(cfg);
-
- APP_PARAM_COUNT(app->mempool_params, app->n_mempools);
- APP_PARAM_COUNT(app->link_params, app->n_links);
- APP_PARAM_COUNT(app->hwq_in_params, app->n_pktq_hwq_in);
- APP_PARAM_COUNT(app->hwq_out_params, app->n_pktq_hwq_out);
- APP_PARAM_COUNT(app->swq_params, app->n_pktq_swq);
- APP_PARAM_COUNT(app->tm_params, app->n_pktq_tm);
- APP_PARAM_COUNT(app->tap_params, app->n_pktq_tap);
- APP_PARAM_COUNT(app->kni_params, app->n_pktq_kni);
- APP_PARAM_COUNT(app->source_params, app->n_pktq_source);
- APP_PARAM_COUNT(app->sink_params, app->n_pktq_sink);
- APP_PARAM_COUNT(app->msgq_params, app->n_msgq);
- APP_PARAM_COUNT(app->pipeline_params, app->n_pipelines);
-
- if (app->port_mask == 0)
- assign_link_pmd_id_from_pci_bdf(app);
-
- /* Save configuration to output file */
- app_config_save(app, app->output_file);
-
- /* Load TM configuration files */
- app_config_parse_tm(app);
-
- return 0;
-}
-
-static void
-save_eal_params(struct app_params *app, FILE *f)
-{
- struct app_eal_params *p = &app->eal_params;
- uint32_t i;
-
- fprintf(f, "[EAL]\n");
-
- if (p->coremap)
- fprintf(f, "%s = %s\n", "lcores", p->coremap);
-
- if (p->master_lcore_present)
- fprintf(f, "%s = %" PRIu32 "\n",
- "master_lcore", p->master_lcore);
-
- fprintf(f, "%s = %" PRIu32 "\n", "n", p->channels);
-
- if (p->memory_present)
- fprintf(f, "%s = %" PRIu32 "\n", "m", p->memory);
-
- if (p->ranks_present)
- fprintf(f, "%s = %" PRIu32 "\n", "r", p->ranks);
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->pci_blacklist[i] == NULL)
- break;
-
- fprintf(f, "%s = %s\n", "pci_blacklist",
- p->pci_blacklist[i]);
- }
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->pci_whitelist[i] == NULL)
- break;
-
- fprintf(f, "%s = %s\n", "pci_whitelist",
- p->pci_whitelist[i]);
- }
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->vdev[i] == NULL)
- break;
-
- fprintf(f, "%s = %s\n", "vdev",
- p->vdev[i]);
- }
-
- if (p->vmware_tsc_map_present)
- fprintf(f, "%s = %s\n", "vmware_tsc_map",
- (p->vmware_tsc_map) ? "yes" : "no");
-
- if (p->proc_type)
- fprintf(f, "%s = %s\n", "proc_type", p->proc_type);
-
- if (p->syslog)
- fprintf(f, "%s = %s\n", "syslog", p->syslog);
-
- if (p->log_level_present)
- fprintf(f, "%s = %" PRIu32 "\n", "log_level", p->log_level);
-
- if (p->version_present)
- fprintf(f, "%s = %s\n", "v", (p->version) ? "yes" : "no");
-
- if (p->help_present)
- fprintf(f, "%s = %s\n", "help", (p->help) ? "yes" : "no");
-
- if (p->no_huge_present)
- fprintf(f, "%s = %s\n", "no_huge", (p->no_huge) ? "yes" : "no");
-
- if (p->no_pci_present)
- fprintf(f, "%s = %s\n", "no_pci", (p->no_pci) ? "yes" : "no");
-
- if (p->no_hpet_present)
- fprintf(f, "%s = %s\n", "no_hpet", (p->no_hpet) ? "yes" : "no");
-
- if (p->no_shconf_present)
- fprintf(f, "%s = %s\n", "no_shconf",
- (p->no_shconf) ? "yes" : "no");
-
- if (p->add_driver)
- fprintf(f, "%s = %s\n", "d", p->add_driver);
-
- if (p->socket_mem)
- fprintf(f, "%s = %s\n", "socket_mem", p->socket_mem);
-
- if (p->huge_dir)
- fprintf(f, "%s = %s\n", "huge_dir", p->huge_dir);
-
- if (p->file_prefix)
- fprintf(f, "%s = %s\n", "file_prefix", p->file_prefix);
-
- if (p->base_virtaddr)
- fprintf(f, "%s = %s\n", "base_virtaddr", p->base_virtaddr);
-
- if (p->create_uio_dev_present)
- fprintf(f, "%s = %s\n", "create_uio_dev",
- (p->create_uio_dev) ? "yes" : "no");
-
- if (p->vfio_intr)
- fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr);
-
- fputc('\n', f);
-}
-
-static void
-save_mempool_params(struct app_params *app, FILE *f)
-{
- struct app_mempool_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->mempool_params);
- for (i = 0; i < count; i++) {
- p = &app->mempool_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %" PRIu32 "\n", "buffer_size", p->buffer_size);
- fprintf(f, "%s = %" PRIu32 "\n", "pool_size", p->pool_size);
- fprintf(f, "%s = %" PRIu32 "\n", "cache_size", p->cache_size);
- fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_links_params(struct app_params *app, FILE *f)
-{
- struct app_link_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->link_params);
- for (i = 0; i < count; i++) {
- p = &app->link_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "; %s = %" PRIu32 "\n", "pmd_id", p->pmd_id);
- fprintf(f, "%s = %s\n", "promisc", p->promisc ? "yes" : "no");
- fprintf(f, "%s = %" PRIu32 "\n", "arp_q", p->arp_q);
- fprintf(f, "%s = %" PRIu32 "\n", "tcp_syn_q",
- p->tcp_syn_q);
- fprintf(f, "%s = %" PRIu32 "\n", "ip_local_q", p->ip_local_q);
- fprintf(f, "%s = %" PRIu32 "\n", "tcp_local_q", p->tcp_local_q);
- fprintf(f, "%s = %" PRIu32 "\n", "udp_local_q", p->udp_local_q);
- fprintf(f, "%s = %" PRIu32 "\n", "sctp_local_q",
- p->sctp_local_q);
-
- if (p->n_rss_qs) {
- uint32_t j;
-
- /* rss_qs */
- fprintf(f, "rss_qs = ");
- for (j = 0; j < p->n_rss_qs; j++)
- fprintf(f, "%" PRIu32 " ", p->rss_qs[j]);
- fputc('\n', f);
-
- /* rss_proto_ipv4 */
- if (p->rss_proto_ipv4) {
- fprintf(f, "rss_proto_ipv4 = ");
- if (p->rss_proto_ipv4 & ETH_RSS_IPV4)
- fprintf(f, "IP ");
- if (p->rss_proto_ipv4 & ETH_RSS_FRAG_IPV4)
- fprintf(f, "FRAG ");
- if (p->rss_proto_ipv4 &
- ETH_RSS_NONFRAG_IPV4_TCP)
- fprintf(f, "TCP ");
- if (p->rss_proto_ipv4 &
- ETH_RSS_NONFRAG_IPV4_UDP)
- fprintf(f, "UDP ");
- if (p->rss_proto_ipv4 &
- ETH_RSS_NONFRAG_IPV4_SCTP)
- fprintf(f, "SCTP ");
- if (p->rss_proto_ipv4 &
- ETH_RSS_NONFRAG_IPV4_OTHER)
- fprintf(f, "OTHER ");
- fprintf(f, "\n");
- } else
- fprintf(f, "; rss_proto_ipv4 = <NONE>\n");
-
- /* rss_proto_ipv6 */
- if (p->rss_proto_ipv6) {
- fprintf(f, "rss_proto_ipv6 = ");
- if (p->rss_proto_ipv6 & ETH_RSS_IPV6)
- fprintf(f, "IP ");
- if (p->rss_proto_ipv6 & ETH_RSS_FRAG_IPV6)
- fprintf(f, "FRAG ");
- if (p->rss_proto_ipv6 &
- ETH_RSS_NONFRAG_IPV6_TCP)
- fprintf(f, "TCP ");
- if (p->rss_proto_ipv6 &
- ETH_RSS_NONFRAG_IPV6_UDP)
- fprintf(f, "UDP ");
- if (p->rss_proto_ipv6 &
- ETH_RSS_NONFRAG_IPV6_SCTP)
- fprintf(f, "SCTP ");
- if (p->rss_proto_ipv6 &
- ETH_RSS_NONFRAG_IPV6_OTHER)
- fprintf(f, "OTHER ");
- if (p->rss_proto_ipv6 & ETH_RSS_IPV6_EX)
- fprintf(f, "IP_EX ");
- if (p->rss_proto_ipv6 &
- ETH_RSS_IPV6_TCP_EX)
- fprintf(f, "TCP_EX ");
- if (p->rss_proto_ipv6 &
- ETH_RSS_IPV6_UDP_EX)
- fprintf(f, "UDP_EX ");
- fprintf(f, "\n");
- } else
- fprintf(f, "; rss_proto_ipv6 = <NONE>\n");
-
- /* rss_proto_l2 */
- if (p->rss_proto_l2) {
- fprintf(f, "rss_proto_l2 = ");
- if (p->rss_proto_l2 & ETH_RSS_L2_PAYLOAD)
- fprintf(f, "L2 ");
- fprintf(f, "\n");
- } else
- fprintf(f, "; rss_proto_l2 = <NONE>\n");
- } else {
- fprintf(f, "; rss_qs = <NONE>\n");
- fprintf(f, "; rss_proto_ipv4 = <NONE>\n");
- fprintf(f, "; rss_proto_ipv6 = <NONE>\n");
- fprintf(f, "; rss_proto_l2 = <NONE>\n");
- }
-
- if (strlen(p->pci_bdf))
- fprintf(f, "%s = %s\n", "pci_bdf", p->pci_bdf);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_rxq_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_hwq_in_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->hwq_in_params);
- for (i = 0; i < count; i++) {
- p = &app->hwq_in_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %s\n",
- "mempool",
- app->mempool_params[p->mempool_id].name);
- fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
- fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_txq_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_hwq_out_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->hwq_out_params);
- for (i = 0; i < count; i++) {
- p = &app->hwq_out_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
- fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
- fprintf(f, "%s = %s\n",
- "dropless",
- p->dropless ? "yes" : "no");
- fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_swq_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_swq_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->swq_params);
- for (i = 0; i < count; i++) {
- p = &app->swq_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
- fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
- fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
- fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
- fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
- fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
- fprintf(f, "%s = %s\n", "ipv4_frag", p->ipv4_frag ? "yes" : "no");
- fprintf(f, "%s = %s\n", "ipv6_frag", p->ipv6_frag ? "yes" : "no");
- fprintf(f, "%s = %s\n", "ipv4_ras", p->ipv4_ras ? "yes" : "no");
- fprintf(f, "%s = %s\n", "ipv6_ras", p->ipv6_ras ? "yes" : "no");
- if ((p->ipv4_frag == 1) || (p->ipv6_frag == 1)) {
- fprintf(f, "%s = %" PRIu32 "\n", "mtu", p->mtu);
- fprintf(f, "%s = %" PRIu32 "\n", "metadata_size", p->metadata_size);
- fprintf(f, "%s = %s\n",
- "mempool_direct",
- app->mempool_params[p->mempool_direct_id].name);
- fprintf(f, "%s = %s\n",
- "mempool_indirect",
- app->mempool_params[p->mempool_indirect_id].name);
- }
-
- fputc('\n', f);
- }
-}
-
-static void
-save_tm_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_tm_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->tm_params);
- for (i = 0; i < count; i++) {
- p = &app->tm_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %s\n", "cfg", p->file_name);
- fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
- fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_tap_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_tap_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->tap_params);
- for (i = 0; i < count; i++) {
- p = &app->tap_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
- fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
- fprintf(f, "%s = %s\n", "dropless", p->dropless ? "yes" : "no");
- fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
- fprintf(f, "%s = %s\n", "mempool",
- app->mempool_params[p->mempool_id].name);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_kni_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_kni_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->kni_params);
- for (i = 0; i < count; i++) {
- p = &app->kni_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- /* section name */
- fprintf(f, "[%s]\n", p->name);
-
- /* core */
- if (p->force_bind) {
- fprintf(f, "; force_bind = 1\n");
- fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n",
- p->socket_id,
- p->core_id,
- (p->hyper_th_id) ? "h" : "");
- } else
- fprintf(f, "; force_bind = 0\n");
-
- /* mempool */
- fprintf(f, "%s = %s\n", "mempool",
- app->mempool_params[p->mempool_id].name);
-
- /* burst_read */
- fprintf(f, "%s = %" PRIu32 "\n", "burst_read", p->burst_read);
-
- /* burst_write */
- fprintf(f, "%s = %" PRIu32 "\n", "burst_write", p->burst_write);
-
- /* dropless */
- fprintf(f, "%s = %s\n",
- "dropless",
- p->dropless ? "yes" : "no");
-
- /* n_retries */
- fprintf(f, "%s = %" PRIu64 "\n", "n_retries", p->n_retries);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_source_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_source_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->source_params);
- for (i = 0; i < count; i++) {
- p = &app->source_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %s\n",
- "mempool",
- app->mempool_params[p->mempool_id].name);
- fprintf(f, "%s = %" PRIu32 "\n", "burst", p->burst);
- fprintf(f, "%s = %s\n", "pcap_file_rd", p->file_name);
- fprintf(f, "%s = %" PRIu32 "\n", "pcap_bytes_rd_per_pkt",
- p->n_bytes_per_pkt);
- fputc('\n', f);
- }
-}
-
-static void
-save_sink_params(struct app_params *app, FILE *f)
-{
- struct app_pktq_sink_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->sink_params);
- for (i = 0; i < count; i++) {
- p = &app->sink_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %s\n", "pcap_file_wr", p->file_name);
- fprintf(f, "%s = %" PRIu32 "\n",
- "pcap_n_pkt_wr", p->n_pkts_to_dump);
- fputc('\n', f);
- }
-}
-
-static void
-save_msgq_params(struct app_params *app, FILE *f)
-{
- struct app_msgq_params *p;
- size_t i, count;
-
- count = RTE_DIM(app->msgq_params);
- for (i = 0; i < count; i++) {
- p = &app->msgq_params[i];
- if (!APP_PARAM_VALID(p))
- continue;
-
- fprintf(f, "[%s]\n", p->name);
- fprintf(f, "%s = %" PRIu32 "\n", "size", p->size);
- fprintf(f, "%s = %" PRIu32 "\n", "cpu", p->cpu_socket_id);
-
- fputc('\n', f);
- }
-}
-
-static void
-save_pipeline_params(struct app_params *app, FILE *f)
-{
- size_t i, count;
-
- count = RTE_DIM(app->pipeline_params);
- for (i = 0; i < count; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
-
- if (!APP_PARAM_VALID(p))
- continue;
-
- /* section name */
- fprintf(f, "[%s]\n", p->name);
-
- /* type */
- fprintf(f, "type = %s\n", p->type);
-
- /* core */
- fprintf(f, "core = s%" PRIu32 "c%" PRIu32 "%s\n",
- p->socket_id,
- p->core_id,
- (p->hyper_th_id) ? "h" : "");
-
- /* pktq_in */
- if (p->n_pktq_in) {
- uint32_t j;
-
- fprintf(f, "pktq_in =");
- for (j = 0; j < p->n_pktq_in; j++) {
- struct app_pktq_in_params *pp = &p->pktq_in[j];
- char *name;
-
- switch (pp->type) {
- case APP_PKTQ_IN_HWQ:
- name = app->hwq_in_params[pp->id].name;
- break;
- case APP_PKTQ_IN_SWQ:
- name = app->swq_params[pp->id].name;
- break;
- case APP_PKTQ_IN_TM:
- name = app->tm_params[pp->id].name;
- break;
- case APP_PKTQ_IN_TAP:
- name = app->tap_params[pp->id].name;
- break;
- case APP_PKTQ_IN_KNI:
- name = app->kni_params[pp->id].name;
- break;
- case APP_PKTQ_IN_SOURCE:
- name = app->source_params[pp->id].name;
- break;
- default:
- APP_CHECK(0, "System error "
- "occurred while saving "
- "parameter to file");
- }
-
- fprintf(f, " %s", name);
- }
- fprintf(f, "\n");
- }
-
- /* pktq_in */
- if (p->n_pktq_out) {
- uint32_t j;
-
- fprintf(f, "pktq_out =");
- for (j = 0; j < p->n_pktq_out; j++) {
- struct app_pktq_out_params *pp =
- &p->pktq_out[j];
- char *name;
-
- switch (pp->type) {
- case APP_PKTQ_OUT_HWQ:
- name = app->hwq_out_params[pp->id].name;
- break;
- case APP_PKTQ_OUT_SWQ:
- name = app->swq_params[pp->id].name;
- break;
- case APP_PKTQ_OUT_TM:
- name = app->tm_params[pp->id].name;
- break;
- case APP_PKTQ_OUT_TAP:
- name = app->tap_params[pp->id].name;
- break;
- case APP_PKTQ_OUT_KNI:
- name = app->kni_params[pp->id].name;
- break;
- case APP_PKTQ_OUT_SINK:
- name = app->sink_params[pp->id].name;
- break;
- default:
- APP_CHECK(0, "System error "
- "occurred while saving "
- "parameter to file");
- }
-
- fprintf(f, " %s", name);
- }
- fprintf(f, "\n");
- }
-
- /* msgq_in */
- if (p->n_msgq_in) {
- uint32_t j;
-
- fprintf(f, "msgq_in =");
- for (j = 0; j < p->n_msgq_in; j++) {
- uint32_t id = p->msgq_in[j];
- char *name = app->msgq_params[id].name;
-
- fprintf(f, " %s", name);
- }
- fprintf(f, "\n");
- }
-
- /* msgq_out */
- if (p->n_msgq_out) {
- uint32_t j;
-
- fprintf(f, "msgq_out =");
- for (j = 0; j < p->n_msgq_out; j++) {
- uint32_t id = p->msgq_out[j];
- char *name = app->msgq_params[id].name;
-
- fprintf(f, " %s", name);
- }
- fprintf(f, "\n");
- }
-
- /* timer_period */
- fprintf(f, "timer_period = %" PRIu32 "\n", p->timer_period);
-
- /* args */
- if (p->n_args) {
- uint32_t j;
-
- for (j = 0; j < p->n_args; j++)
- fprintf(f, "%s = %s\n", p->args_name[j],
- p->args_value[j]);
- }
-
- fprintf(f, "\n");
- }
-}
-
-void
-app_config_save(struct app_params *app, const char *file_name)
-{
- FILE *file;
- char *name, *dir_name;
- int status;
-
- name = strdup(file_name);
- dir_name = dirname(name);
- status = access(dir_name, W_OK);
- APP_CHECK((status == 0),
- "Error: need write access privilege to directory "
- "\"%s\" to save configuration\n", dir_name);
-
- file = fopen(file_name, "w");
- APP_CHECK((file != NULL),
- "Error: failed to save configuration to file \"%s\"",
- file_name);
-
- save_eal_params(app, file);
- save_pipeline_params(app, file);
- save_mempool_params(app, file);
- save_links_params(app, file);
- save_rxq_params(app, file);
- save_txq_params(app, file);
- save_swq_params(app, file);
- save_tm_params(app, file);
- save_tap_params(app, file);
- save_kni_params(app, file);
- save_source_params(app, file);
- save_sink_params(app, file);
- save_msgq_params(app, file);
-
- fclose(file);
- free(name);
-}
-
-int
-app_config_init(struct app_params *app)
-{
- size_t i;
-
- memcpy(app, &app_params_default, sizeof(struct app_params));
-
- for (i = 0; i < RTE_DIM(app->mempool_params); i++)
- memcpy(&app->mempool_params[i],
- &mempool_params_default,
- sizeof(struct app_mempool_params));
-
- for (i = 0; i < RTE_DIM(app->link_params); i++)
- memcpy(&app->link_params[i],
- &link_params_default,
- sizeof(struct app_link_params));
-
- for (i = 0; i < RTE_DIM(app->hwq_in_params); i++)
- memcpy(&app->hwq_in_params[i],
- &default_hwq_in_params,
- sizeof(default_hwq_in_params));
-
- for (i = 0; i < RTE_DIM(app->hwq_out_params); i++)
- memcpy(&app->hwq_out_params[i],
- &default_hwq_out_params,
- sizeof(default_hwq_out_params));
-
- for (i = 0; i < RTE_DIM(app->swq_params); i++)
- memcpy(&app->swq_params[i],
- &default_swq_params,
- sizeof(default_swq_params));
-
- for (i = 0; i < RTE_DIM(app->tm_params); i++)
- memcpy(&app->tm_params[i],
- &default_tm_params,
- sizeof(default_tm_params));
-
- for (i = 0; i < RTE_DIM(app->tap_params); i++)
- memcpy(&app->tap_params[i],
- &default_tap_params,
- sizeof(default_tap_params));
-
- for (i = 0; i < RTE_DIM(app->kni_params); i++)
- memcpy(&app->kni_params[i],
- &default_kni_params,
- sizeof(default_kni_params));
-
- for (i = 0; i < RTE_DIM(app->source_params); i++)
- memcpy(&app->source_params[i],
- &default_source_params,
- sizeof(default_source_params));
-
- for (i = 0; i < RTE_DIM(app->sink_params); i++)
- memcpy(&app->sink_params[i],
- &default_sink_params,
- sizeof(default_sink_params));
-
- for (i = 0; i < RTE_DIM(app->msgq_params); i++)
- memcpy(&app->msgq_params[i],
- &default_msgq_params,
- sizeof(default_msgq_params));
-
- for (i = 0; i < RTE_DIM(app->pipeline_params); i++)
- memcpy(&app->pipeline_params[i],
- &default_pipeline_params,
- sizeof(default_pipeline_params));
-
- return 0;
-}
-
-static char *
-filenamedup(const char *filename, const char *suffix)
-{
- char *s = malloc(strlen(filename) + strlen(suffix) + 1);
-
- if (!s)
- return NULL;
-
- sprintf(s, "%s%s", filename, suffix);
- return s;
-}
-
-int
-app_config_args(struct app_params *app, int argc, char **argv)
-{
- const char *optname;
- int opt, option_index;
- int f_present, s_present, p_present, l_present;
- int preproc_present, preproc_params_present;
- int scaned = 0;
-
- static struct option lgopts[] = {
- { "preproc", 1, 0, 0 },
- { "preproc-args", 1, 0, 0 },
- { NULL, 0, 0, 0 }
- };
-
- /* Copy application name */
- strncpy(app->app_name, argv[0], APP_APPNAME_SIZE - 1);
-
- f_present = 0;
- s_present = 0;
- p_present = 0;
- l_present = 0;
- preproc_present = 0;
- preproc_params_present = 0;
-
- while ((opt = getopt_long(argc, argv, "f:s:p:l:", lgopts,
- &option_index)) != EOF)
- switch (opt) {
- case 'f':
- if (f_present)
- rte_panic("Error: Config file is provided "
- "more than once\n");
- f_present = 1;
-
- if (!strlen(optarg))
- rte_panic("Error: Config file name is null\n");
-
- app->config_file = strdup(optarg);
- if (app->config_file == NULL)
- rte_panic("Error: Memory allocation failure\n");
-
- break;
-
- case 's':
- if (s_present)
- rte_panic("Error: Script file is provided "
- "more than once\n");
- s_present = 1;
-
- if (!strlen(optarg))
- rte_panic("Error: Script file name is null\n");
-
- app->script_file = strdup(optarg);
- if (app->script_file == NULL)
- rte_panic("Error: Memory allocation failure\n");
-
- break;
-
- case 'p':
- if (p_present)
- rte_panic("Error: PORT_MASK is provided "
- "more than once\n");
- p_present = 1;
-
- if ((sscanf(optarg, "%" SCNx64 "%n", &app->port_mask,
- &scaned) != 1) ||
- ((size_t) scaned != strlen(optarg)))
- rte_panic("Error: PORT_MASK is not "
- "a hexadecimal integer\n");
-
- if (app->port_mask == 0)
- rte_panic("Error: PORT_MASK is null\n");
-
- break;
-
- case 'l':
- if (l_present)
- rte_panic("Error: LOG_LEVEL is provided "
- "more than once\n");
- l_present = 1;
-
- if ((sscanf(optarg, "%" SCNu32 "%n", &app->log_level,
- &scaned) != 1) ||
- ((size_t) scaned != strlen(optarg)) ||
- (app->log_level >= APP_LOG_LEVELS))
- rte_panic("Error: LOG_LEVEL invalid value\n");
-
- break;
-
- case 0:
- optname = lgopts[option_index].name;
-
- if (strcmp(optname, "preproc") == 0) {
- if (preproc_present)
- rte_panic("Error: Preprocessor argument "
- "is provided more than once\n");
- preproc_present = 1;
-
- app->preproc = strdup(optarg);
- break;
- }
-
- if (strcmp(optname, "preproc-args") == 0) {
- if (preproc_params_present)
- rte_panic("Error: Preprocessor args "
- "are provided more than once\n");
- preproc_params_present = 1;
-
- app->preproc_args = strdup(optarg);
- break;
- }
-
- app_print_usage(argv[0]);
- break;
-
- default:
- app_print_usage(argv[0]);
- }
-
- optind = 1; /* reset getopt lib */
-
- /* Check dependencies between args */
- if (preproc_params_present && (preproc_present == 0))
- rte_panic("Error: Preprocessor args specified while "
- "preprocessor is not defined\n");
-
- app->parser_file = preproc_present ?
- filenamedup(app->config_file, ".preproc") :
- strdup(app->config_file);
- app->output_file = filenamedup(app->config_file, ".out");
-
- return 0;
-}
-
-int
-app_config_preproc(struct app_params *app)
-{
- char buffer[256];
- int status;
-
- if (app->preproc == NULL)
- return 0;
-
- status = access(app->config_file, F_OK | R_OK);
- APP_CHECK((status == 0), "Error: Unable to open file %s",
- app->config_file);
-
- snprintf(buffer, sizeof(buffer), "%s %s %s > %s",
- app->preproc,
- app->preproc_args ? app->preproc_args : "",
- app->config_file,
- app->parser_file);
-
- status = system(buffer);
- APP_CHECK((WIFEXITED(status) && (WEXITSTATUS(status) == 0)),
- "Error occurred while pre-processing file \"%s\"\n",
- app->config_file);
-
- return status;
-}
diff --git a/examples/ip_pipeline/config_parse_tm.c b/examples/ip_pipeline/config_parse_tm.c
deleted file mode 100644
index 6edd2ca9..00000000
--- a/examples/ip_pipeline/config_parse_tm.c
+++ /dev/null
@@ -1,419 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-#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 <rte_errno.h>
-#include <rte_cfgfile.h>
-#include <rte_string_fns.h>
-
-#include "app.h"
-
-static int
-tm_cfgfile_load_sched_port(
- struct rte_cfgfile *file,
- struct rte_sched_port_params *port_params)
-{
- const char *entry;
- int j;
-
- entry = rte_cfgfile_get_entry(file, "port", "frame overhead");
- if (entry)
- port_params->frame_overhead = (uint32_t)atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, "port", "mtu");
- if (entry)
- port_params->mtu = (uint32_t)atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- "port",
- "number of subports per port");
- if (entry)
- port_params->n_subports_per_port = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- "port",
- "number of pipes per subport");
- if (entry)
- port_params->n_pipes_per_subport = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, "port", "queue sizes");
- if (entry) {
- char *next;
-
- for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
- port_params->qsize[j] = (uint16_t)
- strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
- }
-
-#ifdef RTE_SCHED_RED
- for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) {
- char str[32];
-
- /* Parse WRED min thresholds */
- snprintf(str, sizeof(str), "tc %" PRId32 " wred min", j);
- entry = rte_cfgfile_get_entry(file, "red", str);
- if (entry) {
- char *next;
- int k;
-
- /* for each packet colour (green, yellow, red) */
- for (k = 0; k < e_RTE_METER_COLORS; k++) {
- port_params->red_params[j][k].min_th
- = (uint16_t)strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
- }
-
- /* Parse WRED max thresholds */
- snprintf(str, sizeof(str), "tc %" PRId32 " wred max", j);
- entry = rte_cfgfile_get_entry(file, "red", str);
- if (entry) {
- char *next;
- int k;
-
- /* for each packet colour (green, yellow, red) */
- for (k = 0; k < e_RTE_METER_COLORS; k++) {
- port_params->red_params[j][k].max_th
- = (uint16_t)strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
- }
-
- /* Parse WRED inverse mark probabilities */
- snprintf(str, sizeof(str), "tc %" PRId32 " wred inv prob", j);
- entry = rte_cfgfile_get_entry(file, "red", str);
- if (entry) {
- char *next;
- int k;
-
- /* for each packet colour (green, yellow, red) */
- for (k = 0; k < e_RTE_METER_COLORS; k++) {
- port_params->red_params[j][k].maxp_inv
- = (uint8_t)strtol(entry, &next, 10);
-
- if (next == NULL)
- break;
- entry = next;
- }
- }
-
- /* Parse WRED EWMA filter weights */
- snprintf(str, sizeof(str), "tc %" PRId32 " wred weight", j);
- entry = rte_cfgfile_get_entry(file, "red", str);
- if (entry) {
- char *next;
- int k;
-
- /* for each packet colour (green, yellow, red) */
- for (k = 0; k < e_RTE_METER_COLORS; k++) {
- port_params->red_params[j][k].wq_log2
- = (uint8_t)strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
- }
- }
-#endif /* RTE_SCHED_RED */
-
- return 0;
-}
-
-static int
-tm_cfgfile_load_sched_pipe(
- struct rte_cfgfile *file,
- struct rte_sched_port_params *port_params,
- struct rte_sched_pipe_params *pipe_params)
-{
- int i, j;
- char *next;
- const char *entry;
- int profiles;
-
- profiles = rte_cfgfile_num_sections(file,
- "pipe profile", sizeof("pipe profile") - 1);
- port_params->n_pipe_profiles = profiles;
-
- for (j = 0; j < profiles; j++) {
- char pipe_name[32];
-
- snprintf(pipe_name, sizeof(pipe_name),
- "pipe profile %" PRId32, j);
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tb rate");
- if (entry)
- pipe_params[j].tb_rate = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tb size");
- if (entry)
- pipe_params[j].tb_size = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc period");
- if (entry)
- pipe_params[j].tc_period = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc 0 rate");
- if (entry)
- pipe_params[j].tc_rate[0] = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 rate");
- if (entry)
- pipe_params[j].tc_rate[1] = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 rate");
- if (entry)
- pipe_params[j].tc_rate[2] = (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 rate");
- if (entry)
- pipe_params[j].tc_rate[3] = (uint32_t) atoi(entry);
-
-#ifdef RTE_SCHED_SUBPORT_TC_OV
- entry = rte_cfgfile_get_entry(file, pipe_name,
- "tc 3 oversubscription weight");
- if (entry)
- pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry);
-#endif
-
- entry = rte_cfgfile_get_entry(file,
- pipe_name,
- "tc 0 wrr weights");
- if (entry)
- for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
- pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] =
- (uint8_t) strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc 1 wrr weights");
- if (entry)
- for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
- pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] =
- (uint8_t) strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc 2 wrr weights");
- if (entry)
- for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
- pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] =
- (uint8_t) strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
-
- entry = rte_cfgfile_get_entry(file, pipe_name, "tc 3 wrr weights");
- if (entry)
- for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) {
- pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] =
- (uint8_t) strtol(entry, &next, 10);
- if (next == NULL)
- break;
- entry = next;
- }
- }
- return 0;
-}
-
-static int
-tm_cfgfile_load_sched_subport(
- struct rte_cfgfile *file,
- struct rte_sched_subport_params *subport_params,
- int *pipe_to_profile)
-{
- const char *entry;
- int i, j, k;
-
- for (i = 0; i < APP_MAX_SCHED_SUBPORTS; i++) {
- char sec_name[CFG_NAME_LEN];
-
- snprintf(sec_name, sizeof(sec_name),
- "subport %" PRId32, i);
-
- if (rte_cfgfile_has_section(file, sec_name)) {
- entry = rte_cfgfile_get_entry(file,
- sec_name,
- "tb rate");
- if (entry)
- subport_params[i].tb_rate =
- (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- sec_name,
- "tb size");
- if (entry)
- subport_params[i].tb_size =
- (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- sec_name,
- "tc period");
- if (entry)
- subport_params[i].tc_period =
- (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- sec_name,
- "tc 0 rate");
- if (entry)
- subport_params[i].tc_rate[0] =
- (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- sec_name,
- "tc 1 rate");
- if (entry)
- subport_params[i].tc_rate[1] =
- (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- sec_name,
- "tc 2 rate");
- if (entry)
- subport_params[i].tc_rate[2] =
- (uint32_t) atoi(entry);
-
- entry = rte_cfgfile_get_entry(file,
- sec_name,
- "tc 3 rate");
- if (entry)
- subport_params[i].tc_rate[3] =
- (uint32_t) atoi(entry);
-
- int n_entries = rte_cfgfile_section_num_entries(file,
- sec_name);
- struct rte_cfgfile_entry entries[n_entries];
-
- rte_cfgfile_section_entries(file,
- sec_name,
- entries,
- n_entries);
-
- for (j = 0; j < n_entries; j++)
- if (strncmp("pipe",
- entries[j].name,
- sizeof("pipe") - 1) == 0) {
- int profile;
- char *tokens[2] = {NULL, NULL};
- int n_tokens;
- int begin, end;
- char name[CFG_NAME_LEN + 1];
-
- profile = atoi(entries[j].value);
- strncpy(name,
- entries[j].name,
- sizeof(name));
- n_tokens = rte_strsplit(
- &name[sizeof("pipe")],
- strnlen(name, CFG_NAME_LEN),
- tokens, 2, '-');
-
- begin = atoi(tokens[0]);
- if (n_tokens == 2)
- end = atoi(tokens[1]);
- else
- end = begin;
-
- if ((end >= APP_MAX_SCHED_PIPES) ||
- (begin > end))
- return -1;
-
- for (k = begin; k <= end; k++) {
- char profile_name[CFG_NAME_LEN];
-
- snprintf(profile_name,
- sizeof(profile_name),
- "pipe profile %" PRId32,
- profile);
- if (rte_cfgfile_has_section(file, profile_name))
- pipe_to_profile[i * APP_MAX_SCHED_PIPES + k] = profile;
- else
- rte_exit(EXIT_FAILURE,
- "Wrong pipe profile %s\n",
- entries[j].value);
- }
- }
- }
- }
-
- return 0;
-}
-
-static int
-tm_cfgfile_load(struct app_pktq_tm_params *tm)
-{
- struct rte_cfgfile *file;
- uint32_t i;
-
- memset(tm->sched_subport_params, 0, sizeof(tm->sched_subport_params));
- memset(tm->sched_pipe_profiles, 0, sizeof(tm->sched_pipe_profiles));
- memset(&tm->sched_port_params, 0, sizeof(tm->sched_port_params));
- for (i = 0; i < APP_MAX_SCHED_SUBPORTS * APP_MAX_SCHED_PIPES; i++)
- tm->sched_pipe_to_profile[i] = -1;
-
- tm->sched_port_params.pipe_profiles = &tm->sched_pipe_profiles[0];
-
- if (tm->file_name[0] == '\0')
- return -1;
-
- file = rte_cfgfile_load(tm->file_name, 0);
- if (file == NULL)
- return -1;
-
- tm_cfgfile_load_sched_port(file,
- &tm->sched_port_params);
- tm_cfgfile_load_sched_subport(file,
- tm->sched_subport_params,
- tm->sched_pipe_to_profile);
- tm_cfgfile_load_sched_pipe(file,
- &tm->sched_port_params,
- tm->sched_pipe_profiles);
-
- rte_cfgfile_close(file);
- return 0;
-}
-
-int
-app_config_parse_tm(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < RTE_DIM(app->tm_params); i++) {
- struct app_pktq_tm_params *p = &app->tm_params[i];
- int status;
-
- if (!APP_PARAM_VALID(p))
- break;
-
- status = tm_cfgfile_load(p);
- APP_CHECK(status == 0,
- "Parse error for %s configuration file \"%s\"\n",
- p->name,
- p->file_name);
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/conn.c b/examples/ip_pipeline/conn.c
new file mode 100644
index 00000000..6b08e9e8
--- /dev/null
+++ b/examples/ip_pipeline/conn.c
@@ -0,0 +1,329 @@
+/* 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>
+
+#define __USE_GNU
+#include <sys/socket.h>
+
+#include <sys/epoll.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <errno.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 */
+ strncpy(conn->welcome, p->welcome, CONN_WELCOME_LEN_MAX);
+ strncpy(conn->prompt, p->prompt, CONN_PROMPT_LEN_MAX);
+ 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
new file mode 100644
index 00000000..46f9f95e
--- /dev/null
+++ b/examples/ip_pipeline/conn.h
@@ -0,0 +1,47 @@
+/* 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/cpu_core_map.c b/examples/ip_pipeline/cpu_core_map.c
deleted file mode 100644
index 231f38ef..00000000
--- a/examples/ip_pipeline/cpu_core_map.c
+++ /dev/null
@@ -1,471 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <rte_lcore.h>
-
-#include "cpu_core_map.h"
-
-struct cpu_core_map {
- uint32_t n_max_sockets;
- uint32_t n_max_cores_per_socket;
- uint32_t n_max_ht_per_core;
- uint32_t n_sockets;
- uint32_t n_cores_per_socket;
- uint32_t n_ht_per_core;
- int map[0];
-};
-
-static inline uint32_t
-cpu_core_map_pos(struct cpu_core_map *map,
- uint32_t socket_id,
- uint32_t core_id,
- uint32_t ht_id)
-{
- return (socket_id * map->n_max_cores_per_socket + core_id) *
- map->n_max_ht_per_core + ht_id;
-}
-
-static int
-cpu_core_map_compute_eal(struct cpu_core_map *map);
-
-static int
-cpu_core_map_compute_linux(struct cpu_core_map *map);
-
-static int
-cpu_core_map_compute_and_check(struct cpu_core_map *map);
-
-struct cpu_core_map *
-cpu_core_map_init(uint32_t n_max_sockets,
- uint32_t n_max_cores_per_socket,
- uint32_t n_max_ht_per_core,
- uint32_t eal_initialized)
-{
- uint32_t map_size, map_mem_size, i;
- struct cpu_core_map *map;
- int status;
-
- /* Check input arguments */
- if ((n_max_sockets == 0) ||
- (n_max_cores_per_socket == 0) ||
- (n_max_ht_per_core == 0))
- return NULL;
-
- /* Memory allocation */
- map_size = n_max_sockets * n_max_cores_per_socket * n_max_ht_per_core;
- map_mem_size = sizeof(struct cpu_core_map) + map_size * sizeof(int);
- map = (struct cpu_core_map *) malloc(map_mem_size);
- if (map == NULL)
- return NULL;
-
- /* Initialization */
- map->n_max_sockets = n_max_sockets;
- map->n_max_cores_per_socket = n_max_cores_per_socket;
- map->n_max_ht_per_core = n_max_ht_per_core;
- map->n_sockets = 0;
- map->n_cores_per_socket = 0;
- map->n_ht_per_core = 0;
-
- for (i = 0; i < map_size; i++)
- map->map[i] = -1;
-
- status = (eal_initialized) ?
- cpu_core_map_compute_eal(map) :
- cpu_core_map_compute_linux(map);
-
- if (status) {
- free(map);
- return NULL;
- }
-
- status = cpu_core_map_compute_and_check(map);
- if (status) {
- free(map);
- return NULL;
- }
-
- return map;
-}
-
-int
-cpu_core_map_compute_eal(struct cpu_core_map *map)
-{
- uint32_t socket_id, core_id, ht_id;
-
- /* Compute map */
- for (socket_id = 0; socket_id < map->n_max_sockets; socket_id++) {
- uint32_t n_detected, core_id_contig;
- int lcore_id;
-
- n_detected = 0;
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
- struct lcore_config *p = &lcore_config[lcore_id];
-
- if ((p->detected) && (p->socket_id == socket_id))
- n_detected++;
- }
-
- core_id_contig = 0;
-
- for (core_id = 0; n_detected ; core_id++) {
- ht_id = 0;
-
- for (lcore_id = 0;
- lcore_id < RTE_MAX_LCORE;
- lcore_id++) {
- struct lcore_config *p =
- &lcore_config[lcore_id];
-
- if ((p->detected) &&
- (p->socket_id == socket_id) &&
- (p->core_id == core_id)) {
- uint32_t pos = cpu_core_map_pos(map,
- socket_id,
- core_id_contig,
- ht_id);
-
- map->map[pos] = lcore_id;
- ht_id++;
- n_detected--;
- }
- }
-
- if (ht_id) {
- core_id_contig++;
- if (core_id_contig ==
- map->n_max_cores_per_socket)
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-int
-cpu_core_map_compute_and_check(struct cpu_core_map *map)
-{
- uint32_t socket_id, core_id, ht_id;
-
- /* Compute n_ht_per_core, n_cores_per_socket, n_sockets */
- for (ht_id = 0; ht_id < map->n_max_ht_per_core; ht_id++) {
- if (map->map[ht_id] == -1)
- break;
-
- map->n_ht_per_core++;
- }
-
- if (map->n_ht_per_core == 0)
- return -1;
-
- for (core_id = 0; core_id < map->n_max_cores_per_socket; core_id++) {
- uint32_t pos = core_id * map->n_max_ht_per_core;
-
- if (map->map[pos] == -1)
- break;
-
- map->n_cores_per_socket++;
- }
-
- if (map->n_cores_per_socket == 0)
- return -1;
-
- for (socket_id = 0; socket_id < map->n_max_sockets; socket_id++) {
- uint32_t pos = socket_id * map->n_max_cores_per_socket *
- map->n_max_ht_per_core;
-
- if (map->map[pos] == -1)
- break;
-
- map->n_sockets++;
- }
-
- if (map->n_sockets == 0)
- return -1;
-
- /* Check that each socket has exactly the same number of cores
- and that each core has exactly the same number of hyper-threads */
- for (socket_id = 0; socket_id < map->n_sockets; socket_id++) {
- for (core_id = 0; core_id < map->n_cores_per_socket; core_id++)
- for (ht_id = 0;
- ht_id < map->n_max_ht_per_core;
- ht_id++) {
- uint32_t pos = (socket_id *
- map->n_max_cores_per_socket + core_id) *
- map->n_max_ht_per_core + ht_id;
-
- if (((ht_id < map->n_ht_per_core) &&
- (map->map[pos] == -1)) ||
- ((ht_id >= map->n_ht_per_core) &&
- (map->map[pos] != -1)))
- return -1;
- }
-
- for ( ; core_id < map->n_max_cores_per_socket; core_id++)
- for (ht_id = 0;
- ht_id < map->n_max_ht_per_core;
- ht_id++) {
- uint32_t pos = cpu_core_map_pos(map,
- socket_id,
- core_id,
- ht_id);
-
- if (map->map[pos] != -1)
- return -1;
- }
- }
-
- return 0;
-}
-
-#define FILE_LINUX_CPU_N_LCORES \
- "/sys/devices/system/cpu/present"
-
-static int
-cpu_core_map_get_n_lcores_linux(void)
-{
- char buffer[64], *string;
- FILE *fd;
-
- fd = fopen(FILE_LINUX_CPU_N_LCORES, "r");
- if (fd == NULL)
- return -1;
-
- if (fgets(buffer, sizeof(buffer), fd) == NULL) {
- fclose(fd);
- return -1;
- }
-
- fclose(fd);
-
- string = index(buffer, '-');
- if (string == NULL)
- return -1;
-
- return atoi(++string) + 1;
-}
-
-#define FILE_LINUX_CPU_CORE_ID \
- "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/core_id"
-
-static int
-cpu_core_map_get_core_id_linux(int lcore_id)
-{
- char buffer[64];
- FILE *fd;
- int core_id;
-
- snprintf(buffer, sizeof(buffer), FILE_LINUX_CPU_CORE_ID, lcore_id);
- fd = fopen(buffer, "r");
- if (fd == NULL)
- return -1;
-
- if (fgets(buffer, sizeof(buffer), fd) == NULL) {
- fclose(fd);
- return -1;
- }
-
- fclose(fd);
-
- core_id = atoi(buffer);
- return core_id;
-}
-
-#define FILE_LINUX_CPU_SOCKET_ID \
- "/sys/devices/system/cpu/cpu%" PRIu32 "/topology/physical_package_id"
-
-static int
-cpu_core_map_get_socket_id_linux(int lcore_id)
-{
- char buffer[64];
- FILE *fd;
- int socket_id;
-
- snprintf(buffer, sizeof(buffer), FILE_LINUX_CPU_SOCKET_ID, lcore_id);
- fd = fopen(buffer, "r");
- if (fd == NULL)
- return -1;
-
- if (fgets(buffer, sizeof(buffer), fd) == NULL) {
- fclose(fd);
- return -1;
- }
-
- fclose(fd);
-
- socket_id = atoi(buffer);
- return socket_id;
-}
-
-int
-cpu_core_map_compute_linux(struct cpu_core_map *map)
-{
- uint32_t socket_id, core_id, ht_id;
- int n_lcores;
-
- n_lcores = cpu_core_map_get_n_lcores_linux();
- if (n_lcores <= 0)
- return -1;
-
- /* Compute map */
- for (socket_id = 0; socket_id < map->n_max_sockets; socket_id++) {
- uint32_t n_detected, core_id_contig;
- int lcore_id;
-
- n_detected = 0;
- for (lcore_id = 0; lcore_id < n_lcores; lcore_id++) {
- int lcore_socket_id =
- cpu_core_map_get_socket_id_linux(lcore_id);
-
-#if !defined(RTE_ARCH_PPC_64)
- if (lcore_socket_id < 0)
- return -1;
-#endif
-
- if (((uint32_t) lcore_socket_id) == socket_id)
- n_detected++;
- }
-
- core_id_contig = 0;
-
- for (core_id = 0; n_detected ; core_id++) {
- ht_id = 0;
-
- for (lcore_id = 0; lcore_id < n_lcores; lcore_id++) {
- int lcore_socket_id =
- cpu_core_map_get_socket_id_linux(
- lcore_id);
-
-#if !defined(RTE_ARCH_PPC_64)
- if (lcore_socket_id < 0)
- return -1;
-
- int lcore_core_id =
- cpu_core_map_get_core_id_linux(
- lcore_id);
-
- if (lcore_core_id < 0)
- return -1;
-#endif
-
-#if !defined(RTE_ARCH_PPC_64)
- if (((uint32_t) lcore_socket_id == socket_id) &&
- ((uint32_t) lcore_core_id == core_id)) {
-#else
- if (((uint32_t) lcore_socket_id == socket_id)) {
-#endif
- uint32_t pos = cpu_core_map_pos(map,
- socket_id,
- core_id_contig,
- ht_id);
-
- map->map[pos] = lcore_id;
- ht_id++;
- n_detected--;
- }
- }
-
- if (ht_id) {
- core_id_contig++;
- if (core_id_contig ==
- map->n_max_cores_per_socket)
- return -1;
- }
- }
- }
-
- return 0;
-}
-
-void
-cpu_core_map_print(struct cpu_core_map *map)
-{
- uint32_t socket_id, core_id, ht_id;
-
- if (map == NULL)
- return;
-
- for (socket_id = 0; socket_id < map->n_sockets; socket_id++) {
- printf("Socket %" PRIu32 ":\n", socket_id);
-
- for (core_id = 0;
- core_id < map->n_cores_per_socket;
- core_id++) {
- printf("[%" PRIu32 "] = [", core_id);
-
- for (ht_id = 0; ht_id < map->n_ht_per_core; ht_id++) {
- int lcore_id = cpu_core_map_get_lcore_id(map,
- socket_id,
- core_id,
- ht_id);
-
- uint32_t core_id_noncontig =
- cpu_core_map_get_core_id_linux(
- lcore_id);
-
- printf(" %" PRId32 " (%" PRIu32 ") ",
- lcore_id,
- core_id_noncontig);
- }
-
- printf("]\n");
- }
- }
-}
-
-uint32_t
-cpu_core_map_get_n_sockets(struct cpu_core_map *map)
-{
- if (map == NULL)
- return 0;
-
- return map->n_sockets;
-}
-
-uint32_t
-cpu_core_map_get_n_cores_per_socket(struct cpu_core_map *map)
-{
- if (map == NULL)
- return 0;
-
- return map->n_cores_per_socket;
-}
-
-uint32_t
-cpu_core_map_get_n_ht_per_core(struct cpu_core_map *map)
-{
- if (map == NULL)
- return 0;
-
- return map->n_ht_per_core;
-}
-
-int
-cpu_core_map_get_lcore_id(struct cpu_core_map *map,
- uint32_t socket_id,
- uint32_t core_id,
- uint32_t ht_id)
-{
- uint32_t pos;
-
- if ((map == NULL) ||
- (socket_id >= map->n_sockets) ||
- (core_id >= map->n_cores_per_socket) ||
- (ht_id >= map->n_ht_per_core))
- return -1;
-
- pos = cpu_core_map_pos(map, socket_id, core_id, ht_id);
-
- return map->map[pos];
-}
-
-void
-cpu_core_map_free(struct cpu_core_map *map)
-{
- free(map);
-}
diff --git a/examples/ip_pipeline/cpu_core_map.h b/examples/ip_pipeline/cpu_core_map.h
deleted file mode 100644
index 5e50f6e5..00000000
--- a/examples/ip_pipeline/cpu_core_map.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_CPU_CORE_MAP_H__
-#define __INCLUDE_CPU_CORE_MAP_H__
-
-#include <stdio.h>
-
-#include <rte_lcore.h>
-
-struct cpu_core_map;
-
-struct cpu_core_map *
-cpu_core_map_init(uint32_t n_max_sockets,
- uint32_t n_max_cores_per_socket,
- uint32_t n_max_ht_per_core,
- uint32_t eal_initialized);
-
-uint32_t
-cpu_core_map_get_n_sockets(struct cpu_core_map *map);
-
-uint32_t
-cpu_core_map_get_n_cores_per_socket(struct cpu_core_map *map);
-
-uint32_t
-cpu_core_map_get_n_ht_per_core(struct cpu_core_map *map);
-
-int
-cpu_core_map_get_lcore_id(struct cpu_core_map *map,
- uint32_t socket_id,
- uint32_t core_id,
- uint32_t ht_id);
-
-void cpu_core_map_print(struct cpu_core_map *map);
-
-void
-cpu_core_map_free(struct cpu_core_map *map);
-
-#endif
diff --git a/examples/ip_pipeline/examples/firewall.cli b/examples/ip_pipeline/examples/firewall.cli
new file mode 100644
index 00000000..269256c1
--- /dev/null
+++ b/examples/ip_pipeline/examples/firewall.cli
@@ -0,0 +1,59 @@
+; 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
new file mode 100644
index 00000000..426ff902
--- /dev/null
+++ b/examples/ip_pipeline/examples/flow.cli
@@ -0,0 +1,60 @@
+; 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/kni.cli b/examples/ip_pipeline/examples/kni.cli
new file mode 100644
index 00000000..14383409
--- /dev/null
+++ b/examples/ip_pipeline/examples/kni.cli
@@ -0,0 +1,69 @@
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2010-2018 Intel Corporation
+
+; _______________ ______________________
+; | | KNI0 | |
+; LINK0 RXQ0 --->|...............|------->|--+ |
+; | | KNI1 | | br0 |
+; LINK1 TXQ0 <---|...............|<-------|<-+ |
+; | | | Linux Kernel |
+; | PIPELINE0 | | Network Stack |
+; | | KNI1 | |
+; LINK1 RXQ0 --->|...............|------->|--+ |
+; | | KNI0 | | br0 |
+; LINK0 TXQ0 <---|...............|<-------|<-+ |
+; |_______________| |______________________|
+;
+; Insert Linux kernel KNI module:
+; [Linux]$ insmod rte_kni.ko
+;
+; Configure Linux kernel bridge between KNI0 and KNI1 interfaces:
+; [Linux]$ brctl addbr br0
+; [Linux]$ brctl addif br0 KNI0
+; [Linux]$ brctl addif br0 KNI1
+; [Linux]$ ifconfig br0 up
+; [Linux]$ ifconfig KNI0 up
+; [Linux]$ ifconfig KNI1 up
+;
+; Monitor packet forwarding performed by Linux kernel between KNI0 and KNI1:
+; [Linux]$ tcpdump -i KNI0
+; [Linux]$ tcpdump -i KNI1
+
+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
+
+kni KNI0 link LINK0 mempool MEMPOOL0
+kni KNI1 link LINK1 mempool MEMPOOL0
+
+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 kni KNI1
+pipeline PIPELINE0 port in bsz 32 link LINK1 rxq 0
+pipeline PIPELINE0 port in bsz 32 kni KNI0
+
+pipeline PIPELINE0 port out bsz 32 kni KNI0
+pipeline PIPELINE0 port out bsz 32 link LINK1 txq 0
+pipeline PIPELINE0 port out bsz 32 kni KNI1
+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/examples/l2fwd.cli b/examples/ip_pipeline/examples/l2fwd.cli
new file mode 100644
index 00000000..35e77cc9
--- /dev/null
+++ b/examples/ip_pipeline/examples/l2fwd.cli
@@ -0,0 +1,51 @@
+; 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
new file mode 100644
index 00000000..579b36a6
--- /dev/null
+++ b/examples/ip_pipeline/examples/route.cli
@@ -0,0 +1,60 @@
+; 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
new file mode 100644
index 00000000..06434a25
--- /dev/null
+++ b/examples/ip_pipeline/examples/route_ecmp.cli
@@ -0,0 +1,57 @@
+; 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
new file mode 100644
index 00000000..29c0a913
--- /dev/null
+++ b/examples/ip_pipeline/examples/rss.cli
@@ -0,0 +1,112 @@
+; 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
new file mode 100644
index 00000000..600cea26
--- /dev/null
+++ b/examples/ip_pipeline/examples/tap.cli
@@ -0,0 +1,66 @@
+; 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/pipeline/hash_func.h b/examples/ip_pipeline/hash_func.h
index 806ac227..f1b9d944 100644
--- a/examples/ip_pipeline/pipeline/hash_func.h
+++ b/examples/ip_pipeline/hash_func.h
@@ -1,6 +1,7 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
*/
+
#ifndef __INCLUDE_HASH_FUNC_H__
#define __INCLUDE_HASH_FUNC_H__
diff --git a/examples/ip_pipeline/pipeline/hash_func_arm64.h b/examples/ip_pipeline/hash_func_arm64.h
index ae6c0f41..50df8167 100644
--- a/examples/ip_pipeline/pipeline/hash_func_arm64.h
+++ b/examples/ip_pipeline/hash_func_arm64.h
@@ -1,34 +1,5 @@
-/*-
- * BSD LICENSE
- *
- * Copyright(c) 2017 Linaro Limited. All rights reserved.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Intel Corporation nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2017-2018 Linaro Limited.
*/
#ifndef __HASH_FUNC_ARM64_H__
#define __HASH_FUNC_ARM64_H__
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
deleted file mode 100644
index bb07efa1..00000000
--- a/examples/ip_pipeline/init.c
+++ /dev/null
@@ -1,1927 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <inttypes.h>
-#include <stdio.h>
-#include <string.h>
-#include <netinet/in.h>
-#ifdef RTE_EXEC_ENV_LINUXAPP
-#include <linux/if.h>
-#include <linux/if_tun.h>
-#endif
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <unistd.h>
-
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_eal.h>
-#include <rte_malloc.h>
-#include <rte_bus_pci.h>
-
-#include "app.h"
-#include "pipeline.h"
-#include "pipeline_common_fe.h"
-#include "pipeline_master.h"
-#include "pipeline_passthrough.h"
-#include "pipeline_firewall.h"
-#include "pipeline_flow_classification.h"
-#include "pipeline_flow_actions.h"
-#include "pipeline_routing.h"
-#include "thread_fe.h"
-
-#define APP_NAME_SIZE 32
-
-#define APP_RETA_SIZE_MAX (ETH_RSS_RETA_SIZE_512 / RTE_RETA_GROUP_SIZE)
-
-static void
-app_init_core_map(struct app_params *app)
-{
- APP_LOG(app, HIGH, "Initializing CPU core map ...");
- app->core_map = cpu_core_map_init(RTE_MAX_NUMA_NODES, RTE_MAX_LCORE,
- 4, 0);
-
- if (app->core_map == NULL)
- rte_panic("Cannot create CPU core map\n");
-
- if (app->log_level >= APP_LOG_LEVEL_LOW)
- cpu_core_map_print(app->core_map);
-}
-
-/* Core Mask String in Hex Representation */
-#define APP_CORE_MASK_STRING_SIZE ((64 * APP_CORE_MASK_SIZE) / 8 * 2 + 1)
-
-static void
-app_init_core_mask(struct app_params *app)
-{
- uint32_t i;
- char core_mask_str[APP_CORE_MASK_STRING_SIZE];
-
- for (i = 0; i < app->n_pipelines; i++) {
- struct app_pipeline_params *p = &app->pipeline_params[i];
- int lcore_id;
-
- lcore_id = cpu_core_map_get_lcore_id(app->core_map,
- p->socket_id,
- p->core_id,
- p->hyper_th_id);
-
- if (lcore_id < 0)
- rte_panic("Cannot create CPU core mask\n");
-
- app_core_enable_in_core_mask(app, lcore_id);
- }
-
- app_core_build_core_mask_string(app, core_mask_str);
- APP_LOG(app, HIGH, "CPU core mask = 0x%s", core_mask_str);
-}
-
-static void
-app_init_eal(struct app_params *app)
-{
- char buffer[256];
- char core_mask_str[APP_CORE_MASK_STRING_SIZE];
- struct app_eal_params *p = &app->eal_params;
- uint32_t n_args = 0;
- uint32_t i;
- int status;
-
- app->eal_argv[n_args++] = strdup(app->app_name);
-
- app_core_build_core_mask_string(app, core_mask_str);
- snprintf(buffer, sizeof(buffer), "-c%s", core_mask_str);
- app->eal_argv[n_args++] = strdup(buffer);
-
- if (p->coremap) {
- snprintf(buffer, sizeof(buffer), "--lcores=%s", p->coremap);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->master_lcore_present) {
- snprintf(buffer,
- sizeof(buffer),
- "--master-lcore=%" PRIu32,
- p->master_lcore);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- snprintf(buffer, sizeof(buffer), "-n%" PRIu32, p->channels);
- app->eal_argv[n_args++] = strdup(buffer);
-
- if (p->memory_present) {
- snprintf(buffer, sizeof(buffer), "-m%" PRIu32, p->memory);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->ranks_present) {
- snprintf(buffer, sizeof(buffer), "-r%" PRIu32, p->ranks);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->pci_blacklist[i] == NULL)
- break;
-
- snprintf(buffer,
- sizeof(buffer),
- "--pci-blacklist=%s",
- p->pci_blacklist[i]);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (app->port_mask != 0)
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->pci_whitelist[i] == NULL)
- break;
-
- snprintf(buffer,
- sizeof(buffer),
- "--pci-whitelist=%s",
- p->pci_whitelist[i]);
- app->eal_argv[n_args++] = strdup(buffer);
- }
- else
- for (i = 0; i < app->n_links; i++) {
- char *pci_bdf = app->link_params[i].pci_bdf;
-
- snprintf(buffer,
- sizeof(buffer),
- "--pci-whitelist=%s",
- pci_bdf);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- for (i = 0; i < APP_MAX_LINKS; i++) {
- if (p->vdev[i] == NULL)
- break;
-
- snprintf(buffer,
- sizeof(buffer),
- "--vdev=%s",
- p->vdev[i]);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->vmware_tsc_map_present) && p->vmware_tsc_map) {
- snprintf(buffer, sizeof(buffer), "--vmware-tsc-map");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->proc_type) {
- snprintf(buffer,
- sizeof(buffer),
- "--proc-type=%s",
- p->proc_type);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->syslog) {
- snprintf(buffer, sizeof(buffer), "--syslog=%s", p->syslog);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->log_level_present) {
- snprintf(buffer,
- sizeof(buffer),
- "--log-level=%" PRIu32,
- p->log_level);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->version_present) && p->version) {
- snprintf(buffer, sizeof(buffer), "-v");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->help_present) && p->help) {
- snprintf(buffer, sizeof(buffer), "--help");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->no_huge_present) && p->no_huge) {
- snprintf(buffer, sizeof(buffer), "--no-huge");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->no_pci_present) && p->no_pci) {
- snprintf(buffer, sizeof(buffer), "--no-pci");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->no_hpet_present) && p->no_hpet) {
- snprintf(buffer, sizeof(buffer), "--no-hpet");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->no_shconf_present) && p->no_shconf) {
- snprintf(buffer, sizeof(buffer), "--no-shconf");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->add_driver) {
- snprintf(buffer, sizeof(buffer), "-d%s", p->add_driver);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->socket_mem) {
- snprintf(buffer,
- sizeof(buffer),
- "--socket-mem=%s",
- p->socket_mem);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->huge_dir) {
- snprintf(buffer, sizeof(buffer), "--huge-dir=%s", p->huge_dir);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->file_prefix) {
- snprintf(buffer,
- sizeof(buffer),
- "--file-prefix=%s",
- p->file_prefix);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->base_virtaddr) {
- snprintf(buffer,
- sizeof(buffer),
- "--base-virtaddr=%s",
- p->base_virtaddr);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if ((p->create_uio_dev_present) && p->create_uio_dev) {
- snprintf(buffer, sizeof(buffer), "--create-uio-dev");
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- if (p->vfio_intr) {
- snprintf(buffer,
- sizeof(buffer),
- "--vfio-intr=%s",
- p->vfio_intr);
- app->eal_argv[n_args++] = strdup(buffer);
- }
-
- snprintf(buffer, sizeof(buffer), "--");
- app->eal_argv[n_args++] = strdup(buffer);
-
- app->eal_argc = n_args;
-
- APP_LOG(app, HIGH, "Initializing EAL ...");
- if (app->log_level >= APP_LOG_LEVEL_LOW) {
- int i;
-
- fprintf(stdout, "[APP] EAL arguments: \"");
- for (i = 1; i < app->eal_argc; i++)
- fprintf(stdout, "%s ", app->eal_argv[i]);
- fprintf(stdout, "\"\n");
- }
-
- status = rte_eal_init(app->eal_argc, app->eal_argv);
- if (status < 0)
- rte_panic("EAL init error\n");
-}
-
-static void
-app_init_mempool(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_mempools; i++) {
- struct app_mempool_params *p = &app->mempool_params[i];
-
- APP_LOG(app, HIGH, "Initializing %s ...", p->name);
- app->mempool[i] = rte_pktmbuf_pool_create(
- p->name,
- p->pool_size,
- p->cache_size,
- 0, /* priv_size */
- p->buffer_size -
- sizeof(struct rte_mbuf), /* mbuf data size */
- p->cpu_socket_id);
-
- if (app->mempool[i] == NULL)
- rte_panic("%s init error\n", p->name);
- }
-}
-
-static inline int
-app_link_filter_arp_add(struct app_link_params *link)
-{
- struct rte_eth_ethertype_filter filter = {
- .ether_type = ETHER_TYPE_ARP,
- .flags = 0,
- .queue = link->arp_q,
- };
-
- return rte_eth_dev_filter_ctrl(link->pmd_id,
- RTE_ETH_FILTER_ETHERTYPE,
- RTE_ETH_FILTER_ADD,
- &filter);
-}
-
-static inline int
-app_link_filter_tcp_syn_add(struct app_link_params *link)
-{
- struct rte_eth_syn_filter filter = {
- .hig_pri = 1,
- .queue = link->tcp_syn_q,
- };
-
- return rte_eth_dev_filter_ctrl(link->pmd_id,
- RTE_ETH_FILTER_SYN,
- RTE_ETH_FILTER_ADD,
- &filter);
-}
-
-static inline int
-app_link_filter_ip_add(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = 0,
- .proto_mask = 0, /* Disable */
- .tcp_flags = 0,
- .priority = 1, /* Lowest */
- .queue = l1->ip_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_ADD,
- &filter);
-}
-
-static inline int
-app_link_filter_ip_del(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = 0,
- .proto_mask = 0, /* Disable */
- .tcp_flags = 0,
- .priority = 1, /* Lowest */
- .queue = l1->ip_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_DELETE,
- &filter);
-}
-
-static inline int
-app_link_filter_tcp_add(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = IPPROTO_TCP,
- .proto_mask = UINT8_MAX, /* Enable */
- .tcp_flags = 0,
- .priority = 2, /* Higher priority than IP */
- .queue = l1->tcp_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_ADD,
- &filter);
-}
-
-static inline int
-app_link_filter_tcp_del(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = IPPROTO_TCP,
- .proto_mask = UINT8_MAX, /* Enable */
- .tcp_flags = 0,
- .priority = 2, /* Higher priority than IP */
- .queue = l1->tcp_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_DELETE,
- &filter);
-}
-
-static inline int
-app_link_filter_udp_add(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = IPPROTO_UDP,
- .proto_mask = UINT8_MAX, /* Enable */
- .tcp_flags = 0,
- .priority = 2, /* Higher priority than IP */
- .queue = l1->udp_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_ADD,
- &filter);
-}
-
-static inline int
-app_link_filter_udp_del(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = IPPROTO_UDP,
- .proto_mask = UINT8_MAX, /* Enable */
- .tcp_flags = 0,
- .priority = 2, /* Higher priority than IP */
- .queue = l1->udp_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_DELETE,
- &filter);
-}
-
-static inline int
-app_link_filter_sctp_add(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = IPPROTO_SCTP,
- .proto_mask = UINT8_MAX, /* Enable */
- .tcp_flags = 0,
- .priority = 2, /* Higher priority than IP */
- .queue = l1->sctp_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_ADD,
- &filter);
-}
-
-static inline int
-app_link_filter_sctp_del(struct app_link_params *l1, struct app_link_params *l2)
-{
- struct rte_eth_ntuple_filter filter = {
- .flags = RTE_5TUPLE_FLAGS,
- .dst_ip = rte_bswap32(l2->ip),
- .dst_ip_mask = UINT32_MAX, /* Enable */
- .src_ip = 0,
- .src_ip_mask = 0, /* Disable */
- .dst_port = 0,
- .dst_port_mask = 0, /* Disable */
- .src_port = 0,
- .src_port_mask = 0, /* Disable */
- .proto = IPPROTO_SCTP,
- .proto_mask = UINT8_MAX, /* Enable */
- .tcp_flags = 0,
- .priority = 2, /* Higher priority than IP */
- .queue = l1->sctp_local_q,
- };
-
- return rte_eth_dev_filter_ctrl(l1->pmd_id,
- RTE_ETH_FILTER_NTUPLE,
- RTE_ETH_FILTER_DELETE,
- &filter);
-}
-
-static void
-app_link_set_arp_filter(struct app_params *app, struct app_link_params *cp)
-{
- if (cp->arp_q != 0) {
- int status = app_link_filter_arp_add(cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32 "): "
- "Adding ARP filter (queue = %" PRIu32 ")",
- cp->name, cp->pmd_id, cp->arp_q);
-
- if (status)
- rte_panic("%s (%" PRIu32 "): "
- "Error adding ARP filter "
- "(queue = %" PRIu32 ") (%" PRId32 ")\n",
- cp->name, cp->pmd_id, cp->arp_q, status);
- }
-}
-
-static void
-app_link_set_tcp_syn_filter(struct app_params *app, struct app_link_params *cp)
-{
- if (cp->tcp_syn_q != 0) {
- int status = app_link_filter_tcp_syn_add(cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32 "): "
- "Adding TCP SYN filter (queue = %" PRIu32 ")",
- cp->name, cp->pmd_id, cp->tcp_syn_q);
-
- if (status)
- rte_panic("%s (%" PRIu32 "): "
- "Error adding TCP SYN filter "
- "(queue = %" PRIu32 ") (%" PRId32 ")\n",
- cp->name, cp->pmd_id, cp->tcp_syn_q,
- status);
- }
-}
-
-void
-app_link_up_internal(struct app_params *app, struct app_link_params *cp)
-{
- uint32_t i;
- int status;
-
- /* For each link, add filters for IP of current link */
- if (cp->ip != 0) {
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *p = &app->link_params[i];
-
- /* IP */
- if (p->ip_local_q != 0) {
- int status = app_link_filter_ip_add(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32 "): "
- "Adding IP filter (queue= %" PRIu32
- ", IP = 0x%08" PRIx32 ")",
- p->name, p->pmd_id, p->ip_local_q,
- cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32 "): "
- "Error adding IP "
- "filter (queue= %" PRIu32 ", "
- "IP = 0x%08" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id,
- p->ip_local_q, cp->ip, status);
- }
-
- /* TCP */
- if (p->tcp_local_q != 0) {
- int status = app_link_filter_tcp_add(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32 "): "
- "Adding TCP filter "
- "(queue = %" PRIu32
- ", IP = 0x%08" PRIx32 ")",
- p->name, p->pmd_id, p->tcp_local_q,
- cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32 "): "
- "Error adding TCP "
- "filter (queue = %" PRIu32 ", "
- "IP = 0x%08" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id,
- p->tcp_local_q, cp->ip, status);
- }
-
- /* UDP */
- if (p->udp_local_q != 0) {
- int status = app_link_filter_udp_add(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32 "): "
- "Adding UDP filter "
- "(queue = %" PRIu32
- ", IP = 0x%08" PRIx32 ")",
- p->name, p->pmd_id, p->udp_local_q,
- cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32 "): "
- "Error adding UDP "
- "filter (queue = %" PRIu32 ", "
- "IP = 0x%08" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id,
- p->udp_local_q, cp->ip, status);
- }
-
- /* SCTP */
- if (p->sctp_local_q != 0) {
- int status = app_link_filter_sctp_add(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32
- "): Adding SCTP filter "
- "(queue = %" PRIu32
- ", IP = 0x%08" PRIx32 ")",
- p->name, p->pmd_id, p->sctp_local_q,
- cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32 "): "
- "Error adding SCTP "
- "filter (queue = %" PRIu32 ", "
- "IP = 0x%08" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id,
- p->sctp_local_q, cp->ip,
- status);
- }
- }
- }
-
- /* PMD link up */
- status = rte_eth_dev_set_link_up(cp->pmd_id);
- /* Do not panic if PMD does not provide link up functionality */
- if (status < 0 && status != -ENOTSUP)
- rte_panic("%s (%" PRIu32 "): PMD set link up error %"
- PRId32 "\n", cp->name, cp->pmd_id, status);
-
- /* Mark link as UP */
- cp->state = 1;
-}
-
-void
-app_link_down_internal(struct app_params *app, struct app_link_params *cp)
-{
- uint32_t i;
- int status;
-
- /* PMD link down */
- status = rte_eth_dev_set_link_down(cp->pmd_id);
- /* Do not panic if PMD does not provide link down functionality */
- if (status < 0 && status != -ENOTSUP)
- rte_panic("%s (%" PRIu32 "): PMD set link down error %"
- PRId32 "\n", cp->name, cp->pmd_id, status);
-
- /* Mark link as DOWN */
- cp->state = 0;
-
- /* Return if current link IP is not valid */
- if (cp->ip == 0)
- return;
-
- /* For each link, remove filters for IP of current link */
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *p = &app->link_params[i];
-
- /* IP */
- if (p->ip_local_q != 0) {
- int status = app_link_filter_ip_del(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32
- "): Deleting IP filter "
- "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
- p->name, p->pmd_id, p->ip_local_q, cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32
- "): Error deleting IP filter "
- "(queue = %" PRIu32
- ", IP = 0x%" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id, p->ip_local_q,
- cp->ip, status);
- }
-
- /* TCP */
- if (p->tcp_local_q != 0) {
- int status = app_link_filter_tcp_del(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32
- "): Deleting TCP filter "
- "(queue = %" PRIu32
- ", IP = 0x%" PRIx32 ")",
- p->name, p->pmd_id, p->tcp_local_q, cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32
- "): Error deleting TCP filter "
- "(queue = %" PRIu32
- ", IP = 0x%" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id, p->tcp_local_q,
- cp->ip, status);
- }
-
- /* UDP */
- if (p->udp_local_q != 0) {
- int status = app_link_filter_udp_del(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32
- "): Deleting UDP filter "
- "(queue = %" PRIu32 ", IP = 0x%" PRIx32 ")",
- p->name, p->pmd_id, p->udp_local_q, cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32
- "): Error deleting UDP filter "
- "(queue = %" PRIu32
- ", IP = 0x%" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id, p->udp_local_q,
- cp->ip, status);
- }
-
- /* SCTP */
- if (p->sctp_local_q != 0) {
- int status = app_link_filter_sctp_del(p, cp);
-
- APP_LOG(app, LOW, "%s (%" PRIu32
- "): Deleting SCTP filter "
- "(queue = %" PRIu32
- ", IP = 0x%" PRIx32 ")",
- p->name, p->pmd_id, p->sctp_local_q, cp->ip);
-
- if (status)
- rte_panic("%s (%" PRIu32
- "): Error deleting SCTP filter "
- "(queue = %" PRIu32
- ", IP = 0x%" PRIx32
- ") (%" PRId32 ")\n",
- p->name, p->pmd_id, p->sctp_local_q,
- cp->ip, status);
- }
- }
-}
-
-static void
-app_check_link(struct app_params *app)
-{
- uint32_t all_links_up, i;
-
- all_links_up = 1;
-
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *p = &app->link_params[i];
- struct rte_eth_link link_params;
-
- memset(&link_params, 0, sizeof(link_params));
- rte_eth_link_get(p->pmd_id, &link_params);
-
- APP_LOG(app, HIGH, "%s (%" PRIu32 ") (%" PRIu32 " Gbps) %s",
- p->name,
- p->pmd_id,
- link_params.link_speed / 1000,
- link_params.link_status ? "UP" : "DOWN");
-
- if (link_params.link_status == ETH_LINK_DOWN)
- all_links_up = 0;
- }
-
- if (all_links_up == 0)
- rte_panic("Some links are DOWN\n");
-}
-
-static uint32_t
-is_any_swq_frag_or_ras(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_swq; i++) {
- struct app_pktq_swq_params *p = &app->swq_params[i];
-
- if ((p->ipv4_frag == 1) || (p->ipv6_frag == 1) ||
- (p->ipv4_ras == 1) || (p->ipv6_ras == 1))
- return 1;
- }
-
- return 0;
-}
-
-static void
-app_init_link_frag_ras(struct app_params *app)
-{
- uint32_t i;
-
- if (is_any_swq_frag_or_ras(app)) {
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *p_link = &app->link_params[i];
- p_link->conf.txmode.offloads |=
- DEV_TX_OFFLOAD_MULTI_SEGS;
- }
- }
-}
-
-static inline int
-app_get_cpu_socket_id(uint32_t pmd_id)
-{
- int status = rte_eth_dev_socket_id(pmd_id);
-
- return (status != SOCKET_ID_ANY) ? status : 0;
-}
-
-static inline int
-app_link_rss_enabled(struct app_link_params *cp)
-{
- return (cp->n_rss_qs) ? 1 : 0;
-}
-
-static void
-app_link_rss_setup(struct app_link_params *cp)
-{
- struct rte_eth_dev_info dev_info;
- struct rte_eth_rss_reta_entry64 reta_conf[APP_RETA_SIZE_MAX];
- uint32_t i;
- int status;
-
- /* Get RETA size */
- memset(&dev_info, 0, sizeof(dev_info));
- rte_eth_dev_info_get(cp->pmd_id, &dev_info);
-
- if (dev_info.reta_size == 0)
- rte_panic("%s (%u): RSS setup error (null RETA size)\n",
- cp->name, cp->pmd_id);
-
- if (dev_info.reta_size > ETH_RSS_RETA_SIZE_512)
- rte_panic("%s (%u): RSS setup error (RETA size too big)\n",
- cp->name, cp->pmd_id);
-
- /* Setup RETA contents */
- memset(reta_conf, 0, sizeof(reta_conf));
-
- for (i = 0; i < dev_info.reta_size; i++)
- reta_conf[i / RTE_RETA_GROUP_SIZE].mask = UINT64_MAX;
-
- for (i = 0; i < dev_info.reta_size; i++) {
- uint32_t reta_id = i / RTE_RETA_GROUP_SIZE;
- uint32_t reta_pos = i % RTE_RETA_GROUP_SIZE;
- uint32_t rss_qs_pos = i % cp->n_rss_qs;
-
- reta_conf[reta_id].reta[reta_pos] =
- (uint16_t) cp->rss_qs[rss_qs_pos];
- }
-
- /* RETA update */
- status = rte_eth_dev_rss_reta_update(cp->pmd_id,
- reta_conf,
- dev_info.reta_size);
- if (status != 0)
- rte_panic("%s (%u): RSS setup error (RETA update failed)\n",
- cp->name, cp->pmd_id);
-}
-
-static void
-app_init_link_set_config(struct app_link_params *p)
-{
- if (p->n_rss_qs) {
- p->conf.rxmode.mq_mode = ETH_MQ_RX_RSS;
- p->conf.rx_adv_conf.rss_conf.rss_hf = p->rss_proto_ipv4 |
- p->rss_proto_ipv6 |
- p->rss_proto_l2;
- }
-}
-
-static void
-app_init_link(struct app_params *app)
-{
- uint32_t i;
-
- app_init_link_frag_ras(app);
-
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *p_link = &app->link_params[i];
- struct rte_eth_dev_info dev_info;
- uint32_t link_id, n_hwq_in, n_hwq_out, j;
- int status;
-
- sscanf(p_link->name, "LINK%" PRIu32, &link_id);
- n_hwq_in = app_link_get_n_rxq(app, p_link);
- n_hwq_out = app_link_get_n_txq(app, p_link);
- app_init_link_set_config(p_link);
-
- APP_LOG(app, HIGH, "Initializing %s (%" PRIu32") "
- "(%" PRIu32 " RXQ, %" PRIu32 " TXQ) ...",
- p_link->name,
- p_link->pmd_id,
- n_hwq_in,
- n_hwq_out);
-
- /* LINK */
- rte_eth_dev_info_get(p_link->pmd_id, &dev_info);
- if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
- p_link->conf.txmode.offloads |=
- DEV_TX_OFFLOAD_MBUF_FAST_FREE;
- status = rte_eth_dev_configure(
- p_link->pmd_id,
- n_hwq_in,
- n_hwq_out,
- &p_link->conf);
- if (status < 0)
- rte_panic("%s (%" PRId32 "): "
- "init error (%" PRId32 ")\n",
- p_link->name, p_link->pmd_id, status);
-
- rte_eth_macaddr_get(p_link->pmd_id,
- (struct ether_addr *) &p_link->mac_addr);
-
- if (p_link->promisc)
- rte_eth_promiscuous_enable(p_link->pmd_id);
-
- /* RXQ */
- for (j = 0; j < app->n_pktq_hwq_in; j++) {
- struct app_pktq_hwq_in_params *p_rxq =
- &app->hwq_in_params[j];
- uint32_t rxq_link_id, rxq_queue_id;
- uint16_t nb_rxd = p_rxq->size;
-
- sscanf(p_rxq->name, "RXQ%" PRIu32 ".%" PRIu32,
- &rxq_link_id, &rxq_queue_id);
- if (rxq_link_id != link_id)
- continue;
-
- status = rte_eth_dev_adjust_nb_rx_tx_desc(
- p_link->pmd_id,
- &nb_rxd,
- NULL);
- if (status < 0)
- rte_panic("%s (%" PRIu32 "): "
- "%s adjust number of Rx descriptors "
- "error (%" PRId32 ")\n",
- p_link->name,
- p_link->pmd_id,
- p_rxq->name,
- status);
-
- p_rxq->conf.offloads = p_link->conf.rxmode.offloads;
- status = rte_eth_rx_queue_setup(
- p_link->pmd_id,
- rxq_queue_id,
- nb_rxd,
- app_get_cpu_socket_id(p_link->pmd_id),
- &p_rxq->conf,
- app->mempool[p_rxq->mempool_id]);
- if (status < 0)
- rte_panic("%s (%" PRIu32 "): "
- "%s init error (%" PRId32 ")\n",
- p_link->name,
- p_link->pmd_id,
- p_rxq->name,
- status);
- }
-
- /* TXQ */
- for (j = 0; j < app->n_pktq_hwq_out; j++) {
- struct app_pktq_hwq_out_params *p_txq =
- &app->hwq_out_params[j];
- uint32_t txq_link_id, txq_queue_id;
- uint16_t nb_txd = p_txq->size;
-
- sscanf(p_txq->name, "TXQ%" PRIu32 ".%" PRIu32,
- &txq_link_id, &txq_queue_id);
- if (txq_link_id != link_id)
- continue;
-
- status = rte_eth_dev_adjust_nb_rx_tx_desc(
- p_link->pmd_id,
- NULL,
- &nb_txd);
- if (status < 0)
- rte_panic("%s (%" PRIu32 "): "
- "%s adjust number of Tx descriptors "
- "error (%" PRId32 ")\n",
- p_link->name,
- p_link->pmd_id,
- p_txq->name,
- status);
-
- p_txq->conf.offloads = p_link->conf.txmode.offloads;
- status = rte_eth_tx_queue_setup(
- p_link->pmd_id,
- txq_queue_id,
- nb_txd,
- app_get_cpu_socket_id(p_link->pmd_id),
- &p_txq->conf);
- if (status < 0)
- rte_panic("%s (%" PRIu32 "): "
- "%s init error (%" PRId32 ")\n",
- p_link->name,
- p_link->pmd_id,
- p_txq->name,
- status);
- }
-
- /* LINK START */
- status = rte_eth_dev_start(p_link->pmd_id);
- if (status < 0)
- rte_panic("Cannot start %s (error %" PRId32 ")\n",
- p_link->name, status);
-
- /* LINK FILTERS */
- app_link_set_arp_filter(app, p_link);
- app_link_set_tcp_syn_filter(app, p_link);
- if (app_link_rss_enabled(p_link))
- app_link_rss_setup(p_link);
-
- /* LINK UP */
- app_link_up_internal(app, p_link);
- }
-
- app_check_link(app);
-}
-
-static void
-app_init_swq(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_swq; i++) {
- struct app_pktq_swq_params *p = &app->swq_params[i];
- unsigned flags = 0;
-
- if (app_swq_get_readers(app, p) == 1)
- flags |= RING_F_SC_DEQ;
- if (app_swq_get_writers(app, p) == 1)
- flags |= RING_F_SP_ENQ;
-
- APP_LOG(app, HIGH, "Initializing %s...", p->name);
- app->swq[i] = rte_ring_create(
- p->name,
- p->size,
- p->cpu_socket_id,
- flags);
-
- if (app->swq[i] == NULL)
- rte_panic("%s init error\n", p->name);
- }
-}
-
-static void
-app_init_tm(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_tm; i++) {
- struct app_pktq_tm_params *p_tm = &app->tm_params[i];
- struct app_link_params *p_link;
- struct rte_eth_link link_eth_params;
- struct rte_sched_port *sched;
- uint32_t n_subports, subport_id;
- int status;
-
- p_link = app_get_link_for_tm(app, p_tm);
- /* LINK */
- rte_eth_link_get(p_link->pmd_id, &link_eth_params);
-
- /* TM */
- p_tm->sched_port_params.name = p_tm->name;
- p_tm->sched_port_params.socket =
- app_get_cpu_socket_id(p_link->pmd_id);
- p_tm->sched_port_params.rate =
- (uint64_t) link_eth_params.link_speed * 1000 * 1000 / 8;
-
- APP_LOG(app, HIGH, "Initializing %s ...", p_tm->name);
- sched = rte_sched_port_config(&p_tm->sched_port_params);
- if (sched == NULL)
- rte_panic("%s init error\n", p_tm->name);
- app->tm[i] = sched;
-
- /* Subport */
- n_subports = p_tm->sched_port_params.n_subports_per_port;
- for (subport_id = 0; subport_id < n_subports; subport_id++) {
- uint32_t n_pipes_per_subport, pipe_id;
-
- status = rte_sched_subport_config(sched,
- subport_id,
- &p_tm->sched_subport_params[subport_id]);
- if (status)
- rte_panic("%s subport %" PRIu32
- " init error (%" PRId32 ")\n",
- p_tm->name, subport_id, status);
-
- /* Pipe */
- n_pipes_per_subport =
- p_tm->sched_port_params.n_pipes_per_subport;
- for (pipe_id = 0;
- pipe_id < n_pipes_per_subport;
- pipe_id++) {
- int profile_id = p_tm->sched_pipe_to_profile[
- subport_id * APP_MAX_SCHED_PIPES +
- pipe_id];
-
- if (profile_id == -1)
- continue;
-
- status = rte_sched_pipe_config(sched,
- subport_id,
- pipe_id,
- profile_id);
- if (status)
- rte_panic("%s subport %" PRIu32
- " pipe %" PRIu32
- " (profile %" PRId32 ") "
- "init error (% " PRId32 ")\n",
- p_tm->name, subport_id, pipe_id,
- profile_id, status);
- }
- }
- }
-}
-
-#ifndef RTE_EXEC_ENV_LINUXAPP
-static void
-app_init_tap(struct app_params *app) {
- if (app->n_pktq_tap == 0)
- return;
-
- rte_panic("TAP device not supported.\n");
-}
-#else
-static void
-app_init_tap(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pktq_tap; i++) {
- struct app_pktq_tap_params *p_tap = &app->tap_params[i];
- struct ifreq ifr;
- int fd, status;
-
- APP_LOG(app, HIGH, "Initializing %s ...", p_tap->name);
-
- fd = open("/dev/net/tun", O_RDWR | O_NONBLOCK);
- if (fd < 0)
- rte_panic("Cannot open file /dev/net/tun\n");
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
- snprintf(ifr.ifr_name, IFNAMSIZ, "%s", p_tap->name);
-
- status = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (status < 0)
- rte_panic("TAP setup error\n");
-
- app->tap[i] = fd;
- }
-}
-#endif
-
-#ifdef RTE_LIBRTE_KNI
-static int
-kni_config_network_interface(uint16_t port_id, uint8_t if_up) {
- int ret = 0;
-
- if (port_id >= rte_eth_dev_count())
- return -EINVAL;
-
- ret = (if_up) ?
- rte_eth_dev_set_link_up(port_id) :
- rte_eth_dev_set_link_down(port_id);
-
- return ret;
-}
-
-static int
-kni_change_mtu(uint16_t port_id, unsigned int new_mtu) {
- int ret;
-
- if (port_id >= rte_eth_dev_count())
- return -EINVAL;
-
- if (new_mtu > ETHER_MAX_LEN)
- return -EINVAL;
-
- /* Set new MTU */
- ret = rte_eth_dev_set_mtu(port_id, new_mtu);
- if (ret < 0)
- return ret;
-
- return 0;
-}
-#endif /* RTE_LIBRTE_KNI */
-
-#ifndef RTE_LIBRTE_KNI
-static void
-app_init_kni(struct app_params *app) {
- if (app->n_pktq_kni == 0)
- return;
-
- rte_panic("Can not init KNI without librte_kni support.\n");
-}
-#else
-static void
-app_init_kni(struct app_params *app) {
- uint32_t i;
-
- if (app->n_pktq_kni == 0)
- return;
-
- rte_kni_init(app->n_pktq_kni);
-
- for (i = 0; i < app->n_pktq_kni; i++) {
- struct app_pktq_kni_params *p_kni = &app->kni_params[i];
- struct app_link_params *p_link;
- struct rte_eth_dev_info dev_info;
- struct app_mempool_params *mempool_params;
- struct rte_mempool *mempool;
- struct rte_kni_conf conf;
- struct rte_kni_ops ops;
-
- /* LINK */
- p_link = app_get_link_for_kni(app, p_kni);
- memset(&dev_info, 0, sizeof(dev_info));
- rte_eth_dev_info_get(p_link->pmd_id, &dev_info);
-
- /* MEMPOOL */
- mempool_params = &app->mempool_params[p_kni->mempool_id];
- mempool = app->mempool[p_kni->mempool_id];
-
- /* KNI */
- memset(&conf, 0, sizeof(conf));
- snprintf(conf.name, RTE_KNI_NAMESIZE, "%s", p_kni->name);
- conf.force_bind = p_kni->force_bind;
- if (conf.force_bind) {
- int lcore_id;
-
- lcore_id = cpu_core_map_get_lcore_id(app->core_map,
- p_kni->socket_id,
- p_kni->core_id,
- p_kni->hyper_th_id);
-
- if (lcore_id < 0)
- rte_panic("%s invalid CPU core\n", p_kni->name);
-
- conf.core_id = (uint32_t) lcore_id;
- }
- conf.group_id = p_link->pmd_id;
- conf.mbuf_size = mempool_params->buffer_size;
- conf.addr = dev_info.pci_dev->addr;
- conf.id = dev_info.pci_dev->id;
-
- memset(&ops, 0, sizeof(ops));
- ops.port_id = (uint8_t) p_link->pmd_id;
- ops.change_mtu = kni_change_mtu;
- ops.config_network_if = kni_config_network_interface;
-
- APP_LOG(app, HIGH, "Initializing %s ...", p_kni->name);
- app->kni[i] = rte_kni_alloc(mempool, &conf, &ops);
- if (!app->kni[i])
- rte_panic("%s init error\n", p_kni->name);
- }
-}
-#endif /* RTE_LIBRTE_KNI */
-
-static void
-app_init_msgq(struct app_params *app)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_msgq; i++) {
- struct app_msgq_params *p = &app->msgq_params[i];
-
- APP_LOG(app, HIGH, "Initializing %s ...", p->name);
- app->msgq[i] = rte_ring_create(
- p->name,
- p->size,
- p->cpu_socket_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
-
- if (app->msgq[i] == NULL)
- rte_panic("%s init error\n", p->name);
- }
-}
-
-void app_pipeline_params_get(struct app_params *app,
- struct app_pipeline_params *p_in,
- struct pipeline_params *p_out)
-{
- uint32_t i;
-
- snprintf(p_out->name, PIPELINE_NAME_SIZE, "%s", p_in->name);
-
- snprintf(p_out->type, PIPELINE_TYPE_SIZE, "%s", p_in->type);
-
- p_out->socket_id = (int) p_in->socket_id;
-
- p_out->log_level = app->log_level;
-
- /* pktq_in */
- p_out->n_ports_in = p_in->n_pktq_in;
- for (i = 0; i < p_in->n_pktq_in; i++) {
- struct app_pktq_in_params *in = &p_in->pktq_in[i];
- struct pipeline_port_in_params *out = &p_out->port_in[i];
-
- switch (in->type) {
- case APP_PKTQ_IN_HWQ:
- {
- struct app_pktq_hwq_in_params *p_hwq_in =
- &app->hwq_in_params[in->id];
- struct app_link_params *p_link =
- app_get_link_for_rxq(app, p_hwq_in);
- uint32_t rxq_link_id, rxq_queue_id;
-
- sscanf(p_hwq_in->name, "RXQ%" SCNu32 ".%" SCNu32,
- &rxq_link_id,
- &rxq_queue_id);
-
- out->type = PIPELINE_PORT_IN_ETHDEV_READER;
- out->params.ethdev.port_id = p_link->pmd_id;
- out->params.ethdev.queue_id = rxq_queue_id;
- out->burst_size = p_hwq_in->burst;
- break;
- }
- case APP_PKTQ_IN_SWQ:
- {
- struct app_pktq_swq_params *swq_params = &app->swq_params[in->id];
-
- if ((swq_params->ipv4_frag == 0) && (swq_params->ipv6_frag == 0)) {
- if (app_swq_get_readers(app, swq_params) == 1) {
- out->type = PIPELINE_PORT_IN_RING_READER;
- out->params.ring.ring = app->swq[in->id];
- out->burst_size = app->swq_params[in->id].burst_read;
- } else {
- out->type = PIPELINE_PORT_IN_RING_MULTI_READER;
- out->params.ring_multi.ring = app->swq[in->id];
- out->burst_size = swq_params->burst_read;
- }
- } else {
- if (swq_params->ipv4_frag == 1) {
- struct rte_port_ring_reader_ipv4_frag_params *params =
- &out->params.ring_ipv4_frag;
-
- out->type = PIPELINE_PORT_IN_RING_READER_IPV4_FRAG;
- params->ring = app->swq[in->id];
- params->mtu = swq_params->mtu;
- params->metadata_size = swq_params->metadata_size;
- params->pool_direct =
- app->mempool[swq_params->mempool_direct_id];
- params->pool_indirect =
- app->mempool[swq_params->mempool_indirect_id];
- out->burst_size = swq_params->burst_read;
- } else {
- struct rte_port_ring_reader_ipv6_frag_params *params =
- &out->params.ring_ipv6_frag;
-
- out->type = PIPELINE_PORT_IN_RING_READER_IPV6_FRAG;
- params->ring = app->swq[in->id];
- params->mtu = swq_params->mtu;
- params->metadata_size = swq_params->metadata_size;
- params->pool_direct =
- app->mempool[swq_params->mempool_direct_id];
- params->pool_indirect =
- app->mempool[swq_params->mempool_indirect_id];
- out->burst_size = swq_params->burst_read;
- }
- }
- break;
- }
- case APP_PKTQ_IN_TM:
- {
- out->type = PIPELINE_PORT_IN_SCHED_READER;
- out->params.sched.sched = app->tm[in->id];
- out->burst_size = app->tm_params[in->id].burst_read;
- break;
- }
-#ifdef RTE_EXEC_ENV_LINUXAPP
- case APP_PKTQ_IN_TAP:
- {
- struct app_pktq_tap_params *tap_params =
- &app->tap_params[in->id];
- struct app_mempool_params *mempool_params =
- &app->mempool_params[tap_params->mempool_id];
- struct rte_mempool *mempool =
- app->mempool[tap_params->mempool_id];
-
- out->type = PIPELINE_PORT_IN_FD_READER;
- out->params.fd.fd = app->tap[in->id];
- out->params.fd.mtu = mempool_params->buffer_size;
- out->params.fd.mempool = mempool;
- out->burst_size = app->tap_params[in->id].burst_read;
- break;
- }
-#endif
-#ifdef RTE_LIBRTE_KNI
- case APP_PKTQ_IN_KNI:
- {
- out->type = PIPELINE_PORT_IN_KNI_READER;
- out->params.kni.kni = app->kni[in->id];
- out->burst_size = app->kni_params[in->id].burst_read;
- break;
- }
-#endif /* RTE_LIBRTE_KNI */
- case APP_PKTQ_IN_SOURCE:
- {
- uint32_t mempool_id =
- app->source_params[in->id].mempool_id;
-
- out->type = PIPELINE_PORT_IN_SOURCE;
- out->params.source.mempool = app->mempool[mempool_id];
- out->burst_size = app->source_params[in->id].burst;
- out->params.source.file_name =
- app->source_params[in->id].file_name;
- out->params.source.n_bytes_per_pkt =
- app->source_params[in->id].n_bytes_per_pkt;
- break;
- }
- default:
- break;
- }
- }
-
- /* pktq_out */
- p_out->n_ports_out = p_in->n_pktq_out;
- for (i = 0; i < p_in->n_pktq_out; i++) {
- struct app_pktq_out_params *in = &p_in->pktq_out[i];
- struct pipeline_port_out_params *out = &p_out->port_out[i];
-
- switch (in->type) {
- case APP_PKTQ_OUT_HWQ:
- {
- struct app_pktq_hwq_out_params *p_hwq_out =
- &app->hwq_out_params[in->id];
- struct app_link_params *p_link =
- app_get_link_for_txq(app, p_hwq_out);
- uint32_t txq_link_id, txq_queue_id;
-
- sscanf(p_hwq_out->name,
- "TXQ%" SCNu32 ".%" SCNu32,
- &txq_link_id,
- &txq_queue_id);
-
- if (p_hwq_out->dropless == 0) {
- struct rte_port_ethdev_writer_params *params =
- &out->params.ethdev;
-
- out->type = PIPELINE_PORT_OUT_ETHDEV_WRITER;
- params->port_id = p_link->pmd_id;
- params->queue_id = txq_queue_id;
- params->tx_burst_sz =
- app->hwq_out_params[in->id].burst;
- } else {
- struct rte_port_ethdev_writer_nodrop_params
- *params = &out->params.ethdev_nodrop;
-
- out->type =
- PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP;
- params->port_id = p_link->pmd_id;
- params->queue_id = txq_queue_id;
- params->tx_burst_sz = p_hwq_out->burst;
- params->n_retries = p_hwq_out->n_retries;
- }
- break;
- }
- case APP_PKTQ_OUT_SWQ:
- {
- struct app_pktq_swq_params *swq_params = &app->swq_params[in->id];
-
- if ((swq_params->ipv4_ras == 0) && (swq_params->ipv6_ras == 0)) {
- if (app_swq_get_writers(app, swq_params) == 1) {
- if (app->swq_params[in->id].dropless == 0) {
- struct rte_port_ring_writer_params *params =
- &out->params.ring;
-
- out->type = PIPELINE_PORT_OUT_RING_WRITER;
- params->ring = app->swq[in->id];
- params->tx_burst_sz =
- app->swq_params[in->id].burst_write;
- } else {
- struct rte_port_ring_writer_nodrop_params
- *params = &out->params.ring_nodrop;
-
- out->type =
- PIPELINE_PORT_OUT_RING_WRITER_NODROP;
- params->ring = app->swq[in->id];
- params->tx_burst_sz =
- app->swq_params[in->id].burst_write;
- params->n_retries =
- app->swq_params[in->id].n_retries;
- }
- } else {
- if (swq_params->dropless == 0) {
- struct rte_port_ring_multi_writer_params *params =
- &out->params.ring_multi;
-
- out->type = PIPELINE_PORT_OUT_RING_MULTI_WRITER;
- params->ring = app->swq[in->id];
- params->tx_burst_sz = swq_params->burst_write;
- } else {
- struct rte_port_ring_multi_writer_nodrop_params
- *params = &out->params.ring_multi_nodrop;
-
- out->type = PIPELINE_PORT_OUT_RING_MULTI_WRITER_NODROP;
- params->ring = app->swq[in->id];
- params->tx_burst_sz = swq_params->burst_write;
- params->n_retries = swq_params->n_retries;
- }
- }
- } else {
- if (swq_params->ipv4_ras == 1) {
- struct rte_port_ring_writer_ipv4_ras_params *params =
- &out->params.ring_ipv4_ras;
-
- out->type = PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS;
- params->ring = app->swq[in->id];
- params->tx_burst_sz = swq_params->burst_write;
- } else {
- struct rte_port_ring_writer_ipv6_ras_params *params =
- &out->params.ring_ipv6_ras;
-
- out->type = PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS;
- params->ring = app->swq[in->id];
- params->tx_burst_sz = swq_params->burst_write;
- }
- }
- break;
- }
- case APP_PKTQ_OUT_TM:
- {
- struct rte_port_sched_writer_params *params =
- &out->params.sched;
-
- out->type = PIPELINE_PORT_OUT_SCHED_WRITER;
- params->sched = app->tm[in->id];
- params->tx_burst_sz =
- app->tm_params[in->id].burst_write;
- break;
- }
-#ifdef RTE_EXEC_ENV_LINUXAPP
- case APP_PKTQ_OUT_TAP:
- {
- struct rte_port_fd_writer_params *params =
- &out->params.fd;
-
- out->type = PIPELINE_PORT_OUT_FD_WRITER;
- params->fd = app->tap[in->id];
- params->tx_burst_sz =
- app->tap_params[in->id].burst_write;
- break;
- }
-#endif
-#ifdef RTE_LIBRTE_KNI
- case APP_PKTQ_OUT_KNI:
- {
- struct app_pktq_kni_params *p_kni =
- &app->kni_params[in->id];
-
- if (p_kni->dropless == 0) {
- struct rte_port_kni_writer_params *params =
- &out->params.kni;
-
- out->type = PIPELINE_PORT_OUT_KNI_WRITER;
- params->kni = app->kni[in->id];
- params->tx_burst_sz =
- app->kni_params[in->id].burst_write;
- } else {
- struct rte_port_kni_writer_nodrop_params
- *params = &out->params.kni_nodrop;
-
- out->type = PIPELINE_PORT_OUT_KNI_WRITER_NODROP;
- params->kni = app->kni[in->id];
- params->tx_burst_sz =
- app->kni_params[in->id].burst_write;
- params->n_retries =
- app->kni_params[in->id].n_retries;
- }
- break;
- }
-#endif /* RTE_LIBRTE_KNI */
- case APP_PKTQ_OUT_SINK:
- {
- out->type = PIPELINE_PORT_OUT_SINK;
- out->params.sink.file_name =
- app->sink_params[in->id].file_name;
- out->params.sink.max_n_pkts =
- app->sink_params[in->id].
- n_pkts_to_dump;
-
- break;
- }
- default:
- break;
- }
- }
-
- /* msgq */
- p_out->n_msgq = p_in->n_msgq_in;
-
- for (i = 0; i < p_in->n_msgq_in; i++)
- p_out->msgq_in[i] = app->msgq[p_in->msgq_in[i]];
-
- for (i = 0; i < p_in->n_msgq_out; i++)
- p_out->msgq_out[i] = app->msgq[p_in->msgq_out[i]];
-
- /* args */
- p_out->n_args = p_in->n_args;
- for (i = 0; i < p_in->n_args; i++) {
- p_out->args_name[i] = p_in->args_name[i];
- p_out->args_value[i] = p_in->args_value[i];
- }
-}
-
-static void
-app_init_pipelines(struct app_params *app)
-{
- uint32_t p_id;
-
- for (p_id = 0; p_id < app->n_pipelines; p_id++) {
- struct app_pipeline_params *params =
- &app->pipeline_params[p_id];
- struct app_pipeline_data *data = &app->pipeline_data[p_id];
- struct pipeline_type *ptype;
- struct pipeline_params pp;
-
- APP_LOG(app, HIGH, "Initializing %s ...", params->name);
-
- ptype = app_pipeline_type_find(app, params->type);
- if (ptype == NULL)
- rte_panic("Init error: Unknown pipeline type \"%s\"\n",
- params->type);
-
- app_pipeline_params_get(app, params, &pp);
-
- /* Back-end */
- data->be = NULL;
- if (ptype->be_ops->f_init) {
- data->be = ptype->be_ops->f_init(&pp, (void *) app);
-
- if (data->be == NULL)
- rte_panic("Pipeline instance \"%s\" back-end "
- "init error\n", params->name);
- }
-
- /* Front-end */
- data->fe = NULL;
- if (ptype->fe_ops->f_init) {
- data->fe = ptype->fe_ops->f_init(&pp, (void *) app);
-
- if (data->fe == NULL)
- rte_panic("Pipeline instance \"%s\" front-end "
- "init error\n", params->name);
- }
-
- data->ptype = ptype;
-
- data->timer_period = (rte_get_tsc_hz() *
- params->timer_period) / 1000;
- }
-}
-
-static void
-app_post_init_pipelines(struct app_params *app)
-{
- uint32_t p_id;
-
- for (p_id = 0; p_id < app->n_pipelines; p_id++) {
- struct app_pipeline_params *params =
- &app->pipeline_params[p_id];
- struct app_pipeline_data *data = &app->pipeline_data[p_id];
- int status;
-
- if (data->ptype->fe_ops->f_post_init == NULL)
- continue;
-
- status = data->ptype->fe_ops->f_post_init(data->fe);
- if (status)
- rte_panic("Pipeline instance \"%s\" front-end "
- "post-init error\n", params->name);
- }
-}
-
-static void
-app_init_threads(struct app_params *app)
-{
- uint64_t time = rte_get_tsc_cycles();
- uint32_t p_id;
-
- for (p_id = 0; p_id < app->n_pipelines; p_id++) {
- struct app_pipeline_params *params =
- &app->pipeline_params[p_id];
- struct app_pipeline_data *data = &app->pipeline_data[p_id];
- struct pipeline_type *ptype;
- struct app_thread_data *t;
- struct app_thread_pipeline_data *p;
- int lcore_id;
-
- lcore_id = cpu_core_map_get_lcore_id(app->core_map,
- params->socket_id,
- params->core_id,
- params->hyper_th_id);
-
- if (lcore_id < 0)
- rte_panic("Invalid core s%" PRIu32 "c%" PRIu32 "%s\n",
- params->socket_id,
- params->core_id,
- (params->hyper_th_id) ? "h" : "");
-
- t = &app->thread_data[lcore_id];
-
- t->timer_period = (rte_get_tsc_hz() * APP_THREAD_TIMER_PERIOD) / 1000;
- t->thread_req_deadline = time + t->timer_period;
-
- t->headroom_cycles = 0;
- t->headroom_time = rte_get_tsc_cycles();
- t->headroom_ratio = 0.0;
-
- t->msgq_in = app_thread_msgq_in_get(app,
- params->socket_id,
- params->core_id,
- params->hyper_th_id);
- if (t->msgq_in == NULL)
- rte_panic("Init error: Cannot find MSGQ_IN for thread %" PRId32,
- lcore_id);
-
- t->msgq_out = app_thread_msgq_out_get(app,
- params->socket_id,
- params->core_id,
- params->hyper_th_id);
- if (t->msgq_out == NULL)
- rte_panic("Init error: Cannot find MSGQ_OUT for thread %" PRId32,
- lcore_id);
-
- ptype = app_pipeline_type_find(app, params->type);
- if (ptype == NULL)
- rte_panic("Init error: Unknown pipeline "
- "type \"%s\"\n", params->type);
-
- p = (ptype->be_ops->f_run == NULL) ?
- &t->regular[t->n_regular] :
- &t->custom[t->n_custom];
-
- p->pipeline_id = p_id;
- p->be = data->be;
- p->f_run = ptype->be_ops->f_run;
- p->f_timer = ptype->be_ops->f_timer;
- p->timer_period = data->timer_period;
- p->deadline = time + data->timer_period;
-
- data->enabled = 1;
-
- if (ptype->be_ops->f_run == NULL)
- t->n_regular++;
- else
- t->n_custom++;
- }
-}
-
-int app_init(struct app_params *app)
-{
- app_init_core_map(app);
- app_init_core_mask(app);
-
- app_init_eal(app);
- app_init_mempool(app);
- app_init_link(app);
- app_init_swq(app);
- app_init_tm(app);
- app_init_tap(app);
- app_init_kni(app);
- app_init_msgq(app);
-
- app_pipeline_common_cmd_push(app);
- app_pipeline_thread_cmd_push(app);
- app_pipeline_type_register(app, &pipeline_master);
- app_pipeline_type_register(app, &pipeline_passthrough);
- app_pipeline_type_register(app, &pipeline_flow_classification);
- app_pipeline_type_register(app, &pipeline_flow_actions);
- app_pipeline_type_register(app, &pipeline_firewall);
- app_pipeline_type_register(app, &pipeline_routing);
-
- app_init_pipelines(app);
- app_init_threads(app);
-
- return 0;
-}
-
-int app_post_init(struct app_params *app)
-{
- app_post_init_pipelines(app);
-
- return 0;
-}
-
-static int
-app_pipeline_type_cmd_push(struct app_params *app,
- struct pipeline_type *ptype)
-{
- cmdline_parse_ctx_t *cmds;
- uint32_t n_cmds, i;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (ptype == NULL))
- return -EINVAL;
-
- n_cmds = pipeline_type_cmds_count(ptype);
- if (n_cmds == 0)
- return 0;
-
- cmds = ptype->fe_ops->cmds;
-
- /* Check for available slots in the application commands array */
- if (n_cmds > APP_MAX_CMDS - app->n_cmds)
- return -ENOMEM;
-
- /* Push pipeline commands into the application */
- memcpy(&app->cmds[app->n_cmds],
- cmds,
- n_cmds * sizeof(cmdline_parse_ctx_t));
-
- for (i = 0; i < n_cmds; i++)
- app->cmds[app->n_cmds + i]->data = app;
-
- app->n_cmds += n_cmds;
- app->cmds[app->n_cmds] = NULL;
-
- return 0;
-}
-
-int
-app_pipeline_type_register(struct app_params *app, struct pipeline_type *ptype)
-{
- uint32_t n_cmds, i;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (ptype == NULL) ||
- (ptype->name == NULL) ||
- (strlen(ptype->name) == 0) ||
- (ptype->be_ops->f_init == NULL) ||
- (ptype->be_ops->f_timer == NULL))
- return -EINVAL;
-
- /* Check for duplicate entry */
- for (i = 0; i < app->n_pipeline_types; i++)
- if (strcmp(app->pipeline_type[i].name, ptype->name) == 0)
- return -EEXIST;
-
- /* Check for resource availability */
- n_cmds = pipeline_type_cmds_count(ptype);
- if ((app->n_pipeline_types == APP_MAX_PIPELINE_TYPES) ||
- (n_cmds > APP_MAX_CMDS - app->n_cmds))
- return -ENOMEM;
-
- /* Copy pipeline type */
- memcpy(&app->pipeline_type[app->n_pipeline_types++],
- ptype,
- sizeof(struct pipeline_type));
-
- /* Copy CLI commands */
- if (n_cmds)
- app_pipeline_type_cmd_push(app, ptype);
-
- return 0;
-}
-
-struct
-pipeline_type *app_pipeline_type_find(struct app_params *app, char *name)
-{
- uint32_t i;
-
- for (i = 0; i < app->n_pipeline_types; i++)
- if (strcmp(app->pipeline_type[i].name, name) == 0)
- return &app->pipeline_type[i];
-
- return NULL;
-}
diff --git a/examples/ip_pipeline/kni.c b/examples/ip_pipeline/kni.c
new file mode 100644
index 00000000..7e5ff054
--- /dev/null
+++ b/examples/ip_pipeline/kni.c
@@ -0,0 +1,175 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <rte_ethdev.h>
+#include <rte_bus_pci.h>
+#include <rte_string_fns.h>
+
+#include "kni.h"
+#include "mempool.h"
+#include "link.h"
+
+static struct kni_list kni_list;
+
+#ifndef KNI_MAX
+#define KNI_MAX 16
+#endif
+
+int
+kni_init(void)
+{
+ TAILQ_INIT(&kni_list);
+
+#ifdef RTE_LIBRTE_KNI
+ rte_kni_init(KNI_MAX);
+#endif
+
+ return 0;
+}
+
+struct kni *
+kni_find(const char *name)
+{
+ struct kni *kni;
+
+ if (name == NULL)
+ return NULL;
+
+ TAILQ_FOREACH(kni, &kni_list, node)
+ if (strcmp(kni->name, name) == 0)
+ return kni;
+
+ return NULL;
+}
+
+#ifndef RTE_LIBRTE_KNI
+
+struct kni *
+kni_create(const char *name __rte_unused,
+ struct kni_params *params __rte_unused)
+{
+ return NULL;
+}
+
+void
+kni_handle_request(void)
+{
+ return;
+}
+
+#else
+
+static int
+kni_config_network_interface(uint16_t port_id, uint8_t if_up)
+{
+ int ret = 0;
+
+ if (!rte_eth_dev_is_valid_port(port_id))
+ return -EINVAL;
+
+ ret = (if_up) ?
+ rte_eth_dev_set_link_up(port_id) :
+ rte_eth_dev_set_link_down(port_id);
+
+ return ret;
+}
+
+static int
+kni_change_mtu(uint16_t port_id, unsigned int new_mtu)
+{
+ int ret;
+
+ if (!rte_eth_dev_is_valid_port(port_id))
+ return -EINVAL;
+
+ if (new_mtu > ETHER_MAX_LEN)
+ return -EINVAL;
+
+ /* Set new MTU */
+ ret = rte_eth_dev_set_mtu(port_id, new_mtu);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+struct kni *
+kni_create(const char *name, struct kni_params *params)
+{
+ struct rte_eth_dev_info dev_info;
+ struct rte_kni_conf kni_conf;
+ struct rte_kni_ops kni_ops;
+ struct kni *kni;
+ struct mempool *mempool;
+ struct link *link;
+ struct rte_kni *k;
+ const struct rte_pci_device *pci_dev;
+ const struct rte_bus *bus = NULL;
+
+ /* Check input params */
+ if ((name == NULL) ||
+ kni_find(name) ||
+ (params == NULL))
+ return NULL;
+
+ mempool = mempool_find(params->mempool_name);
+ link = link_find(params->link_name);
+ if ((mempool == NULL) ||
+ (link == NULL))
+ return NULL;
+
+ /* Resource create */
+ rte_eth_dev_info_get(link->port_id, &dev_info);
+
+ memset(&kni_conf, 0, sizeof(kni_conf));
+ snprintf(kni_conf.name, RTE_KNI_NAMESIZE, "%s", name);
+ kni_conf.force_bind = params->force_bind;
+ kni_conf.core_id = params->thread_id;
+ kni_conf.group_id = link->port_id;
+ kni_conf.mbuf_size = mempool->buffer_size;
+ if (dev_info.device)
+ bus = rte_bus_find_by_device(dev_info.device);
+ if (bus && !strcmp(bus->name, "pci")) {
+ pci_dev = RTE_DEV_TO_PCI(dev_info.device);
+ kni_conf.addr = pci_dev->addr;
+ kni_conf.id = pci_dev->id;
+ }
+
+ memset(&kni_ops, 0, sizeof(kni_ops));
+ kni_ops.port_id = link->port_id;
+ kni_ops.config_network_if = kni_config_network_interface;
+ kni_ops.change_mtu = kni_change_mtu;
+
+ k = rte_kni_alloc(mempool->m, &kni_conf, &kni_ops);
+ if (k == NULL)
+ return NULL;
+
+ /* Node allocation */
+ kni = calloc(1, sizeof(struct kni));
+ if (kni == NULL)
+ return NULL;
+
+ /* Node fill in */
+ strlcpy(kni->name, name, sizeof(kni->name));
+ kni->k = k;
+
+ /* Node add to list */
+ TAILQ_INSERT_TAIL(&kni_list, kni, node);
+
+ return kni;
+}
+
+void
+kni_handle_request(void)
+{
+ struct kni *kni;
+
+ TAILQ_FOREACH(kni, &kni_list, node)
+ rte_kni_handle_request(kni->k);
+}
+
+#endif
diff --git a/examples/ip_pipeline/kni.h b/examples/ip_pipeline/kni.h
new file mode 100644
index 00000000..c3856456
--- /dev/null
+++ b/examples/ip_pipeline/kni.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _INCLUDE_KNI_H_
+#define _INCLUDE_KNI_H_
+
+#include <stdint.h>
+#include <sys/queue.h>
+
+#ifdef RTE_LIBRTE_KNI
+#include <rte_kni.h>
+#endif
+
+#include "common.h"
+
+struct kni {
+ TAILQ_ENTRY(kni) node;
+ char name[NAME_SIZE];
+#ifdef RTE_LIBRTE_KNI
+ struct rte_kni *k;
+#endif
+};
+
+TAILQ_HEAD(kni_list, kni);
+
+int
+kni_init(void);
+
+struct kni *
+kni_find(const char *name);
+
+struct kni_params {
+ const char *link_name;
+ const char *mempool_name;
+ int force_bind;
+ uint32_t thread_id;
+};
+
+struct kni *
+kni_create(const char *name, struct kni_params *params);
+
+void
+kni_handle_request(void);
+
+#endif /* _INCLUDE_KNI_H_ */
diff --git a/examples/ip_pipeline/link.c b/examples/ip_pipeline/link.c
new file mode 100644
index 00000000..392a890f
--- /dev/null
+++ b/examples/ip_pipeline/link.c
@@ -0,0 +1,267 @@
+/* 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 = ETH_MQ_RX_NONE,
+ .max_rx_pkt_len = 9000, /* Jumbo frame max packet len */
+ .split_hdr_size = 0, /* Header split buffer size */
+ .offloads = DEV_RX_OFFLOAD_CRC_STRIP,
+ },
+ .rx_adv_conf = {
+ .rss_conf = {
+ .rss_key = NULL,
+ .rss_key_len = 40,
+ .rss_hf = 0,
+ },
+ },
+ .txmode = {
+ .mq_mode = ETH_MQ_TX_NONE,
+ },
+ .lpbk_mode = 0,
+};
+
+#define RETA_CONF_SIZE (ETH_RSS_RETA_SIZE_512 / RTE_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_RETA_GROUP_SIZE].mask = UINT64_MAX;
+
+ for (i = 0; i < reta_size; i++) {
+ uint32_t reta_id = i / RTE_RETA_GROUP_SIZE;
+ uint32_t reta_pos = i % RTE_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;
+
+ rte_eth_dev_info_get(port_id, &port_info);
+
+ 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 > 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 = ETH_MQ_RX_RSS;
+ port_conf.rx_adv_conf.rss_conf.rss_hf =
+ (ETH_RSS_IP | ETH_RSS_TCP | 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)
+ rte_eth_promiscuous_enable(port_id);
+
+ /* 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 */
+ rte_eth_link_get(link->port_id, &link_params);
+
+ return (link_params.link_status == ETH_LINK_DOWN) ? 0 : 1;
+}
diff --git a/examples/ip_pipeline/link.h b/examples/ip_pipeline/link.h
new file mode 100644
index 00000000..34ff1149
--- /dev/null
+++ b/examples/ip_pipeline/link.h
@@ -0,0 +1,66 @@
+/* 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
index a44cf9a3..a69facee 100644
--- a/examples/ip_pipeline/main.c
+++ b/examples/ip_pipeline/main.c
@@ -1,35 +1,260 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
*/
-#include "app.h"
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <getopt.h>
-static struct app_params app;
+#include <rte_launch.h>
+#include <rte_eal.h>
+
+#include "cli.h"
+#include "conn.h"
+#include "kni.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)
{
- rte_openlog_stream(stderr);
+ 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;
+ };
- /* Config */
- app_config_init(&app);
+ /* Mempool */
+ status = mempool_init();
+ if (status) {
+ printf("Error: Mempool initialization failed (%d)\n", status);
+ return status;
+ }
- app_config_args(&app, argc, argv);
+ /* Link */
+ status = link_init();
+ if (status) {
+ printf("Error: Link initialization failed (%d)\n", status);
+ return status;
+ }
- app_config_preproc(&app);
+ /* SWQ */
+ status = swq_init();
+ if (status) {
+ printf("Error: SWQ initialization failed (%d)\n", status);
+ return status;
+ }
- app_config_parse(&app, app.parser_file);
+ /* Traffic Manager */
+ status = tmgr_init();
+ if (status) {
+ printf("Error: TMGR initialization failed (%d)\n", status);
+ return status;
+ }
- app_config_check(&app);
+ /* TAP */
+ status = tap_init();
+ if (status) {
+ printf("Error: TAP initialization failed (%d)\n", status);
+ return status;
+ }
- /* Init */
- app_init(&app);
+ /* KNI */
+ status = kni_init();
+ if (status) {
+ printf("Error: KNI 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;
+ }
- /* Run-time */
rte_eal_mp_remote_launch(
- app_thread,
- (void *) &app,
- CALL_MASTER);
+ thread_main,
+ NULL,
+ SKIP_MASTER);
- return 0;
+ /* 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);
+
+ kni_handle_request();
+ }
}
diff --git a/examples/ip_pipeline/mempool.c b/examples/ip_pipeline/mempool.c
new file mode 100644
index 00000000..f5d2a7d1
--- /dev/null
+++ b/examples/ip_pipeline/mempool.c
@@ -0,0 +1,82 @@
+/* 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
new file mode 100644
index 00000000..bd46a11c
--- /dev/null
+++ b/examples/ip_pipeline/mempool.h
@@ -0,0 +1,40 @@
+/* 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
index 748c9ae0..a9f2ea44 100644
--- a/examples/ip_pipeline/meson.build
+++ b/examples/ip_pipeline/meson.build
@@ -1,35 +1,25 @@
# SPDX-License-Identifier: BSD-3-Clause
-# Copyright(c) 2017 Intel Corporation
+# 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'
-deps += ['cfgfile', 'pipeline', 'bus_pci']
-includes += include_directories('pipeline')
+deps += ['pipeline', 'bus_pci']
+allow_experimental_apis = true
sources = files(
- 'config_check.c',
- 'config_parse.c',
- 'config_parse_tm.c',
- 'cpu_core_map.c',
- 'init.c',
+ 'action.c',
+ 'cli.c',
+ 'conn.c',
+ 'kni.c',
+ 'link.c',
'main.c',
+ 'mempool.c',
'parser.c',
+ 'pipeline.c',
+ 'swq.c',
+ 'tap.c',
'thread.c',
- 'thread_fe.c',
- 'pipeline/pipeline_common_be.c',
- 'pipeline/pipeline_common_fe.c',
- 'pipeline/pipeline_firewall_be.c',
- 'pipeline/pipeline_firewall.c',
- 'pipeline/pipeline_flow_actions_be.c',
- 'pipeline/pipeline_flow_actions.c',
- 'pipeline/pipeline_flow_classification_be.c',
- 'pipeline/pipeline_flow_classification.c',
- 'pipeline/pipeline_master_be.c',
- 'pipeline/pipeline_master.c',
- 'pipeline/pipeline_passthrough_be.c',
- 'pipeline/pipeline_passthrough.c',
- 'pipeline/pipeline_routing_be.c',
- 'pipeline/pipeline_routing.c',
+ 'tmgr.c'
)
diff --git a/examples/ip_pipeline/parser.c b/examples/ip_pipeline/parser.c
index 0901e9c6..ffcdeb3a 100644
--- a/examples/ip_pipeline/parser.c
+++ b/examples/ip_pipeline/parser.c
@@ -36,10 +36,8 @@
#include <sys/wait.h>
#include <rte_errno.h>
-#include <rte_cfgfile.h>
#include <rte_string_fns.h>
-#include "app.h"
#include "parser.h"
static uint32_t
@@ -596,10 +594,8 @@ parse_mac_addr(const char *token, struct ether_addr *addr)
}
int
-parse_pipeline_core(uint32_t *socket,
- uint32_t *core,
- uint32_t *ht,
- const char *entry)
+parse_cpu_core(const char *entry,
+ struct cpu_core_params *p)
{
size_t num_len;
char num[8];
@@ -609,6 +605,9 @@ parse_pipeline_core(uint32_t *socket,
const char *next = skip_white_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 */
@@ -682,8 +681,8 @@ parse_pipeline_core(uint32_t *socket,
}
}
- *socket = s;
- *core = c;
- *ht = h;
+ 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
index 5c421d27..261a8c85 100644
--- a/examples/ip_pipeline/parser.h
+++ b/examples/ip_pipeline/parser.h
@@ -50,6 +50,14 @@ int parse_ipv6_addr(const char *token, struct in6_addr *ipv6);
int parse_mac_addr(const char *token, struct 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
new file mode 100644
index 00000000..43fe8677
--- /dev/null
+++ b/examples/ip_pipeline/pipeline.c
@@ -0,0 +1,988 @@
+/* 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>
+#ifdef RTE_LIBRTE_KNI
+#include <rte_port_kni.h>
+#endif
+#include <rte_port_ring.h>
+#include <rte_port_source_sink.h>
+#include <rte_port_fd.h>
+#include <rte_port_sched.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 <rte_table_stub.h>
+
+#ifdef RTE_LIBRTE_KNI
+#include "kni.h"
+#endif
+#include "link.h"
+#include "mempool.h"
+#include "pipeline.h"
+#include "tap.h"
+#include "tmgr.h"
+#include "swq.h"
+
+#include "hash_func.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;
+#ifdef RTE_LIBRTE_KNI
+ struct rte_port_kni_reader_params kni;
+#endif
+ struct rte_port_source_params source;
+ } 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;
+ }
+
+#ifdef RTE_LIBRTE_KNI
+ case PORT_IN_KNI:
+ {
+ struct kni *kni;
+
+ kni = kni_find(params->dev_name);
+ if (kni == NULL)
+ return -1;
+
+ pp.kni.kni = kni->k;
+
+ p.ops = &rte_port_kni_reader_ops;
+ p.arg_create = &pp.kni;
+ break;
+ }
+#endif
+
+ 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;
+ }
+
+ 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;
+#ifdef RTE_LIBRTE_KNI
+ struct rte_port_kni_writer_params kni;
+#endif
+ struct rte_port_sink_params sink;
+ } 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;
+#ifdef RTE_LIBRTE_KNI
+ struct rte_port_kni_writer_nodrop_params kni;
+#endif
+ } 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;
+ }
+
+#ifdef RTE_LIBRTE_KNI
+ case PORT_OUT_KNI:
+ {
+ struct kni *kni;
+
+ kni = kni_find(params->dev_name);
+ if (kni == NULL)
+ return -1;
+
+ pp.kni.kni = kni->k;
+ pp.kni.tx_burst_sz = params->burst_size;
+
+ pp_nodrop.kni.kni = kni->k;
+ pp_nodrop.kni.tx_burst_sz = params->burst_size;
+ pp_nodrop.kni.n_retries = params->n_retries;
+
+ if (params->retry == 0) {
+ p.ops = &rte_port_kni_writer_ops;
+ p.arg_create = &pp.kni;
+ } else {
+ p.ops = &rte_port_kni_writer_nodrop_ops;
+ p.arg_create = &pp_nodrop.kni;
+ }
+ break;
+ }
+#endif
+
+ 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;
+ }
+
+ 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 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 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 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 ipv4_hdr) +
+ offsetof(struct 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 ipv4_hdr) +
+ offsetof(struct 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 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 ipv6_hdr, src_addr[0]),
+ },
+
+ [2] = {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = 2,
+ .input_index = 2,
+ .offset = offsetof(struct ipv6_hdr, src_addr[4]),
+ },
+
+ [3] = {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = 3,
+ .input_index = 3,
+ .offset = offsetof(struct ipv6_hdr, src_addr[8]),
+ },
+
+ [4] = {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = 4,
+ .input_index = 4,
+ .offset = offsetof(struct ipv6_hdr, src_addr[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 ipv6_hdr, dst_addr[0]),
+ },
+
+ [6] = {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = 6,
+ .input_index = 6,
+ .offset = offsetof(struct ipv6_hdr, dst_addr[4]),
+ },
+
+ [7] = {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = 7,
+ .input_index = 7,
+ .offset = offsetof(struct ipv6_hdr, dst_addr[8]),
+ },
+
+ [8] = {
+ .type = RTE_ACL_FIELD_TYPE_MASK,
+ .size = sizeof(uint32_t),
+ .field_index = 8,
+ .input_index = 8,
+ .offset = offsetof(struct ipv6_hdr, dst_addr[12]),
+ },
+
+ /* Source Port */
+ [9] = {
+ .type = RTE_ACL_FIELD_TYPE_RANGE,
+ .size = sizeof(uint16_t),
+ .field_index = 9,
+ .input_index = 9,
+ .offset = sizeof(struct ipv6_hdr) +
+ offsetof(struct 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 ipv6_hdr) +
+ offsetof(struct 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 = hash_default_key8;
+ break;
+ case 16:
+ f_hash = hash_default_key16;
+ break;
+ case 24:
+ f_hash = hash_default_key24;
+ break;
+ case 32:
+ f_hash = hash_default_key32;
+ break;
+ case 40:
+ f_hash = hash_default_key40;
+ break;
+ case 48:
+ f_hash = hash_default_key48;
+ break;
+ case 56:
+ f_hash = hash_default_key56;
+ break;
+ case 64:
+ f_hash = hash_default_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;
+ pipeline->n_tables++;
+
+ return 0;
+}
diff --git a/examples/ip_pipeline/pipeline.h b/examples/ip_pipeline/pipeline.h
index 7ca9cad6..a953a29f 100644
--- a/examples/ip_pipeline/pipeline.h
+++ b/examples/ip_pipeline/pipeline.h
@@ -1,73 +1,368 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
*/
-#ifndef __INCLUDE_PIPELINE_H__
-#define __INCLUDE_PIPELINE_H__
+#ifndef _INCLUDE_PIPELINE_H_
+#define _INCLUDE_PIPELINE_H_
-#include <cmdline_parse.h>
+#include <stdint.h>
+#include <sys/queue.h>
-#include "pipeline_be.h"
+#include <rte_pipeline.h>
+#include <rte_table_action.h>
-/*
- * Pipeline type front-end operations
- */
+#include "common.h"
+#include "action.h"
+
+struct pipeline_params {
+ uint32_t timer_period_ms;
+ uint32_t offset_port_id;
+ uint32_t cpu_id;
+};
-typedef void* (*pipeline_fe_op_init)(struct pipeline_params *params,
- void *arg);
+enum port_in_type {
+ PORT_IN_RXQ,
+ PORT_IN_SWQ,
+ PORT_IN_TMGR,
+ PORT_IN_TAP,
+ PORT_IN_KNI,
+ PORT_IN_SOURCE,
+};
-typedef int (*pipeline_fe_op_post_init)(void *pipeline);
+struct port_in_params {
+ /* Read */
+ enum port_in_type type;
+ const char *dev_name;
+ union {
+ struct {
+ uint16_t queue_id;
+ } rxq;
-typedef int (*pipeline_fe_op_free)(void *pipeline);
+ struct {
+ const char *mempool_name;
+ uint32_t mtu;
+ } tap;
-typedef int (*pipeline_fe_op_track)(struct pipeline_params *params,
- uint32_t port_in,
- uint32_t *port_out);
+ struct {
+ const char *mempool_name;
+ const char *file_name;
+ uint32_t n_bytes_per_pkt;
+ } source;
+ };
+ uint32_t burst_size;
-struct pipeline_fe_ops {
- pipeline_fe_op_init f_init;
- pipeline_fe_op_post_init f_post_init;
- pipeline_fe_op_free f_free;
- pipeline_fe_op_track f_track;
- cmdline_parse_ctx_t *cmds;
+ /* Action */
+ const char *action_profile_name;
};
-/*
- * Pipeline type
- */
+enum port_out_type {
+ PORT_OUT_TXQ,
+ PORT_OUT_SWQ,
+ PORT_OUT_TMGR,
+ PORT_OUT_TAP,
+ PORT_OUT_KNI,
+ PORT_OUT_SINK,
+};
+
+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;
+ };
+ uint32_t burst_size;
+ int retry;
+ uint32_t n_retries;
+};
+
+enum table_type {
+ TABLE_ACL,
+ TABLE_ARRAY,
+ TABLE_HASH,
+ TABLE_LPM,
+ TABLE_STUB,
+};
-struct pipeline_type {
- const char *name;
+struct table_acl_params {
+ uint32_t n_rules;
+ uint32_t ip_header_offset;
+ int ip_version;
+};
- /* pipeline back-end */
- struct pipeline_be_ops *be_ops;
+struct table_array_params {
+ uint32_t n_keys;
+ uint32_t key_offset;
+};
- /* pipeline front-end */
- struct pipeline_fe_ops *fe_ops;
+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;
};
-static inline uint32_t
-pipeline_type_cmds_count(struct pipeline_type *ptype)
-{
- cmdline_parse_ctx_t *cmds;
- uint32_t n_cmds;
+struct table_lpm_params {
+ uint32_t n_rules;
+ uint32_t key_offset;
+ uint32_t key_size;
+};
- if (ptype->fe_ops == NULL)
- return 0;
+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;
- cmds = ptype->fe_ops->cmds;
- if (cmds == NULL)
- return 0;
+ /* Action */
+ const char *action_profile_name;
+};
- for (n_cmds = 0; cmds[n_cmds]; n_cmds++);
+struct port_in {
+ struct port_in_params params;
+ struct port_in_action_profile *ap;
+ struct rte_port_in_action *a;
+};
- return n_cmds;
-}
+struct table {
+ struct table_params params;
+ struct table_action_profile *ap;
+ struct rte_table_action *a;
+};
+
+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
-parse_pipeline_core(uint32_t *socket,
- uint32_t *core,
- uint32_t *ht,
- const char *entry);
+pipeline_table_create(const char *pipeline_name,
+ struct table_params *params);
+struct table_rule_match_acl {
+ int ip_version;
+
+ RTE_STD_C11
+ union {
+ struct {
+ uint32_t sa;
+ uint32_t da;
+ } ipv4;
+
+ struct {
+ uint8_t sa[16];
+ uint8_t da[16];
+ } 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;
+
+ RTE_STD_C11
+ union {
+ uint32_t ipv4;
+ uint8_t ipv6[16];
+ };
+
+ 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;
+};
+
+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;
+};
+
+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,
+ void **data);
+
+int
+pipeline_table_rule_add_bulk(const char *pipeline_name,
+ uint32_t table_id,
+ struct table_rule_match *match,
+ struct table_rule_action *action,
+ void **data,
+ uint32_t *n_rules);
+
+int
+pipeline_table_rule_add_default(const char *pipeline_name,
+ uint32_t table_id,
+ struct table_rule_action *action,
+ void **data);
+
+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,
+ void *data,
+ 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,
+ void *data,
+ uint32_t tc_mask,
+ 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,
+ void *data,
+ struct rte_table_action_ttl_counters *stats,
+ int clear);
+
+#endif /* _INCLUDE_PIPELINE_H_ */
diff --git a/examples/ip_pipeline/pipeline/pipeline_actions_common.h b/examples/ip_pipeline/pipeline/pipeline_actions_common.h
deleted file mode 100644
index 23f88367..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_actions_common.h
+++ /dev/null
@@ -1,202 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-#ifndef __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
-#define __INCLUDE_PIPELINE_ACTIONS_COMMON_H__
-
-#include <stdint.h>
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_mbuf.h>
-#include <rte_pipeline.h>
-
-#define PIPELINE_PORT_IN_AH(f_ah, f_pkt_work, f_pkt4_work) \
-static int \
-f_ah( \
- __rte_unused struct rte_pipeline *p, \
- struct rte_mbuf **pkts, \
- uint32_t n_pkts, \
- void *arg) \
-{ \
- uint32_t i; \
- \
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) \
- f_pkt4_work(&pkts[i], arg); \
- \
- for ( ; i < n_pkts; i++) \
- f_pkt_work(pkts[i], arg); \
- \
- return 0; \
-}
-
-#define PIPELINE_PORT_IN_AH_HIJACK_ALL(f_ah, f_pkt_work, f_pkt4_work) \
-static int \
-f_ah( \
- struct rte_pipeline *p, \
- struct rte_mbuf **pkts, \
- uint32_t n_pkts, \
- void *arg) \
-{ \
- 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 & (~0x3LLU)); i += 4) \
- f_pkt4_work(&pkts[i], arg); \
- \
- for ( ; i < n_pkts; i++) \
- f_pkt_work(pkts[i], arg); \
- \
- return 0; \
-}
-
-#define PIPELINE_TABLE_AH_HIT(f_ah, f_pkt_work, f_pkt4_work) \
-static int \
-f_ah( \
- __rte_unused struct rte_pipeline *p, \
- struct rte_mbuf **pkts, \
- uint64_t pkts_in_mask, \
- struct rte_pipeline_table_entry **entries, \
- void *arg) \
-{ \
- if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
- uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
- uint32_t i; \
- \
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) \
- f_pkt4_work(&pkts[i], &entries[i], arg); \
- \
- for ( ; i < n_pkts; i++) \
- f_pkt_work(pkts[i], entries[i], arg); \
- } else \
- for ( ; pkts_in_mask; ) { \
- uint32_t pos = __builtin_ctzll(pkts_in_mask); \
- uint64_t pkt_mask = 1LLU << pos; \
- \
- pkts_in_mask &= ~pkt_mask; \
- f_pkt_work(pkts[pos], entries[pos], arg); \
- } \
- \
- return 0; \
-}
-
-#define PIPELINE_TABLE_AH_MISS(f_ah, f_pkt_work, f_pkt4_work) \
-static int \
-f_ah( \
- __rte_unused struct rte_pipeline *p, \
- struct rte_mbuf **pkts, \
- uint64_t pkts_in_mask, \
- struct rte_pipeline_table_entry *entry, \
- void *arg) \
-{ \
- if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
- uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
- uint32_t i; \
- \
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) \
- f_pkt4_work(&pkts[i], entry, arg); \
- \
- for ( ; i < n_pkts; i++) \
- f_pkt_work(pkts[i], entry, arg); \
- } else \
- for ( ; pkts_in_mask; ) { \
- uint32_t pos = __builtin_ctzll(pkts_in_mask); \
- uint64_t pkt_mask = 1LLU << pos; \
- \
- pkts_in_mask &= ~pkt_mask; \
- f_pkt_work(pkts[pos], entry, arg); \
- } \
- \
- return 0; \
-}
-
-#define PIPELINE_TABLE_AH_HIT_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work) \
-static int \
-f_ah( \
- struct rte_pipeline *p, \
- struct rte_mbuf **pkts, \
- uint64_t pkts_mask, \
- struct rte_pipeline_table_entry **entries, \
- void *arg) \
-{ \
- uint64_t pkts_in_mask = pkts_mask; \
- uint64_t pkts_out_mask = pkts_mask; \
- uint64_t time = rte_rdtsc(); \
- \
- if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
- uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
- uint32_t i; \
- \
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) { \
- uint64_t mask = f_pkt4_work(&pkts[i], \
- &entries[i], arg, time); \
- pkts_out_mask ^= mask << i; \
- } \
- \
- for ( ; i < n_pkts; i++) { \
- uint64_t mask = f_pkt_work(pkts[i], \
- entries[i], arg, time); \
- pkts_out_mask ^= mask << i; \
- } \
- } else \
- for ( ; pkts_in_mask; ) { \
- uint32_t pos = __builtin_ctzll(pkts_in_mask); \
- uint64_t pkt_mask = 1LLU << pos; \
- uint64_t mask = f_pkt_work(pkts[pos], \
- entries[pos], arg, time); \
- \
- pkts_in_mask &= ~pkt_mask; \
- pkts_out_mask ^= mask << pos; \
- } \
- \
- rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask); \
- \
- return 0; \
-}
-
-#define PIPELINE_TABLE_AH_MISS_DROP_TIME(f_ah, f_pkt_work, f_pkt4_work) \
-static int \
-f_ah( \
- struct rte_pipeline *p, \
- struct rte_mbuf **pkts, \
- uint64_t pkts_mask, \
- struct rte_pipeline_table_entry *entry, \
- void *arg) \
-{ \
- uint64_t pkts_in_mask = pkts_mask; \
- uint64_t pkts_out_mask = pkts_mask; \
- uint64_t time = rte_rdtsc(); \
- \
- if ((pkts_in_mask & (pkts_in_mask + 1)) == 0) { \
- uint64_t n_pkts = __builtin_popcountll(pkts_in_mask); \
- uint32_t i; \
- \
- for (i = 0; i < (n_pkts & (~0x3LLU)); i += 4) { \
- uint64_t mask = f_pkt4_work(&pkts[i], \
- entry, arg, time); \
- pkts_out_mask ^= mask << i; \
- } \
- \
- for ( ; i < n_pkts; i++) { \
- uint64_t mask = f_pkt_work(pkts[i], entry, arg, time);\
- pkts_out_mask ^= mask << i; \
- } \
- } else \
- for ( ; pkts_in_mask; ) { \
- uint32_t pos = __builtin_ctzll(pkts_in_mask); \
- uint64_t pkt_mask = 1LLU << pos; \
- uint64_t mask = f_pkt_work(pkts[pos], \
- entry, arg, time); \
- \
- pkts_in_mask &= ~pkt_mask; \
- pkts_out_mask ^= mask << pos; \
- } \
- \
- rte_pipeline_ah_packet_drop(p, pkts_out_mask ^ pkts_mask); \
- \
- return 0; \
-}
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_be.c b/examples/ip_pipeline/pipeline/pipeline_common_be.c
deleted file mode 100644
index 5d84989a..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_common_be.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include "pipeline_common_be.h"
-
-void *
-pipeline_msg_req_ping_handler(__rte_unused struct pipeline *p,
- void *msg)
-{
- struct pipeline_msg_rsp *rsp = msg;
-
- rsp->status = 0; /* OK */
-
- return rsp;
-}
-
-void *
-pipeline_msg_req_stats_port_in_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_stats_msg_req *req = msg;
- struct pipeline_stats_port_in_msg_rsp *rsp = msg;
- uint32_t port_id;
-
- /* Check request */
- if (req->id >= p->n_ports_in) {
- rsp->status = -1;
- return rsp;
- }
- port_id = p->port_in_id[req->id];
-
- /* Process request */
- rsp->status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- &rsp->stats,
- 1);
-
- return rsp;
-}
-
-void *
-pipeline_msg_req_stats_port_out_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_stats_msg_req *req = msg;
- struct pipeline_stats_port_out_msg_rsp *rsp = msg;
- uint32_t port_id;
-
- /* Check request */
- if (req->id >= p->n_ports_out) {
- rsp->status = -1;
- return rsp;
- }
- port_id = p->port_out_id[req->id];
-
- /* Process request */
- rsp->status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- &rsp->stats,
- 1);
-
- return rsp;
-}
-
-void *
-pipeline_msg_req_stats_table_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_stats_msg_req *req = msg;
- struct pipeline_stats_table_msg_rsp *rsp = msg;
- uint32_t table_id;
-
- /* Check request */
- if (req->id >= p->n_tables) {
- rsp->status = -1;
- return rsp;
- }
- table_id = p->table_id[req->id];
-
- /* Process request */
- rsp->status = rte_pipeline_table_stats_read(p->p,
- table_id,
- &rsp->stats,
- 1);
-
- return rsp;
-}
-
-void *
-pipeline_msg_req_port_in_enable_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_port_in_msg_req *req = msg;
- struct pipeline_msg_rsp *rsp = msg;
- uint32_t port_id;
-
- /* Check request */
- if (req->port_id >= p->n_ports_in) {
- rsp->status = -1;
- return rsp;
- }
- port_id = p->port_in_id[req->port_id];
-
- /* Process request */
- rsp->status = rte_pipeline_port_in_enable(p->p,
- port_id);
-
- return rsp;
-}
-
-void *
-pipeline_msg_req_port_in_disable_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_port_in_msg_req *req = msg;
- struct pipeline_msg_rsp *rsp = msg;
- uint32_t port_id;
-
- /* Check request */
- if (req->port_id >= p->n_ports_in) {
- rsp->status = -1;
- return rsp;
- }
- port_id = p->port_in_id[req->port_id];
-
- /* Process request */
- rsp->status = rte_pipeline_port_in_disable(p->p,
- port_id);
-
- return rsp;
-}
-
-void *
-pipeline_msg_req_invalid_handler(__rte_unused struct pipeline *p,
- void *msg)
-{
- struct pipeline_msg_rsp *rsp = msg;
-
- rsp->status = -1; /* Error */
-
- return rsp;
-}
-
-int
-pipeline_msg_req_handle(struct pipeline *p)
-{
- uint32_t msgq_id;
-
- for (msgq_id = 0; msgq_id < p->n_msgq; msgq_id++) {
- for ( ; ; ) {
- struct pipeline_msg_req *req;
- pipeline_msg_req_handler f_handle;
-
- req = pipeline_msg_recv(p, msgq_id);
- if (req == NULL)
- break;
-
- f_handle = (req->type < PIPELINE_MSG_REQS) ?
- p->handlers[req->type] :
- pipeline_msg_req_invalid_handler;
-
- if (f_handle == NULL)
- f_handle = pipeline_msg_req_invalid_handler;
-
- pipeline_msg_send(p,
- msgq_id,
- f_handle(p, (void *) req));
- }
- }
-
- return 0;
-}
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_be.h b/examples/ip_pipeline/pipeline/pipeline_common_be.h
deleted file mode 100644
index 83bd04e6..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_common_be.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_COMMON_BE_H__
-#define __INCLUDE_PIPELINE_COMMON_BE_H__
-
-#include <rte_common.h>
-#include <rte_ring.h>
-#include <rte_pipeline.h>
-
-#include "pipeline_be.h"
-
-struct pipeline;
-
-enum pipeline_msg_req_type {
- PIPELINE_MSG_REQ_PING = 0,
- PIPELINE_MSG_REQ_STATS_PORT_IN,
- PIPELINE_MSG_REQ_STATS_PORT_OUT,
- PIPELINE_MSG_REQ_STATS_TABLE,
- PIPELINE_MSG_REQ_PORT_IN_ENABLE,
- PIPELINE_MSG_REQ_PORT_IN_DISABLE,
- PIPELINE_MSG_REQ_CUSTOM,
- PIPELINE_MSG_REQS
-};
-
-typedef void *(*pipeline_msg_req_handler)(struct pipeline *p, void *msg);
-
-struct pipeline {
- struct rte_pipeline *p;
- uint32_t port_in_id[PIPELINE_MAX_PORT_IN];
- uint32_t port_out_id[PIPELINE_MAX_PORT_OUT];
- uint32_t table_id[PIPELINE_MAX_TABLES];
- struct rte_ring *msgq_in[PIPELINE_MAX_MSGQ_IN];
- struct rte_ring *msgq_out[PIPELINE_MAX_MSGQ_OUT];
-
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- uint32_t n_tables;
- uint32_t n_msgq;
-
- pipeline_msg_req_handler handlers[PIPELINE_MSG_REQS];
- char name[PIPELINE_NAME_SIZE];
- uint32_t log_level;
-};
-
-enum pipeline_log_level {
- PIPELINE_LOG_LEVEL_HIGH = 1,
- PIPELINE_LOG_LEVEL_LOW,
- PIPELINE_LOG_LEVELS
-};
-
-#define PLOG(p, level, fmt, ...) \
-do { \
- if (p->log_level >= PIPELINE_LOG_LEVEL_ ## level) \
- fprintf(stdout, "[%s] " fmt "\n", p->name, ## __VA_ARGS__);\
-} while (0)
-
-static inline void *
-pipeline_msg_recv(struct pipeline *p,
- uint32_t msgq_id)
-{
- struct rte_ring *r = p->msgq_in[msgq_id];
- void *msg;
- int status = rte_ring_sc_dequeue(r, &msg);
-
- if (status != 0)
- return NULL;
-
- return msg;
-}
-
-static inline void
-pipeline_msg_send(struct pipeline *p,
- uint32_t msgq_id,
- void *msg)
-{
- struct rte_ring *r = p->msgq_out[msgq_id];
- int status;
-
- do {
- status = rte_ring_sp_enqueue(r, msg);
- } while (status == -ENOBUFS);
-}
-
-struct pipeline_msg_req {
- enum pipeline_msg_req_type type;
-};
-
-struct pipeline_stats_msg_req {
- enum pipeline_msg_req_type type;
- uint32_t id;
-};
-
-struct pipeline_port_in_msg_req {
- enum pipeline_msg_req_type type;
- uint32_t port_id;
-};
-
-struct pipeline_custom_msg_req {
- enum pipeline_msg_req_type type;
- uint32_t subtype;
-};
-
-struct pipeline_msg_rsp {
- int status;
-};
-
-struct pipeline_stats_port_in_msg_rsp {
- int status;
- struct rte_pipeline_port_in_stats stats;
-};
-
-struct pipeline_stats_port_out_msg_rsp {
- int status;
- struct rte_pipeline_port_out_stats stats;
-};
-
-struct pipeline_stats_table_msg_rsp {
- int status;
- struct rte_pipeline_table_stats stats;
-};
-
-void *pipeline_msg_req_ping_handler(struct pipeline *p, void *msg);
-void *pipeline_msg_req_stats_port_in_handler(struct pipeline *p, void *msg);
-void *pipeline_msg_req_stats_port_out_handler(struct pipeline *p, void *msg);
-void *pipeline_msg_req_stats_table_handler(struct pipeline *p, void *msg);
-void *pipeline_msg_req_port_in_enable_handler(struct pipeline *p, void *msg);
-void *pipeline_msg_req_port_in_disable_handler(struct pipeline *p, void *msg);
-void *pipeline_msg_req_invalid_handler(struct pipeline *p, void *msg);
-
-int pipeline_msg_req_handle(struct pipeline *p);
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
deleted file mode 100644
index cc5214c7..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.c
+++ /dev/null
@@ -1,1455 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <cmdline_rdline.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-#include <cmdline.h>
-
-#include "pipeline_common_fe.h"
-#include "parser.h"
-
-struct app_link_params *
-app_pipeline_track_pktq_out_to_link(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t pktq_out_id)
-{
- struct app_pipeline_params *p;
-
- /* Check input arguments */
- if (app == NULL)
- return NULL;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if (p == NULL)
- return NULL;
-
- for ( ; ; ) {
- struct app_pktq_out_params *pktq_out =
- &p->pktq_out[pktq_out_id];
-
- switch (pktq_out->type) {
- case APP_PKTQ_OUT_HWQ:
- {
- struct app_pktq_hwq_out_params *hwq_out;
-
- hwq_out = &app->hwq_out_params[pktq_out->id];
-
- return app_get_link_for_txq(app, hwq_out);
- }
-
- case APP_PKTQ_OUT_SWQ:
- {
- struct pipeline_params pp;
- struct pipeline_type *ptype;
- struct app_pktq_swq_params *swq;
- uint32_t pktq_in_id;
- int status;
-
- swq = &app->swq_params[pktq_out->id];
- p = app_swq_get_reader(app, swq, &pktq_in_id);
- if (p == NULL)
- return NULL;
-
- ptype = app_pipeline_type_find(app, p->type);
- if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
- return NULL;
-
- app_pipeline_params_get(app, p, &pp);
- status = ptype->fe_ops->f_track(&pp,
- pktq_in_id,
- &pktq_out_id);
- if (status)
- return NULL;
-
- break;
- }
-
- case APP_PKTQ_OUT_TM:
- {
- struct pipeline_params pp;
- struct pipeline_type *ptype;
- struct app_pktq_tm_params *tm;
- uint32_t pktq_in_id;
- int status;
-
- tm = &app->tm_params[pktq_out->id];
- p = app_tm_get_reader(app, tm, &pktq_in_id);
- if (p == NULL)
- return NULL;
-
- ptype = app_pipeline_type_find(app, p->type);
- if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
- return NULL;
-
- app_pipeline_params_get(app, p, &pp);
- status = ptype->fe_ops->f_track(&pp,
- pktq_in_id,
- &pktq_out_id);
- if (status)
- return NULL;
-
- break;
- }
-
- case APP_PKTQ_OUT_KNI:
- {
- struct pipeline_params pp;
- struct pipeline_type *ptype;
- struct app_pktq_kni_params *kni;
- uint32_t pktq_in_id;
- int status;
-
- kni = &app->kni_params[pktq_out->id];
- p = app_kni_get_reader(app, kni, &pktq_in_id);
- if (p == NULL)
- return NULL;
-
- ptype = app_pipeline_type_find(app, p->type);
- if ((ptype == NULL) || (ptype->fe_ops->f_track == NULL))
- return NULL;
-
- app_pipeline_params_get(app, p, &pp);
- status = ptype->fe_ops->f_track(&pp,
- pktq_in_id,
- &pktq_out_id);
- if (status)
- return NULL;
-
- break;
- }
-
- case APP_PKTQ_OUT_TAP:
- case APP_PKTQ_OUT_SINK:
- default:
- return NULL;
- }
- }
-}
-
-int
-app_pipeline_track_default(struct pipeline_params *p,
- uint32_t port_in,
- uint32_t *port_out)
-{
- /* Check input arguments */
- if ((p == NULL) ||
- (port_in >= p->n_ports_in) ||
- (port_out == NULL))
- return -1;
-
- if (p->n_ports_out == 1) {
- *port_out = 0;
- return 0;
- }
-
- return -1;
-}
-
-int
-app_pipeline_ping(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_params *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status = 0;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if (p == NULL)
- return -1;
-
- /* Message buffer allocation */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- /* Fill in request */
- req->type = PIPELINE_MSG_REQ_PING;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Check response */
- status = rsp->status;
-
- /* Message buffer free */
- app_msg_free(app, rsp);
-
- return status;
-}
-
-int
-app_pipeline_stats_port_in(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats)
-{
- struct app_pipeline_params *p;
- struct pipeline_stats_msg_req *req;
- struct pipeline_stats_port_in_msg_rsp *rsp;
- int status = 0;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (stats == NULL))
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if ((p == NULL) ||
- (port_id >= p->n_pktq_in))
- return -1;
-
- /* Message buffer allocation */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- /* Fill in request */
- req->type = PIPELINE_MSG_REQ_STATS_PORT_IN;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = (struct pipeline_stats_port_in_msg_rsp *)
- app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Check response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->stats, sizeof(rsp->stats));
-
- /* Message buffer free */
- app_msg_free(app, rsp);
-
- return status;
-}
-
-int
-app_pipeline_stats_port_out(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats)
-{
- struct app_pipeline_params *p;
- struct pipeline_stats_msg_req *req;
- struct pipeline_stats_port_out_msg_rsp *rsp;
- int status = 0;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (pipeline_id >= app->n_pipelines) ||
- (stats == NULL))
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if ((p == NULL) ||
- (port_id >= p->n_pktq_out))
- return -1;
-
- /* Message buffer allocation */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- /* Fill in request */
- req->type = PIPELINE_MSG_REQ_STATS_PORT_OUT;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Check response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->stats, sizeof(rsp->stats));
-
- /* Message buffer free */
- app_msg_free(app, rsp);
-
- return status;
-}
-
-int
-app_pipeline_stats_table(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats)
-{
- struct app_pipeline_params *p;
- struct pipeline_stats_msg_req *req;
- struct pipeline_stats_table_msg_rsp *rsp;
- int status = 0;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (stats == NULL))
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if (p == NULL)
- return -1;
-
- /* Message buffer allocation */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- /* Fill in request */
- req->type = PIPELINE_MSG_REQ_STATS_TABLE;
- req->id = table_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Check response */
- status = rsp->status;
- if (status == 0)
- memcpy(stats, &rsp->stats, sizeof(rsp->stats));
-
- /* Message buffer free */
- app_msg_free(app, rsp);
-
- return status;
-}
-
-int
-app_pipeline_port_in_enable(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id)
-{
- struct app_pipeline_params *p;
- struct pipeline_port_in_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status = 0;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if ((p == NULL) ||
- (port_id >= p->n_pktq_in))
- return -1;
-
- /* Message buffer allocation */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- /* Fill in request */
- req->type = PIPELINE_MSG_REQ_PORT_IN_ENABLE;
- req->port_id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Check response */
- status = rsp->status;
-
- /* Message buffer free */
- app_msg_free(app, rsp);
-
- return status;
-}
-
-int
-app_pipeline_port_in_disable(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id)
-{
- struct app_pipeline_params *p;
- struct pipeline_port_in_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- int status = 0;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if ((p == NULL) ||
- (port_id >= p->n_pktq_in))
- return -1;
-
- /* Message buffer allocation */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- /* Fill in request */
- req->type = PIPELINE_MSG_REQ_PORT_IN_DISABLE;
- req->port_id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Check response */
- status = rsp->status;
-
- /* Message buffer free */
- app_msg_free(app, rsp);
-
- return status;
-}
-
-int
-app_link_set_op(struct app_params *app,
- uint32_t link_id,
- uint32_t pipeline_id,
- app_link_op op,
- void *arg)
-{
- struct app_pipeline_params *pp;
- struct app_link_params *lp;
- struct app_link_data *ld;
- uint32_t ppos, lpos;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (op == NULL))
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
- if (lp == NULL)
- return -1;
- lpos = lp - app->link_params;
- ld = &app->link_data[lpos];
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, pp);
- if (pp == NULL)
- return -1;
- ppos = pp - app->pipeline_params;
-
- ld->f_link[ppos] = op;
- ld->arg[ppos] = arg;
-
- return 0;
-}
-
-int
-app_link_config(struct app_params *app,
- uint32_t link_id,
- uint32_t ip,
- uint32_t depth)
-{
- struct app_link_params *p;
- uint32_t i, netmask, host, bcast;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
- if (p == NULL) {
- APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
- link_id);
- return -1;
- }
-
- if (p->state) {
- APP_LOG(app, HIGH, "%s is UP, please bring it DOWN first",
- p->name);
- return -1;
- }
-
- netmask = (~0U) << (32 - depth);
- host = ip & netmask;
- bcast = host | (~netmask);
-
- if ((ip == 0) ||
- (ip == UINT32_MAX) ||
- (ip == host) ||
- (ip == bcast)) {
- APP_LOG(app, HIGH, "Illegal IP address");
- return -1;
- }
-
- for (i = 0; i < app->n_links; i++) {
- struct app_link_params *link = &app->link_params[i];
-
- if (strcmp(p->name, link->name) == 0)
- continue;
-
- if (link->ip == ip) {
- APP_LOG(app, HIGH,
- "%s is already assigned this IP address",
- link->name);
- return -1;
- }
- }
-
- if ((depth == 0) || (depth > 32)) {
- APP_LOG(app, HIGH, "Illegal value for depth parameter "
- "(%" PRIu32 ")",
- depth);
- return -1;
- }
-
- /* Save link parameters */
- p->ip = ip;
- p->depth = depth;
-
- return 0;
-}
-
-int
-app_link_up(struct app_params *app,
- uint32_t link_id)
-{
- struct app_link_params *p;
- struct app_link_data *d;
- int i;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
- if (p == NULL) {
- APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
- link_id);
- return -1;
- }
-
- d = &app->link_data[p - app->link_params];
-
- /* Check link state */
- if (p->state) {
- APP_LOG(app, HIGH, "%s is already UP", p->name);
- return 0;
- }
-
- /* Check that IP address is valid */
- if (p->ip == 0) {
- APP_LOG(app, HIGH, "%s IP address is not set", p->name);
- return 0;
- }
-
- app_link_up_internal(app, p);
-
- /* Callbacks */
- for (i = 0; i < APP_MAX_PIPELINES; i++)
- if (d->f_link[i])
- d->f_link[i](app, link_id, 1, d->arg[i]);
-
- return 0;
-}
-
-int
-app_link_down(struct app_params *app,
- uint32_t link_id)
-{
- struct app_link_params *p;
- struct app_link_data *d;
- uint32_t i;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
- if (p == NULL) {
- APP_LOG(app, HIGH, "LINK%" PRIu32 " is not a valid link",
- link_id);
- return -1;
- }
-
- d = &app->link_data[p - app->link_params];
-
- /* Check link state */
- if (p->state == 0) {
- APP_LOG(app, HIGH, "%s is already DOWN", p->name);
- return 0;
- }
-
- app_link_down_internal(app, p);
-
- /* Callbacks */
- for (i = 0; i < APP_MAX_PIPELINES; i++)
- if (d->f_link[i])
- d->f_link[i](app, link_id, 0, d->arg[i]);
-
- return 0;
-}
-
-/*
- * ping
- */
-
-struct cmd_ping_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t ping_string;
-};
-
-static void
-cmd_ping_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_ping_result *params = parsed_result;
- struct app_params *app = data;
- int status;
-
- status = app_pipeline_ping(app, params->pipeline_id);
- if (status != 0)
- printf("Command failed\n");
-}
-
-static cmdline_parse_token_string_t cmd_ping_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_ping_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_ping_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_ping_result, pipeline_id, UINT32);
-
-static cmdline_parse_token_string_t cmd_ping_ping_string =
- TOKEN_STRING_INITIALIZER(struct cmd_ping_result, ping_string, "ping");
-
-static cmdline_parse_inst_t cmd_ping = {
- .f = cmd_ping_parsed,
- .data = NULL,
- .help_str = "Pipeline ping",
- .tokens = {
- (void *) &cmd_ping_p_string,
- (void *) &cmd_ping_pipeline_id,
- (void *) &cmd_ping_ping_string,
- NULL,
- },
-};
-
-/*
- * stats port in
- */
-
-struct cmd_stats_port_in_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t stats_string;
- cmdline_fixed_string_t port_string;
- cmdline_fixed_string_t in_string;
- uint32_t port_in_id;
-
-};
-
-static void
-cmd_stats_port_in_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_stats_port_in_result *params = parsed_result;
- struct app_params *app = data;
- struct rte_pipeline_port_in_stats stats;
- int status;
-
- status = app_pipeline_stats_port_in(app,
- params->pipeline_id,
- params->port_in_id,
- &stats);
-
- if (status != 0) {
- printf("Command failed\n");
- return;
- }
-
- /* Display stats */
- printf("Pipeline %" PRIu32 " - stats for input port %" PRIu32 ":\n"
- "\tPkts in: %" PRIu64 "\n"
- "\tPkts dropped by AH: %" PRIu64 "\n"
- "\tPkts dropped by other: %" PRIu64 "\n",
- params->pipeline_id,
- params->port_in_id,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-static cmdline_parse_token_string_t cmd_stats_port_in_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, p_string,
- "p");
-
-static cmdline_parse_token_num_t cmd_stats_port_in_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, pipeline_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_stats_port_in_stats_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, stats_string,
- "stats");
-
-static cmdline_parse_token_string_t cmd_stats_port_in_port_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, port_string,
- "port");
-
-static cmdline_parse_token_string_t cmd_stats_port_in_in_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_in_result, in_string,
- "in");
-
- cmdline_parse_token_num_t cmd_stats_port_in_port_in_id =
- TOKEN_NUM_INITIALIZER(struct cmd_stats_port_in_result, port_in_id,
- UINT32);
-
-static cmdline_parse_inst_t cmd_stats_port_in = {
- .f = cmd_stats_port_in_parsed,
- .data = NULL,
- .help_str = "Pipeline input port stats",
- .tokens = {
- (void *) &cmd_stats_port_in_p_string,
- (void *) &cmd_stats_port_in_pipeline_id,
- (void *) &cmd_stats_port_in_stats_string,
- (void *) &cmd_stats_port_in_port_string,
- (void *) &cmd_stats_port_in_in_string,
- (void *) &cmd_stats_port_in_port_in_id,
- NULL,
- },
-};
-
-/*
- * stats port out
- */
-
-struct cmd_stats_port_out_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t stats_string;
- cmdline_fixed_string_t port_string;
- cmdline_fixed_string_t out_string;
- uint32_t port_out_id;
-};
-
-static void
-cmd_stats_port_out_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
-
- struct cmd_stats_port_out_result *params = parsed_result;
- struct app_params *app = data;
- struct rte_pipeline_port_out_stats stats;
- int status;
-
- status = app_pipeline_stats_port_out(app,
- params->pipeline_id,
- params->port_out_id,
- &stats);
-
- if (status != 0) {
- printf("Command failed\n");
- return;
- }
-
- /* Display stats */
- printf("Pipeline %" PRIu32 " - stats for output port %" PRIu32 ":\n"
- "\tPkts in: %" PRIu64 "\n"
- "\tPkts dropped by AH: %" PRIu64 "\n"
- "\tPkts dropped by other: %" PRIu64 "\n",
- params->pipeline_id,
- params->port_out_id,
- stats.stats.n_pkts_in,
- stats.n_pkts_dropped_by_ah,
- stats.stats.n_pkts_drop);
-}
-
-static cmdline_parse_token_string_t cmd_stats_port_out_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, p_string,
- "p");
-
-static cmdline_parse_token_num_t cmd_stats_port_out_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, pipeline_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_stats_port_out_stats_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, stats_string,
- "stats");
-
-static cmdline_parse_token_string_t cmd_stats_port_out_port_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, port_string,
- "port");
-
-static cmdline_parse_token_string_t cmd_stats_port_out_out_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_port_out_result, out_string,
- "out");
-
-static cmdline_parse_token_num_t cmd_stats_port_out_port_out_id =
- TOKEN_NUM_INITIALIZER(struct cmd_stats_port_out_result, port_out_id,
- UINT32);
-
-static cmdline_parse_inst_t cmd_stats_port_out = {
- .f = cmd_stats_port_out_parsed,
- .data = NULL,
- .help_str = "Pipeline output port stats",
- .tokens = {
- (void *) &cmd_stats_port_out_p_string,
- (void *) &cmd_stats_port_out_pipeline_id,
- (void *) &cmd_stats_port_out_stats_string,
- (void *) &cmd_stats_port_out_port_string,
- (void *) &cmd_stats_port_out_out_string,
- (void *) &cmd_stats_port_out_port_out_id,
- NULL,
- },
-};
-
-/*
- * stats table
- */
-
-struct cmd_stats_table_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t stats_string;
- cmdline_fixed_string_t table_string;
- uint32_t table_id;
-};
-
-static void
-cmd_stats_table_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_stats_table_result *params = parsed_result;
- struct app_params *app = data;
- struct rte_pipeline_table_stats stats;
- int status;
-
- status = app_pipeline_stats_table(app,
- params->pipeline_id,
- params->table_id,
- &stats);
-
- if (status != 0) {
- printf("Command failed\n");
- return;
- }
-
- /* Display stats */
- printf("Pipeline %" PRIu32 " - stats for table %" PRIu32 ":\n"
- "\tPkts in: %" PRIu64 "\n"
- "\tPkts in with lookup miss: %" PRIu64 "\n"
- "\tPkts in with lookup hit dropped by AH: %" PRIu64 "\n"
- "\tPkts in with lookup hit dropped by others: %" PRIu64 "\n"
- "\tPkts in with lookup miss dropped by AH: %" PRIu64 "\n"
- "\tPkts in with lookup miss dropped by others: %" PRIu64 "\n",
- params->pipeline_id,
- params->table_id,
- 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);
-}
-
-static cmdline_parse_token_string_t cmd_stats_table_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, p_string,
- "p");
-
-static cmdline_parse_token_num_t cmd_stats_table_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, pipeline_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_stats_table_stats_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, stats_string,
- "stats");
-
-static cmdline_parse_token_string_t cmd_stats_table_table_string =
- TOKEN_STRING_INITIALIZER(struct cmd_stats_table_result, table_string,
- "table");
-
-static cmdline_parse_token_num_t cmd_stats_table_table_id =
- TOKEN_NUM_INITIALIZER(struct cmd_stats_table_result, table_id, UINT32);
-
-static cmdline_parse_inst_t cmd_stats_table = {
- .f = cmd_stats_table_parsed,
- .data = NULL,
- .help_str = "Pipeline table stats",
- .tokens = {
- (void *) &cmd_stats_table_p_string,
- (void *) &cmd_stats_table_pipeline_id,
- (void *) &cmd_stats_table_stats_string,
- (void *) &cmd_stats_table_table_string,
- (void *) &cmd_stats_table_table_id,
- NULL,
- },
-};
-
-/*
- * port in enable
- */
-
-struct cmd_port_in_enable_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t port_string;
- cmdline_fixed_string_t in_string;
- uint32_t port_in_id;
- cmdline_fixed_string_t enable_string;
-};
-
-static void
-cmd_port_in_enable_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_port_in_enable_result *params = parsed_result;
- struct app_params *app = data;
- int status;
-
- status = app_pipeline_port_in_enable(app,
- params->pipeline_id,
- params->port_in_id);
-
- if (status != 0)
- printf("Command failed\n");
-}
-
-static cmdline_parse_token_string_t cmd_port_in_enable_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, p_string,
- "p");
-
-static cmdline_parse_token_num_t cmd_port_in_enable_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, pipeline_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_port_in_enable_port_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, port_string,
- "port");
-
-static cmdline_parse_token_string_t cmd_port_in_enable_in_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result, in_string,
- "in");
-
-static cmdline_parse_token_num_t cmd_port_in_enable_port_in_id =
- TOKEN_NUM_INITIALIZER(struct cmd_port_in_enable_result, port_in_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_port_in_enable_enable_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_enable_result,
- enable_string, "enable");
-
-static cmdline_parse_inst_t cmd_port_in_enable = {
- .f = cmd_port_in_enable_parsed,
- .data = NULL,
- .help_str = "Pipeline input port enable",
- .tokens = {
- (void *) &cmd_port_in_enable_p_string,
- (void *) &cmd_port_in_enable_pipeline_id,
- (void *) &cmd_port_in_enable_port_string,
- (void *) &cmd_port_in_enable_in_string,
- (void *) &cmd_port_in_enable_port_in_id,
- (void *) &cmd_port_in_enable_enable_string,
- NULL,
- },
-};
-
-/*
- * port in disable
- */
-
-struct cmd_port_in_disable_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t port_string;
- cmdline_fixed_string_t in_string;
- uint32_t port_in_id;
- cmdline_fixed_string_t disable_string;
-};
-
-static void
-cmd_port_in_disable_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_port_in_disable_result *params = parsed_result;
- struct app_params *app = data;
- int status;
-
- status = app_pipeline_port_in_disable(app,
- params->pipeline_id,
- params->port_in_id);
-
- if (status != 0)
- printf("Command failed\n");
-}
-
-static cmdline_parse_token_string_t cmd_port_in_disable_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, p_string,
- "p");
-
-static cmdline_parse_token_num_t cmd_port_in_disable_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, pipeline_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_port_in_disable_port_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, port_string,
- "port");
-
-static cmdline_parse_token_string_t cmd_port_in_disable_in_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result, in_string,
- "in");
-
-static cmdline_parse_token_num_t cmd_port_in_disable_port_in_id =
- TOKEN_NUM_INITIALIZER(struct cmd_port_in_disable_result, port_in_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_port_in_disable_disable_string =
- TOKEN_STRING_INITIALIZER(struct cmd_port_in_disable_result,
- disable_string, "disable");
-
-static cmdline_parse_inst_t cmd_port_in_disable = {
- .f = cmd_port_in_disable_parsed,
- .data = NULL,
- .help_str = "Pipeline input port disable",
- .tokens = {
- (void *) &cmd_port_in_disable_p_string,
- (void *) &cmd_port_in_disable_pipeline_id,
- (void *) &cmd_port_in_disable_port_string,
- (void *) &cmd_port_in_disable_in_string,
- (void *) &cmd_port_in_disable_port_in_id,
- (void *) &cmd_port_in_disable_disable_string,
- NULL,
- },
-};
-
-/*
- * link config
- */
-
-static void
-print_link_info(struct app_link_params *p)
-{
- struct rte_eth_stats stats;
- struct ether_addr *mac_addr;
- uint32_t netmask = (~0U) << (32 - p->depth);
- uint32_t host = p->ip & netmask;
- uint32_t bcast = host | (~netmask);
-
- memset(&stats, 0, sizeof(stats));
- rte_eth_stats_get(p->pmd_id, &stats);
-
- mac_addr = (struct ether_addr *) &p->mac_addr;
-
- if (strlen(p->pci_bdf))
- printf("%s(%s): flags=<%s>\n",
- p->name,
- p->pci_bdf,
- (p->state) ? "UP" : "DOWN");
- else
- printf("%s: flags=<%s>\n",
- p->name,
- (p->state) ? "UP" : "DOWN");
-
- if (p->ip)
- printf("\tinet %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32
- " netmask %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32 " "
- "broadcast %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32 "\n",
- (p->ip >> 24) & 0xFF,
- (p->ip >> 16) & 0xFF,
- (p->ip >> 8) & 0xFF,
- p->ip & 0xFF,
- (netmask >> 24) & 0xFF,
- (netmask >> 16) & 0xFF,
- (netmask >> 8) & 0xFF,
- netmask & 0xFF,
- (bcast >> 24) & 0xFF,
- (bcast >> 16) & 0xFF,
- (bcast >> 8) & 0xFF,
- bcast & 0xFF);
-
- printf("\tether %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
- ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
- mac_addr->addr_bytes[0],
- mac_addr->addr_bytes[1],
- mac_addr->addr_bytes[2],
- mac_addr->addr_bytes[3],
- mac_addr->addr_bytes[4],
- mac_addr->addr_bytes[5]);
-
- printf("\tRX packets %" PRIu64
- " bytes %" PRIu64
- "\n",
- stats.ipackets,
- stats.ibytes);
-
- printf("\tRX errors %" PRIu64
- " missed %" PRIu64
- " no-mbuf %" PRIu64
- "\n",
- stats.ierrors,
- stats.imissed,
- stats.rx_nombuf);
-
- printf("\tTX packets %" PRIu64
- " bytes %" PRIu64 "\n",
- stats.opackets,
- stats.obytes);
-
- printf("\tTX errors %" PRIu64
- "\n",
- stats.oerrors);
-
- printf("\n");
-}
-
-/*
- * link
- *
- * link config:
- * link <linkid> config <ipaddr> <depth>
- *
- * link up:
- * link <linkid> up
- *
- * link down:
- * link <linkid> down
- *
- * link ls:
- * link ls
- */
-
-struct cmd_link_result {
- cmdline_fixed_string_t link_string;
- cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_link_parsed(
- void *parsed_result,
- __attribute__((unused)) struct cmdline *cl,
- void *data)
-{
- struct cmd_link_result *params = parsed_result;
- struct app_params *app = data;
-
- char *tokens[16];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- uint32_t link_id;
-
- status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
- if (status != 0) {
- printf(CMD_MSG_TOO_MANY_ARGS, "link");
- return;
- }
-
- /* link ls */
- if ((n_tokens == 1) && (strcmp(tokens[0], "ls") == 0)) {
- for (link_id = 0; link_id < app->n_links; link_id++) {
- struct app_link_params *p;
-
- APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, p);
- print_link_info(p);
- }
- return;
- } /* link ls */
-
- if (n_tokens < 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "link");
- return;
- }
-
- if (parser_read_uint32(&link_id, tokens[0])) {
- printf(CMD_MSG_INVALID_ARG, "linkid");
- return;
- }
-
- /* link config */
- if (strcmp(tokens[1], "config") == 0) {
- struct in_addr ipaddr_ipv4;
- uint32_t depth;
-
- if (n_tokens != 4) {
- printf(CMD_MSG_MISMATCH_ARGS, "link config");
- return;
- }
-
- if (parse_ipv4_addr(tokens[2], &ipaddr_ipv4)) {
- printf(CMD_MSG_INVALID_ARG, "ipaddr");
- return;
- }
-
- if (parser_read_uint32(&depth, tokens[3])) {
- printf(CMD_MSG_INVALID_ARG, "depth");
- return;
- }
-
- status = app_link_config(app,
- link_id,
- rte_be_to_cpu_32(ipaddr_ipv4.s_addr),
- depth);
- if (status)
- printf(CMD_MSG_FAIL, "link config");
-
- return;
- } /* link config */
-
- /* link up */
- if (strcmp(tokens[1], "up") == 0) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "link up");
- return;
- }
-
- status = app_link_up(app, link_id);
- if (status)
- printf(CMD_MSG_FAIL, "link up");
-
- return;
- } /* link up */
-
- /* link down */
- if (strcmp(tokens[1], "down") == 0) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "link down");
- return;
- }
-
- status = app_link_down(app, link_id);
- if (status)
- printf(CMD_MSG_FAIL, "link down");
-
- return;
- } /* link down */
-
- printf(CMD_MSG_MISMATCH_ARGS, "link");
-}
-
-static cmdline_parse_token_string_t cmd_link_link_string =
- TOKEN_STRING_INITIALIZER(struct cmd_link_result, link_string, "link");
-
-static cmdline_parse_token_string_t cmd_link_multi_string =
- TOKEN_STRING_INITIALIZER(struct cmd_link_result, multi_string,
- TOKEN_STRING_MULTI);
-
-static cmdline_parse_inst_t cmd_link = {
- .f = cmd_link_parsed,
- .data = NULL,
- .help_str = "link config / up / down / ls",
- .tokens = {
- (void *) &cmd_link_link_string,
- (void *) &cmd_link_multi_string,
- NULL,
- },
-};
-
-/*
- * quit
- */
-
-struct cmd_quit_result {
- cmdline_fixed_string_t quit;
-};
-
-static void
-cmd_quit_parsed(
- __rte_unused void *parsed_result,
- struct cmdline *cl,
- __rte_unused void *data)
-{
- cmdline_quit(cl);
-}
-
-static cmdline_parse_token_string_t cmd_quit_quit =
- TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit, "quit");
-
-static cmdline_parse_inst_t cmd_quit = {
- .f = cmd_quit_parsed,
- .data = NULL,
- .help_str = "Quit",
- .tokens = {
- (void *) &cmd_quit_quit,
- NULL,
- },
-};
-
-/*
- * run
- *
- * run <file>
- * run <file> [<count> [<interval>]]
- <count> default is 1
- * <interval> is measured in milliseconds, default is 1 second
- */
-
-static void
-app_run_file(
- cmdline_parse_ctx_t *ctx,
- const char *file_name)
-{
- struct cmdline *file_cl;
- int fd;
-
- fd = open(file_name, O_RDONLY);
- if (fd < 0) {
- printf("Cannot open file \"%s\"\n", file_name);
- return;
- }
-
- file_cl = cmdline_new(ctx, "", fd, 1);
- cmdline_interact(file_cl);
- close(fd);
-}
-
-struct cmd_run_result {
- cmdline_fixed_string_t run_string;
- cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_run_parsed(
- void *parsed_result,
- struct cmdline *cl,
- __attribute__((unused)) void *data)
-{
- struct cmd_run_result *params = parsed_result;
-
- char *tokens[16];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- char *file_name;
- uint32_t count, interval, i;
-
- status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
- if (status) {
- printf(CMD_MSG_TOO_MANY_ARGS, "run");
- return;
- }
-
- switch (n_tokens) {
- case 0:
- printf(CMD_MSG_NOT_ENOUGH_ARGS, "run");
- return;
-
- case 1:
- file_name = tokens[0];
- count = 1;
- interval = 1000;
- break;
-
- case 2:
- file_name = tokens[0];
-
- if (parser_read_uint32(&count, tokens[1]) ||
- (count == 0)) {
- printf(CMD_MSG_INVALID_ARG, "count");
- return;
- }
-
- interval = 1000;
- break;
-
- case 3:
- file_name = tokens[0];
-
- if (parser_read_uint32(&count, tokens[1]) ||
- (count == 0)) {
- printf(CMD_MSG_INVALID_ARG, "count");
- return;
- }
-
- if (parser_read_uint32(&interval, tokens[2]) ||
- (interval == 0)) {
- printf(CMD_MSG_INVALID_ARG, "interval");
- return;
- }
- break;
-
- default:
- printf(CMD_MSG_MISMATCH_ARGS, "run");
- return;
- }
-
- for (i = 0; i < count; i++) {
- app_run_file(cl->ctx, file_name);
- if (interval)
- usleep(interval * 1000);
- }
-}
-
-static cmdline_parse_token_string_t cmd_run_run_string =
- TOKEN_STRING_INITIALIZER(struct cmd_run_result, run_string, "run");
-
-static cmdline_parse_token_string_t cmd_run_multi_string =
- TOKEN_STRING_INITIALIZER(struct cmd_run_result, multi_string,
- TOKEN_STRING_MULTI);
-
-
-static cmdline_parse_inst_t cmd_run = {
- .f = cmd_run_parsed,
- .data = NULL,
- .help_str = "Run CLI script file",
- .tokens = {
- (void *) &cmd_run_run_string,
- (void *) &cmd_run_multi_string,
- NULL,
- },
-};
-
-static cmdline_parse_ctx_t pipeline_common_cmds[] = {
- (cmdline_parse_inst_t *) &cmd_quit,
- (cmdline_parse_inst_t *) &cmd_run,
- (cmdline_parse_inst_t *) &cmd_link,
- (cmdline_parse_inst_t *) &cmd_ping,
- (cmdline_parse_inst_t *) &cmd_stats_port_in,
- (cmdline_parse_inst_t *) &cmd_stats_port_out,
- (cmdline_parse_inst_t *) &cmd_stats_table,
- (cmdline_parse_inst_t *) &cmd_port_in_enable,
- (cmdline_parse_inst_t *) &cmd_port_in_disable,
- NULL,
-};
-
-int
-app_pipeline_common_cmd_push(struct app_params *app)
-{
- uint32_t n_cmds, i;
-
- /* Check for available slots in the application commands array */
- n_cmds = RTE_DIM(pipeline_common_cmds) - 1;
- if (n_cmds > APP_MAX_CMDS - app->n_cmds)
- return -ENOMEM;
-
- /* Push pipeline commands into the application */
- memcpy(&app->cmds[app->n_cmds],
- pipeline_common_cmds,
- n_cmds * sizeof(cmdline_parse_ctx_t));
-
- for (i = 0; i < n_cmds; i++)
- app->cmds[app->n_cmds + i]->data = app;
-
- app->n_cmds += n_cmds;
- app->cmds[app->n_cmds] = NULL;
-
- return 0;
-}
diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.h b/examples/ip_pipeline/pipeline/pipeline_common_fe.h
deleted file mode 100644
index 7227544f..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_common_fe.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_COMMON_FE_H__
-#define __INCLUDE_PIPELINE_COMMON_FE_H__
-
-#include <rte_common.h>
-#include <rte_cycles.h>
-#include <rte_malloc.h>
-#include <cmdline_parse.h>
-
-#include "pipeline_common_be.h"
-#include "pipeline.h"
-#include "app.h"
-
-#ifndef MSG_TIMEOUT_DEFAULT
-#define MSG_TIMEOUT_DEFAULT 1000
-#endif
-
-static inline struct app_pipeline_data *
-app_pipeline_data(struct app_params *app, uint32_t id)
-{
- struct app_pipeline_params *params;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", id, params);
- if (params == NULL)
- return NULL;
-
- return &app->pipeline_data[params - app->pipeline_params];
-}
-
-static inline void *
-app_pipeline_data_fe(struct app_params *app, uint32_t id, struct pipeline_type *ptype)
-{
- struct app_pipeline_data *pipeline_data;
-
- pipeline_data = app_pipeline_data(app, id);
- if (pipeline_data == NULL)
- return NULL;
-
- if (strcmp(pipeline_data->ptype->name, ptype->name) != 0)
- return NULL;
-
- if (pipeline_data->enabled == 0)
- return NULL;
-
- return pipeline_data->fe;
-}
-
-static inline struct rte_ring *
-app_pipeline_msgq_in_get(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_msgq_params *p;
-
- APP_PARAM_FIND_BY_ID(app->msgq_params,
- "MSGQ-REQ-PIPELINE",
- pipeline_id,
- p);
- if (p == NULL)
- return NULL;
-
- return app->msgq[p - app->msgq_params];
-}
-
-static inline struct rte_ring *
-app_pipeline_msgq_out_get(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_msgq_params *p;
-
- APP_PARAM_FIND_BY_ID(app->msgq_params,
- "MSGQ-RSP-PIPELINE",
- pipeline_id,
- p);
- if (p == NULL)
- return NULL;
-
- return app->msgq[p - app->msgq_params];
-}
-
-static inline void *
-app_msg_alloc(__rte_unused struct app_params *app)
-{
- return rte_malloc(NULL, 2048, RTE_CACHE_LINE_SIZE);
-}
-
-static inline void
-app_msg_free(__rte_unused struct app_params *app,
- void *msg)
-{
- rte_free(msg);
-}
-
-static inline void
-app_msg_send(struct app_params *app,
- uint32_t pipeline_id,
- void *msg)
-{
- struct rte_ring *r = app_pipeline_msgq_in_get(app, pipeline_id);
- int status;
-
- do {
- status = rte_ring_sp_enqueue(r, msg);
- } while (status == -ENOBUFS);
-}
-
-static inline void *
-app_msg_recv(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct rte_ring *r = app_pipeline_msgq_out_get(app, pipeline_id);
- void *msg;
- int status = rte_ring_sc_dequeue(r, &msg);
-
- if (status != 0)
- return NULL;
-
- return msg;
-}
-
-static inline void *
-app_msg_send_recv(struct app_params *app,
- uint32_t pipeline_id,
- void *msg,
- uint32_t timeout_ms)
-{
- struct rte_ring *r_req = app_pipeline_msgq_in_get(app, pipeline_id);
- struct rte_ring *r_rsp = app_pipeline_msgq_out_get(app, pipeline_id);
- uint64_t hz = rte_get_tsc_hz();
- void *msg_recv;
- uint64_t deadline;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(r_req, (void *) msg);
- } while (status == -ENOBUFS);
-
- /* recv */
- deadline = (timeout_ms) ?
- (rte_rdtsc() + ((hz * timeout_ms) / 1000)) :
- UINT64_MAX;
-
- do {
- if (rte_rdtsc() > deadline)
- return NULL;
-
- status = rte_ring_sc_dequeue(r_rsp, &msg_recv);
- } while (status != 0);
-
- return msg_recv;
-}
-
-struct app_link_params *
-app_pipeline_track_pktq_out_to_link(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t pktq_out_id);
-
-int
-app_pipeline_track_default(struct pipeline_params *params,
- uint32_t port_in,
- uint32_t *port_out);
-
-int
-app_pipeline_ping(struct app_params *app,
- uint32_t pipeline_id);
-
-int
-app_pipeline_stats_port_in(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats);
-
-int
-app_pipeline_stats_port_out(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats);
-
-int
-app_pipeline_stats_table(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats);
-
-int
-app_pipeline_port_in_enable(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id);
-
-int
-app_pipeline_port_in_disable(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id);
-
-int
-app_link_set_op(struct app_params *app,
- uint32_t link_id,
- uint32_t pipeline_id,
- app_link_op op,
- void *arg);
-
-int
-app_link_config(struct app_params *app,
- uint32_t link_id,
- uint32_t ip,
- uint32_t depth);
-
-int
-app_link_up(struct app_params *app,
- uint32_t link_id);
-
-int
-app_link_down(struct app_params *app,
- uint32_t link_id);
-
-int
-app_pipeline_common_cmd_push(struct app_params *app);
-
-#define CMD_MSG_OUT_OF_MEMORY "Not enough memory\n"
-#define CMD_MSG_NOT_ENOUGH_ARGS "Not enough arguments for command \"%s\"\n"
-#define CMD_MSG_TOO_MANY_ARGS "Too many arguments for command \"%s\"\n"
-#define CMD_MSG_MISMATCH_ARGS "Incorrect set of arguments for command \"%s\"\n"
-#define CMD_MSG_INVALID_ARG "Invalid value for argument \"%s\"\n"
-#define CMD_MSG_ARG_NOT_FOUND "Syntax error: \"%s\" not found\n"
-#define CMD_MSG_FILE_ERR "Error in file \"%s\" at line %u\n"
-#define CMD_MSG_FAIL "Command \"%s\" failed\n"
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c b/examples/ip_pipeline/pipeline/pipeline_firewall.c
deleted file mode 100644
index 0cae9d74..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
+++ /dev/null
@@ -1,1421 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-#include <errno.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/queue.h>
-#include <netinet/in.h>
-
-#include <rte_common.h>
-#include <rte_hexdump.h>
-#include <rte_malloc.h>
-#include <cmdline_rdline.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-
-#include "app.h"
-#include "pipeline_common_fe.h"
-#include "pipeline_firewall.h"
-#include "parser.h"
-
-struct app_pipeline_firewall_rule {
- struct pipeline_firewall_key key;
- int32_t priority;
- uint32_t port_id;
- void *entry_ptr;
-
- TAILQ_ENTRY(app_pipeline_firewall_rule) node;
-};
-
-struct app_pipeline_firewall {
- /* parameters */
- uint32_t n_ports_in;
- uint32_t n_ports_out;
-
- /* rules */
- TAILQ_HEAD(, app_pipeline_firewall_rule) rules;
- uint32_t n_rules;
- uint32_t default_rule_present;
- uint32_t default_rule_port_id;
- void *default_rule_entry_ptr;
-};
-
-static void
-print_firewall_ipv4_rule(struct app_pipeline_firewall_rule *rule)
-{
- printf("Prio = %" PRId32 " (SA = %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32 "/%" PRIu32 ", "
- "DA = %" PRIu32 ".%" PRIu32
- ".%"PRIu32 ".%" PRIu32 "/%" PRIu32 ", "
- "SP = %" PRIu32 "-%" PRIu32 ", "
- "DP = %" PRIu32 "-%" PRIu32 ", "
- "Proto = %" PRIu32 " / 0x%" PRIx32 ") => "
- "Port = %" PRIu32 " (entry ptr = %p)\n",
-
- rule->priority,
-
- (rule->key.key.ipv4_5tuple.src_ip >> 24) & 0xFF,
- (rule->key.key.ipv4_5tuple.src_ip >> 16) & 0xFF,
- (rule->key.key.ipv4_5tuple.src_ip >> 8) & 0xFF,
- rule->key.key.ipv4_5tuple.src_ip & 0xFF,
- rule->key.key.ipv4_5tuple.src_ip_mask,
-
- (rule->key.key.ipv4_5tuple.dst_ip >> 24) & 0xFF,
- (rule->key.key.ipv4_5tuple.dst_ip >> 16) & 0xFF,
- (rule->key.key.ipv4_5tuple.dst_ip >> 8) & 0xFF,
- rule->key.key.ipv4_5tuple.dst_ip & 0xFF,
- rule->key.key.ipv4_5tuple.dst_ip_mask,
-
- rule->key.key.ipv4_5tuple.src_port_from,
- rule->key.key.ipv4_5tuple.src_port_to,
-
- rule->key.key.ipv4_5tuple.dst_port_from,
- rule->key.key.ipv4_5tuple.dst_port_to,
-
- rule->key.key.ipv4_5tuple.proto,
- rule->key.key.ipv4_5tuple.proto_mask,
-
- rule->port_id,
- rule->entry_ptr);
-}
-
-static struct app_pipeline_firewall_rule *
-app_pipeline_firewall_rule_find(struct app_pipeline_firewall *p,
- struct pipeline_firewall_key *key)
-{
- struct app_pipeline_firewall_rule *r;
-
- TAILQ_FOREACH(r, &p->rules, node)
- if (memcmp(key,
- &r->key,
- sizeof(struct pipeline_firewall_key)) == 0)
- return r;
-
- return NULL;
-}
-
-static int
-app_pipeline_firewall_ls(
- struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_firewall *p;
- struct app_pipeline_firewall_rule *rule;
- uint32_t n_rules;
- int priority;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
- if (p == NULL)
- return -1;
-
- n_rules = p->n_rules;
- for (priority = 0; n_rules; priority++)
- TAILQ_FOREACH(rule, &p->rules, node)
- if (rule->priority == priority) {
- print_firewall_ipv4_rule(rule);
- n_rules--;
- }
-
- if (p->default_rule_present)
- printf("Default rule: port %" PRIu32 " (entry ptr = %p)\n",
- p->default_rule_port_id,
- p->default_rule_entry_ptr);
- else
- printf("Default rule: DROP\n");
-
- printf("\n");
-
- return 0;
-}
-
-static void*
-app_pipeline_firewall_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct app_pipeline_firewall *p;
- uint32_t size;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_firewall));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p == NULL)
- return NULL;
-
- /* Initialization */
- p->n_ports_in = params->n_ports_in;
- p->n_ports_out = params->n_ports_out;
-
- TAILQ_INIT(&p->rules);
- p->n_rules = 0;
- p->default_rule_present = 0;
- p->default_rule_port_id = 0;
- p->default_rule_entry_ptr = NULL;
-
- return (void *) p;
-}
-
-static int
-app_pipeline_firewall_free(void *pipeline)
-{
- struct app_pipeline_firewall *p = pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- while (!TAILQ_EMPTY(&p->rules)) {
- struct app_pipeline_firewall_rule *rule;
-
- rule = TAILQ_FIRST(&p->rules);
- TAILQ_REMOVE(&p->rules, rule, node);
- rte_free(rule);
- }
-
- rte_free(p);
- return 0;
-}
-
-static int
-app_pipeline_firewall_key_check_and_normalize(struct pipeline_firewall_key *key)
-{
- switch (key->type) {
- case PIPELINE_FIREWALL_IPV4_5TUPLE:
- {
- uint32_t src_ip_depth = key->key.ipv4_5tuple.src_ip_mask;
- uint32_t dst_ip_depth = key->key.ipv4_5tuple.dst_ip_mask;
- uint16_t src_port_from = key->key.ipv4_5tuple.src_port_from;
- uint16_t src_port_to = key->key.ipv4_5tuple.src_port_to;
- uint16_t dst_port_from = key->key.ipv4_5tuple.dst_port_from;
- uint16_t dst_port_to = key->key.ipv4_5tuple.dst_port_to;
-
- uint32_t src_ip_netmask = 0;
- uint32_t dst_ip_netmask = 0;
-
- if ((src_ip_depth > 32) ||
- (dst_ip_depth > 32) ||
- (src_port_from > src_port_to) ||
- (dst_port_from > dst_port_to))
- return -1;
-
- if (src_ip_depth)
- src_ip_netmask = (~0U) << (32 - src_ip_depth);
-
- if (dst_ip_depth)
- dst_ip_netmask = ((~0U) << (32 - dst_ip_depth));
-
- key->key.ipv4_5tuple.src_ip &= src_ip_netmask;
- key->key.ipv4_5tuple.dst_ip &= dst_ip_netmask;
-
- return 0;
- }
-
- default:
- return -1;
- }
-}
-
-int
-app_pipeline_firewall_load_file(char *filename,
- struct pipeline_firewall_key *keys,
- uint32_t *priorities,
- uint32_t *port_ids,
- uint32_t *n_keys,
- uint32_t *line)
-{
- FILE *f = NULL;
- char file_buf[1024];
- uint32_t i, l;
-
- /* Check input arguments */
- if ((filename == NULL) ||
- (keys == NULL) ||
- (priorities == NULL) ||
- (port_ids == NULL) ||
- (n_keys == NULL) ||
- (*n_keys == 0) ||
- (line == NULL)) {
- if (line)
- *line = 0;
- return -1;
- }
-
- /* Open input file */
- f = fopen(filename, "r");
- if (f == NULL) {
- *line = 0;
- return -1;
- }
-
- /* Read file */
- for (i = 0, l = 1; i < *n_keys; l++) {
- char *tokens[32];
- uint32_t n_tokens = RTE_DIM(tokens);
-
- uint32_t priority = 0;
- struct in_addr sipaddr;
- uint32_t sipdepth = 0;
- struct in_addr dipaddr;
- uint32_t dipdepth = 0;
- uint16_t sport0 = 0;
- uint16_t sport1 = 0;
- uint16_t dport0 = 0;
- uint16_t dport1 = 0;
- uint8_t proto = 0;
- uint8_t protomask = 0;
- uint32_t port_id = 0;
-
- int status;
-
- if (fgets(file_buf, sizeof(file_buf), f) == NULL)
- break;
-
- status = parse_tokenize_string(file_buf, tokens, &n_tokens);
- if (status)
- goto error1;
-
- if ((n_tokens == 0) || (tokens[0][0] == '#'))
- continue;
-
- if ((n_tokens != 15) ||
- strcmp(tokens[0], "priority") ||
- parser_read_uint32(&priority, tokens[1]) ||
- strcmp(tokens[2], "ipv4") ||
- parse_ipv4_addr(tokens[3], &sipaddr) ||
- parser_read_uint32(&sipdepth, tokens[4]) ||
- parse_ipv4_addr(tokens[5], &dipaddr) ||
- parser_read_uint32(&dipdepth, tokens[6]) ||
- parser_read_uint16(&sport0, tokens[7]) ||
- parser_read_uint16(&sport1, tokens[8]) ||
- parser_read_uint16(&dport0, tokens[9]) ||
- parser_read_uint16(&dport1, tokens[10]) ||
- parser_read_uint8(&proto, tokens[11]) ||
- parser_read_uint8_hex(&protomask, tokens[12]) ||
- strcmp(tokens[13], "port") ||
- parser_read_uint32(&port_id, tokens[14]))
- goto error1;
-
- keys[i].type = PIPELINE_FIREWALL_IPV4_5TUPLE;
- keys[i].key.ipv4_5tuple.src_ip =
- rte_be_to_cpu_32(sipaddr.s_addr);
- keys[i].key.ipv4_5tuple.src_ip_mask = sipdepth;
- keys[i].key.ipv4_5tuple.dst_ip =
- rte_be_to_cpu_32(dipaddr.s_addr);
- keys[i].key.ipv4_5tuple.dst_ip_mask = dipdepth;
- keys[i].key.ipv4_5tuple.src_port_from = sport0;
- keys[i].key.ipv4_5tuple.src_port_to = sport1;
- keys[i].key.ipv4_5tuple.dst_port_from = dport0;
- keys[i].key.ipv4_5tuple.dst_port_to = dport1;
- keys[i].key.ipv4_5tuple.proto = proto;
- keys[i].key.ipv4_5tuple.proto_mask = protomask;
-
- port_ids[i] = port_id;
- priorities[i] = priority;
-
- if (app_pipeline_firewall_key_check_and_normalize(&keys[i]))
- goto error1;
-
- i++;
- }
-
- /* Close file */
- *n_keys = i;
- fclose(f);
- return 0;
-
-error1:
- *line = l;
- fclose(f);
- return -1;
-}
-
-int
-app_pipeline_firewall_add_rule(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *key,
- uint32_t priority,
- uint32_t port_id)
-{
- struct app_pipeline_firewall *p;
- struct app_pipeline_firewall_rule *rule;
- struct pipeline_firewall_add_msg_req *req;
- struct pipeline_firewall_add_msg_rsp *rsp;
- int new_rule;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL) ||
- (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
- if (p == NULL)
- return -1;
-
- if (port_id >= p->n_ports_out)
- return -1;
-
- if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
- return -1;
-
- /* Find existing rule or allocate new rule */
- rule = app_pipeline_firewall_rule_find(p, key);
- new_rule = (rule == NULL);
- if (rule == NULL) {
- rule = rte_malloc(NULL, sizeof(*rule), RTE_CACHE_LINE_SIZE);
-
- if (rule == NULL)
- return -1;
- }
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL) {
- if (new_rule)
- rte_free(rule);
- return -1;
- }
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD;
- memcpy(&req->key, key, sizeof(*key));
- req->priority = priority;
- req->port_id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL) {
- if (new_rule)
- rte_free(rule);
- return -1;
- }
-
- /* Read response and write rule */
- if (rsp->status ||
- (rsp->entry_ptr == NULL) ||
- ((new_rule == 0) && (rsp->key_found == 0)) ||
- ((new_rule == 1) && (rsp->key_found == 1))) {
- app_msg_free(app, rsp);
- if (new_rule)
- rte_free(rule);
- return -1;
- }
-
- memcpy(&rule->key, key, sizeof(*key));
- rule->priority = priority;
- rule->port_id = port_id;
- rule->entry_ptr = rsp->entry_ptr;
-
- /* Commit rule */
- if (new_rule) {
- TAILQ_INSERT_TAIL(&p->rules, rule, node);
- p->n_rules++;
- }
-
- print_firewall_ipv4_rule(rule);
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_firewall_delete_rule(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *key)
-{
- struct app_pipeline_firewall *p;
- struct app_pipeline_firewall_rule *rule;
- struct pipeline_firewall_del_msg_req *req;
- struct pipeline_firewall_del_msg_rsp *rsp;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL) ||
- (key->type != PIPELINE_FIREWALL_IPV4_5TUPLE))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
- if (p == NULL)
- return -1;
-
- if (app_pipeline_firewall_key_check_and_normalize(key) != 0)
- return -1;
-
- /* Find rule */
- rule = app_pipeline_firewall_rule_find(p, key);
- if (rule == NULL)
- return 0;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL;
- memcpy(&req->key, key, sizeof(*key));
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status || !rsp->key_found) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Remove rule */
- TAILQ_REMOVE(&p->rules, rule, node);
- p->n_rules--;
- rte_free(rule);
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_firewall_add_bulk(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *keys,
- uint32_t n_keys,
- uint32_t *priorities,
- uint32_t *port_ids)
-{
- struct app_pipeline_firewall *p;
- struct pipeline_firewall_add_bulk_msg_req *req;
- struct pipeline_firewall_add_bulk_msg_rsp *rsp;
-
- struct app_pipeline_firewall_rule **rules;
- int *new_rules;
-
- int *keys_found;
- void **entries_ptr;
-
- uint32_t i;
- int status = 0;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
- if (p == NULL)
- return -1;
-
- rules = rte_malloc(NULL,
- n_keys * sizeof(struct app_pipeline_firewall_rule *),
- RTE_CACHE_LINE_SIZE);
- if (rules == NULL)
- return -1;
-
- new_rules = rte_malloc(NULL,
- n_keys * sizeof(int),
- RTE_CACHE_LINE_SIZE);
- if (new_rules == NULL) {
- rte_free(rules);
- return -1;
- }
-
- /* check data integrity and add to rule list */
- for (i = 0; i < n_keys; i++) {
- if (port_ids[i] >= p->n_ports_out) {
- rte_free(rules);
- rte_free(new_rules);
- return -1;
- }
-
- if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
- rte_free(rules);
- rte_free(new_rules);
- return -1;
- }
-
- rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
- new_rules[i] = (rules[i] == NULL);
- if (rules[i] == NULL) {
- rules[i] = rte_malloc(NULL,
- sizeof(*rules[i]),
- RTE_CACHE_LINE_SIZE);
-
- if (rules[i] == NULL) {
- uint32_t j;
-
- for (j = 0; j <= i; j++)
- if (new_rules[j])
- rte_free(rules[j]);
-
- rte_free(rules);
- rte_free(new_rules);
- return -1;
- }
- }
- }
-
- keys_found = rte_malloc(NULL,
- n_keys * sizeof(int),
- RTE_CACHE_LINE_SIZE);
- if (keys_found == NULL) {
- uint32_t j;
-
- for (j = 0; j < n_keys; j++)
- if (new_rules[j])
- rte_free(rules[j]);
-
- rte_free(rules);
- rte_free(new_rules);
- return -1;
- }
-
- entries_ptr = rte_malloc(NULL,
- n_keys * sizeof(struct rte_pipeline_table_entry *),
- RTE_CACHE_LINE_SIZE);
- if (entries_ptr == NULL) {
- uint32_t j;
-
- for (j = 0; j < n_keys; j++)
- if (new_rules[j])
- rte_free(rules[j]);
-
- rte_free(rules);
- rte_free(new_rules);
- rte_free(keys_found);
- return -1;
- }
- for (i = 0; i < n_keys; i++) {
- entries_ptr[i] = rte_malloc(NULL,
- sizeof(struct rte_pipeline_table_entry),
- RTE_CACHE_LINE_SIZE);
-
- if (entries_ptr[i] == NULL) {
- uint32_t j;
-
- for (j = 0; j < n_keys; j++)
- if (new_rules[j])
- rte_free(rules[j]);
-
- for (j = 0; j <= i; j++)
- rte_free(entries_ptr[j]);
-
- rte_free(rules);
- rte_free(new_rules);
- rte_free(keys_found);
- rte_free(entries_ptr);
- return -1;
- }
- }
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL) {
- uint32_t j;
-
- for (j = 0; j < n_keys; j++)
- if (new_rules[j])
- rte_free(rules[j]);
-
- for (j = 0; j < n_keys; j++)
- rte_free(entries_ptr[j]);
-
- rte_free(rules);
- rte_free(new_rules);
- rte_free(keys_found);
- rte_free(entries_ptr);
- return -1;
- }
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_BULK;
-
- req->keys = keys;
- req->n_keys = n_keys;
- req->port_ids = port_ids;
- req->priorities = priorities;
- req->keys_found = keys_found;
- req->entries_ptr = entries_ptr;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL) {
- uint32_t j;
-
- for (j = 0; j < n_keys; j++)
- if (new_rules[j])
- rte_free(rules[j]);
-
- for (j = 0; j < n_keys; j++)
- rte_free(entries_ptr[j]);
-
- rte_free(rules);
- rte_free(new_rules);
- rte_free(keys_found);
- rte_free(entries_ptr);
- return -1;
- }
-
- if (rsp->status) {
- for (i = 0; i < n_keys; i++)
- if (new_rules[i])
- rte_free(rules[i]);
-
- for (i = 0; i < n_keys; i++)
- rte_free(entries_ptr[i]);
-
- status = -1;
- goto cleanup;
- }
-
- for (i = 0; i < n_keys; i++) {
- if (entries_ptr[i] == NULL ||
- ((new_rules[i] == 0) && (keys_found[i] == 0)) ||
- ((new_rules[i] == 1) && (keys_found[i] == 1))) {
- for (i = 0; i < n_keys; i++)
- if (new_rules[i])
- rte_free(rules[i]);
-
- for (i = 0; i < n_keys; i++)
- rte_free(entries_ptr[i]);
-
- status = -1;
- goto cleanup;
- }
- }
-
- for (i = 0; i < n_keys; i++) {
- memcpy(&rules[i]->key, &keys[i], sizeof(keys[i]));
- rules[i]->priority = priorities[i];
- rules[i]->port_id = port_ids[i];
- rules[i]->entry_ptr = entries_ptr[i];
-
- /* Commit rule */
- if (new_rules[i]) {
- TAILQ_INSERT_TAIL(&p->rules, rules[i], node);
- p->n_rules++;
- }
-
- print_firewall_ipv4_rule(rules[i]);
- }
-
-cleanup:
- app_msg_free(app, rsp);
- rte_free(rules);
- rte_free(new_rules);
- rte_free(keys_found);
- rte_free(entries_ptr);
-
- return status;
-}
-
-int
-app_pipeline_firewall_delete_bulk(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *keys,
- uint32_t n_keys)
-{
- struct app_pipeline_firewall *p;
- struct pipeline_firewall_del_bulk_msg_req *req;
- struct pipeline_firewall_del_bulk_msg_rsp *rsp;
-
- struct app_pipeline_firewall_rule **rules;
- int *keys_found;
-
- uint32_t i;
- int status = 0;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
- if (p == NULL)
- return -1;
-
- rules = rte_malloc(NULL,
- n_keys * sizeof(struct app_pipeline_firewall_rule *),
- RTE_CACHE_LINE_SIZE);
- if (rules == NULL)
- return -1;
-
- for (i = 0; i < n_keys; i++) {
- if (app_pipeline_firewall_key_check_and_normalize(&keys[i]) != 0) {
- return -1;
- }
-
- rules[i] = app_pipeline_firewall_rule_find(p, &keys[i]);
- }
-
- keys_found = rte_malloc(NULL,
- n_keys * sizeof(int),
- RTE_CACHE_LINE_SIZE);
- if (keys_found == NULL) {
- rte_free(rules);
- return -1;
- }
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL) {
- rte_free(rules);
- rte_free(keys_found);
- return -1;
- }
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_BULK;
-
- req->keys = keys;
- req->n_keys = n_keys;
- req->keys_found = keys_found;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL) {
- rte_free(rules);
- rte_free(keys_found);
- return -1;
- }
-
- if (rsp->status) {
- status = -1;
- goto cleanup;
- }
-
- for (i = 0; i < n_keys; i++) {
- if (keys_found[i] == 0) {
- status = -1;
- goto cleanup;
- }
- }
-
- for (i = 0; i < n_keys; i++) {
- TAILQ_REMOVE(&p->rules, rules[i], node);
- p->n_rules--;
- rte_free(rules[i]);
- }
-
-cleanup:
- app_msg_free(app, rsp);
- rte_free(rules);
- rte_free(keys_found);
-
- return status;
-}
-
-int
-app_pipeline_firewall_add_default_rule(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id)
-{
- struct app_pipeline_firewall *p;
- struct pipeline_firewall_add_default_msg_req *req;
- struct pipeline_firewall_add_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
- if (p == NULL)
- return -1;
-
- if (port_id >= p->n_ports_out)
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT;
- req->port_id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response and write rule */
- if (rsp->status || (rsp->entry_ptr == NULL)) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- p->default_rule_port_id = port_id;
- p->default_rule_entry_ptr = rsp->entry_ptr;
-
- /* Commit rule */
- p->default_rule_present = 1;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_firewall_delete_default_rule(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_firewall *p;
- struct pipeline_firewall_del_default_msg_req *req;
- struct pipeline_firewall_del_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_firewall);
- if (p == NULL)
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response and write rule */
- if (rsp->status) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Commit rule */
- p->default_rule_present = 0;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-/*
- * firewall
- *
- * firewall add:
- * p <pipelineid> firewall add priority <priority>
- * ipv4 <sipaddr> <sipdepth> <dipaddr> <dipdepth>
- * <sport0> <sport1> <dport0> <dport1> <proto> <protomask>
- * port <portid>
- * Note: <protomask> is a hex value
- *
- * p <pipelineid> firewall add bulk <file>
- *
- * firewall add default:
- * p <pipelineid> firewall add default <port ID>
- *
- * firewall del:
- * p <pipelineid> firewall del
- * ipv4 <sipaddr> <sipdepth> <dipaddr> <dipdepth>
- * <sport0> <sport1> <dport0> <dport1> <proto> <protomask>
- *
- * p <pipelineid> firewall del bulk <file>
- *
- * firewall del default:
- * p <pipelineid> firewall del default
- *
- * firewall ls:
- * p <pipelineid> firewall ls
- */
-
-struct cmd_firewall_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t firewall_string;
- cmdline_multi_string_t multi_string;
-};
-
-static void cmd_firewall_parsed(void *parsed_result,
- __attribute__((unused)) struct cmdline *cl,
- void *data)
-{
- struct cmd_firewall_result *params = parsed_result;
- struct app_params *app = data;
- int status;
-
- char *tokens[17];
- uint32_t n_tokens = RTE_DIM(tokens);
-
- status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
- if (status) {
- printf(CMD_MSG_TOO_MANY_ARGS, "firewall");
- return;
- }
-
- /* firewall add */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "priority") == 0)) {
- struct pipeline_firewall_key key;
- uint32_t priority;
- struct in_addr sipaddr;
- uint32_t sipdepth;
- struct in_addr dipaddr;
- uint32_t dipdepth;
- uint16_t sport0;
- uint16_t sport1;
- uint16_t dport0;
- uint16_t dport1;
- uint8_t proto;
- uint8_t protomask;
- uint32_t port_id;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 16) {
- printf(CMD_MSG_MISMATCH_ARGS, "firewall add");
- return;
- }
-
- if (parser_read_uint32(&priority, tokens[2])) {
- printf(CMD_MSG_INVALID_ARG, "priority");
- return;
- }
-
- if (strcmp(tokens[3], "ipv4")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "ipv4");
- return;
- }
-
- if (parse_ipv4_addr(tokens[4], &sipaddr)) {
- printf(CMD_MSG_INVALID_ARG, "sipaddr");
- return;
- }
-
- if (parser_read_uint32(&sipdepth, tokens[5])) {
- printf(CMD_MSG_INVALID_ARG, "sipdepth");
- return;
- }
-
- if (parse_ipv4_addr(tokens[6], &dipaddr)) {
- printf(CMD_MSG_INVALID_ARG, "dipaddr");
- return;
- }
-
- if (parser_read_uint32(&dipdepth, tokens[7])) {
- printf(CMD_MSG_INVALID_ARG, "dipdepth");
- return;
- }
-
- if (parser_read_uint16(&sport0, tokens[8])) {
- printf(CMD_MSG_INVALID_ARG, "sport0");
- return;
- }
-
- if (parser_read_uint16(&sport1, tokens[9])) {
- printf(CMD_MSG_INVALID_ARG, "sport1");
- return;
- }
-
- if (parser_read_uint16(&dport0, tokens[10])) {
- printf(CMD_MSG_INVALID_ARG, "dport0");
- return;
- }
-
- if (parser_read_uint16(&dport1, tokens[11])) {
- printf(CMD_MSG_INVALID_ARG, "dport1");
- return;
- }
-
- if (parser_read_uint8(&proto, tokens[12])) {
- printf(CMD_MSG_INVALID_ARG, "proto");
- return;
- }
-
- if (parser_read_uint8_hex(&protomask, tokens[13])) {
- printf(CMD_MSG_INVALID_ARG, "protomask");
- return;
- }
-
- if (strcmp(tokens[14], "port")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[15])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- key.type = PIPELINE_FIREWALL_IPV4_5TUPLE;
- key.key.ipv4_5tuple.src_ip = rte_be_to_cpu_32(sipaddr.s_addr);
- key.key.ipv4_5tuple.src_ip_mask = sipdepth;
- key.key.ipv4_5tuple.dst_ip = rte_be_to_cpu_32(dipaddr.s_addr);
- key.key.ipv4_5tuple.dst_ip_mask = dipdepth;
- key.key.ipv4_5tuple.src_port_from = sport0;
- key.key.ipv4_5tuple.src_port_to = sport1;
- key.key.ipv4_5tuple.dst_port_from = dport0;
- key.key.ipv4_5tuple.dst_port_to = dport1;
- key.key.ipv4_5tuple.proto = proto;
- key.key.ipv4_5tuple.proto_mask = protomask;
-
- status = app_pipeline_firewall_add_rule(app,
- params->pipeline_id,
- &key,
- priority,
- port_id);
- if (status)
- printf(CMD_MSG_FAIL, "firewall add");
-
- return;
- } /* firewall add */
-
- /* firewall add bulk */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "bulk") == 0)) {
- struct pipeline_firewall_key *keys;
- uint32_t *priorities, *port_ids, n_keys, line;
- char *filename;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "firewall add bulk");
- return;
- }
-
- filename = tokens[2];
-
- n_keys = APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE;
- keys = malloc(n_keys * sizeof(struct pipeline_firewall_key));
- if (keys == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- return;
- }
- memset(keys, 0, n_keys * sizeof(struct pipeline_firewall_key));
-
- priorities = malloc(n_keys * sizeof(uint32_t));
- if (priorities == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- free(keys);
- return;
- }
-
- port_ids = malloc(n_keys * sizeof(uint32_t));
- if (port_ids == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- free(priorities);
- free(keys);
- return;
- }
-
- status = app_pipeline_firewall_load_file(filename,
- keys,
- priorities,
- port_ids,
- &n_keys,
- &line);
- if (status != 0) {
- printf(CMD_MSG_FILE_ERR, filename, line);
- free(port_ids);
- free(priorities);
- free(keys);
- return;
- }
-
- status = app_pipeline_firewall_add_bulk(app,
- params->pipeline_id,
- keys,
- n_keys,
- priorities,
- port_ids);
- if (status)
- printf(CMD_MSG_FAIL, "firewall add bulk");
-
- free(keys);
- free(priorities);
- free(port_ids);
- return;
- } /* firewall add bulk */
-
- /* firewall add default */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- uint32_t port_id;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "firewall add default");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[2])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- status = app_pipeline_firewall_add_default_rule(app,
- params->pipeline_id,
- port_id);
- if (status)
- printf(CMD_MSG_FAIL, "firewall add default");
-
- return;
- } /* firewall add default */
-
- /* firewall del */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "ipv4") == 0)) {
- struct pipeline_firewall_key key;
- struct in_addr sipaddr;
- uint32_t sipdepth;
- struct in_addr dipaddr;
- uint32_t dipdepth;
- uint16_t sport0;
- uint16_t sport1;
- uint16_t dport0;
- uint16_t dport1;
- uint8_t proto;
- uint8_t protomask;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 12) {
- printf(CMD_MSG_MISMATCH_ARGS, "firewall del");
- return;
- }
-
- if (parse_ipv4_addr(tokens[2], &sipaddr)) {
- printf(CMD_MSG_INVALID_ARG, "sipaddr");
- return;
- }
-
- if (parser_read_uint32(&sipdepth, tokens[3])) {
- printf(CMD_MSG_INVALID_ARG, "sipdepth");
- return;
- }
-
- if (parse_ipv4_addr(tokens[4], &dipaddr)) {
- printf(CMD_MSG_INVALID_ARG, "dipaddr");
- return;
- }
-
- if (parser_read_uint32(&dipdepth, tokens[5])) {
- printf(CMD_MSG_INVALID_ARG, "dipdepth");
- return;
- }
-
- if (parser_read_uint16(&sport0, tokens[6])) {
- printf(CMD_MSG_INVALID_ARG, "sport0");
- return;
- }
-
- if (parser_read_uint16(&sport1, tokens[7])) {
- printf(CMD_MSG_INVALID_ARG, "sport1");
- return;
- }
-
- if (parser_read_uint16(&dport0, tokens[8])) {
- printf(CMD_MSG_INVALID_ARG, "dport0");
- return;
- }
-
- if (parser_read_uint16(&dport1, tokens[9])) {
- printf(CMD_MSG_INVALID_ARG, "dport1");
- return;
- }
-
- if (parser_read_uint8(&proto, tokens[10])) {
- printf(CMD_MSG_INVALID_ARG, "proto");
- return;
- }
-
- if (parser_read_uint8_hex(&protomask, tokens[11])) {
- printf(CMD_MSG_INVALID_ARG, "protomask");
- return;
- }
-
- key.type = PIPELINE_FIREWALL_IPV4_5TUPLE;
- key.key.ipv4_5tuple.src_ip = rte_be_to_cpu_32(sipaddr.s_addr);
- key.key.ipv4_5tuple.src_ip_mask = sipdepth;
- key.key.ipv4_5tuple.dst_ip = rte_be_to_cpu_32(dipaddr.s_addr);
- key.key.ipv4_5tuple.dst_ip_mask = dipdepth;
- key.key.ipv4_5tuple.src_port_from = sport0;
- key.key.ipv4_5tuple.src_port_to = sport1;
- key.key.ipv4_5tuple.dst_port_from = dport0;
- key.key.ipv4_5tuple.dst_port_to = dport1;
- key.key.ipv4_5tuple.proto = proto;
- key.key.ipv4_5tuple.proto_mask = protomask;
-
- status = app_pipeline_firewall_delete_rule(app,
- params->pipeline_id,
- &key);
- if (status)
- printf(CMD_MSG_FAIL, "firewall del");
-
- return;
- } /* firewall del */
-
- /* firewall del bulk */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "bulk") == 0)) {
- struct pipeline_firewall_key *keys;
- uint32_t *priorities, *port_ids, n_keys, line;
- char *filename;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "firewall del bulk");
- return;
- }
-
- filename = tokens[2];
-
- n_keys = APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE;
- keys = malloc(n_keys * sizeof(struct pipeline_firewall_key));
- if (keys == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- return;
- }
- memset(keys, 0, n_keys * sizeof(struct pipeline_firewall_key));
-
- priorities = malloc(n_keys * sizeof(uint32_t));
- if (priorities == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- free(keys);
- return;
- }
-
- port_ids = malloc(n_keys * sizeof(uint32_t));
- if (port_ids == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- free(priorities);
- free(keys);
- return;
- }
-
- status = app_pipeline_firewall_load_file(filename,
- keys,
- priorities,
- port_ids,
- &n_keys,
- &line);
- if (status != 0) {
- printf(CMD_MSG_FILE_ERR, filename, line);
- free(port_ids);
- free(priorities);
- free(keys);
- return;
- }
-
- status = app_pipeline_firewall_delete_bulk(app,
- params->pipeline_id,
- keys,
- n_keys);
- if (status)
- printf(CMD_MSG_FAIL, "firewall del bulk");
-
- free(port_ids);
- free(priorities);
- free(keys);
- return;
- } /* firewall del bulk */
-
- /* firewall del default */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "firewall del default");
- return;
- }
-
- status = app_pipeline_firewall_delete_default_rule(app,
- params->pipeline_id);
- if (status)
- printf(CMD_MSG_FAIL, "firewall del default");
-
- return;
-
- } /* firewall del default */
-
- /* firewall ls */
- if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
- if (n_tokens != 1) {
- printf(CMD_MSG_MISMATCH_ARGS, "firewall ls");
- return;
- }
-
- status = app_pipeline_firewall_ls(app, params->pipeline_id);
- if (status)
- printf(CMD_MSG_FAIL, "firewall ls");
-
- return;
- } /* firewall ls */
-
- printf(CMD_MSG_MISMATCH_ARGS, "firewall");
-}
-
-static cmdline_parse_token_string_t cmd_firewall_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_firewall_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_firewall_result, pipeline_id, UINT32);
-
-static cmdline_parse_token_string_t cmd_firewall_firewall_string =
- TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, firewall_string,
- "firewall");
-
-static cmdline_parse_token_string_t cmd_firewall_multi_string =
- TOKEN_STRING_INITIALIZER(struct cmd_firewall_result, multi_string,
- TOKEN_STRING_MULTI);
-
-static cmdline_parse_inst_t cmd_firewall = {
- .f = cmd_firewall_parsed,
- .data = NULL,
- .help_str = "firewall add / add bulk / add default / del / del bulk"
- " / del default / ls",
- .tokens = {
- (void *) &cmd_firewall_p_string,
- (void *) &cmd_firewall_pipeline_id,
- (void *) &cmd_firewall_firewall_string,
- (void *) &cmd_firewall_multi_string,
- NULL,
- },
-};
-
-static cmdline_parse_ctx_t pipeline_cmds[] = {
- (cmdline_parse_inst_t *) &cmd_firewall,
- NULL,
-};
-
-static struct pipeline_fe_ops pipeline_firewall_fe_ops = {
- .f_init = app_pipeline_firewall_init,
- .f_post_init = NULL,
- .f_free = app_pipeline_firewall_free,
- .f_track = app_pipeline_track_default,
- .cmds = pipeline_cmds,
-};
-
-struct pipeline_type pipeline_firewall = {
- .name = "FIREWALL",
- .be_ops = &pipeline_firewall_be_ops,
- .fe_ops = &pipeline_firewall_fe_ops,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.h b/examples/ip_pipeline/pipeline/pipeline_firewall.h
deleted file mode 100644
index 27304b00..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_firewall.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_FIREWALL_H__
-#define __INCLUDE_PIPELINE_FIREWALL_H__
-
-#include "pipeline.h"
-#include "pipeline_firewall_be.h"
-
-int
-app_pipeline_firewall_add_rule(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *key,
- uint32_t priority,
- uint32_t port_id);
-
-int
-app_pipeline_firewall_delete_rule(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *key);
-
-int
-app_pipeline_firewall_add_bulk(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *keys,
- uint32_t n_keys,
- uint32_t *priorities,
- uint32_t *port_ids);
-
-int
-app_pipeline_firewall_delete_bulk(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_firewall_key *keys,
- uint32_t n_keys);
-
-int
-app_pipeline_firewall_add_default_rule(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id);
-
-int
-app_pipeline_firewall_delete_default_rule(struct app_params *app,
- uint32_t pipeline_id);
-
-#ifndef APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE
-#define APP_PIPELINE_FIREWALL_MAX_RULES_IN_FILE 65536
-#endif
-
-int
-app_pipeline_firewall_load_file(char *filename,
- struct pipeline_firewall_key *keys,
- uint32_t *priorities,
- uint32_t *port_ids,
- uint32_t *n_keys,
- uint32_t *line);
-
-extern struct pipeline_type pipeline_firewall;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c b/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
deleted file mode 100644
index bd5e1b2b..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_firewall_be.c
+++ /dev/null
@@ -1,856 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_ether.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-#include <rte_byteorder.h>
-#include <rte_table_acl.h>
-
-#include "pipeline_firewall_be.h"
-#include "parser.h"
-
-struct pipeline_firewall {
- struct pipeline p;
- pipeline_msg_req_handler custom_handlers[PIPELINE_FIREWALL_MSG_REQS];
-
- uint32_t n_rules;
- uint32_t n_rule_fields;
- struct rte_acl_field_def *field_format;
- uint32_t field_format_size;
-} __rte_cache_aligned;
-
-static void *
-pipeline_firewall_msg_req_custom_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler handlers[] = {
- [PIPELINE_MSG_REQ_PING] =
- pipeline_msg_req_ping_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_IN] =
- pipeline_msg_req_stats_port_in_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
- pipeline_msg_req_stats_port_out_handler,
- [PIPELINE_MSG_REQ_STATS_TABLE] =
- pipeline_msg_req_stats_table_handler,
- [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
- pipeline_msg_req_port_in_enable_handler,
- [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
- pipeline_msg_req_port_in_disable_handler,
- [PIPELINE_MSG_REQ_CUSTOM] =
- pipeline_firewall_msg_req_custom_handler,
-};
-
-static void *
-pipeline_firewall_msg_req_add_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_firewall_msg_req_del_default_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler custom_handlers[] = {
- [PIPELINE_FIREWALL_MSG_REQ_ADD] =
- pipeline_firewall_msg_req_add_handler,
- [PIPELINE_FIREWALL_MSG_REQ_DEL] =
- pipeline_firewall_msg_req_del_handler,
- [PIPELINE_FIREWALL_MSG_REQ_ADD_BULK] =
- pipeline_firewall_msg_req_add_bulk_handler,
- [PIPELINE_FIREWALL_MSG_REQ_DEL_BULK] =
- pipeline_firewall_msg_req_del_bulk_handler,
- [PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT] =
- pipeline_firewall_msg_req_add_default_handler,
- [PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT] =
- pipeline_firewall_msg_req_del_default_handler,
-};
-
-/*
- * Firewall table
- */
-struct firewall_table_entry {
- struct rte_pipeline_table_entry head;
-};
-
-static struct rte_acl_field_def field_format_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = sizeof(struct ether_hdr) +
- offsetof(struct 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 = sizeof(struct ether_hdr) +
- offsetof(struct 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 = sizeof(struct ether_hdr) +
- offsetof(struct 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 ether_hdr) +
- sizeof(struct ipv4_hdr) +
- offsetof(struct 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 ether_hdr) +
- sizeof(struct ipv4_hdr) +
- offsetof(struct tcp_hdr, dst_port),
- },
-};
-
-#define SIZEOF_VLAN_HDR 4
-
-static struct rte_acl_field_def field_format_vlan_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = sizeof(struct ether_hdr) +
- SIZEOF_VLAN_HDR +
- offsetof(struct 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 = sizeof(struct ether_hdr) +
- SIZEOF_VLAN_HDR +
- offsetof(struct 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 = sizeof(struct ether_hdr) +
- SIZEOF_VLAN_HDR +
- offsetof(struct 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 ether_hdr) +
- SIZEOF_VLAN_HDR +
- sizeof(struct ipv4_hdr) +
- offsetof(struct 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 ether_hdr) +
- SIZEOF_VLAN_HDR +
- sizeof(struct ipv4_hdr) +
- offsetof(struct tcp_hdr, dst_port),
- },
-};
-
-#define SIZEOF_QINQ_HEADER 8
-
-static struct rte_acl_field_def field_format_qinq_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = sizeof(struct ether_hdr) +
- SIZEOF_QINQ_HEADER +
- offsetof(struct 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 = sizeof(struct ether_hdr) +
- SIZEOF_QINQ_HEADER +
- offsetof(struct 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 = sizeof(struct ether_hdr) +
- SIZEOF_QINQ_HEADER +
- offsetof(struct 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 ether_hdr) +
- SIZEOF_QINQ_HEADER +
- sizeof(struct ipv4_hdr) +
- offsetof(struct 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 ether_hdr) +
- SIZEOF_QINQ_HEADER +
- sizeof(struct ipv4_hdr) +
- offsetof(struct tcp_hdr, dst_port),
- },
-};
-
-static int
-pipeline_firewall_parse_args(struct pipeline_firewall *p,
- struct pipeline_params *params)
-{
- uint32_t n_rules_present = 0;
- uint32_t pkt_type_present = 0;
- uint32_t i;
-
- /* defaults */
- p->n_rules = 4 * 1024;
- p->n_rule_fields = RTE_DIM(field_format_ipv4);
- p->field_format = field_format_ipv4;
- p->field_format_size = sizeof(field_format_ipv4);
-
- for (i = 0; i < params->n_args; i++) {
- char *arg_name = params->args_name[i];
- char *arg_value = params->args_value[i];
-
- if (strcmp(arg_name, "n_rules") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- n_rules_present == 0, params->name,
- arg_name);
- n_rules_present = 1;
-
- status = parser_read_uint32(&p->n_rules,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
- continue;
- }
-
- if (strcmp(arg_name, "pkt_type") == 0) {
- PIPELINE_PARSE_ERR_DUPLICATE(
- pkt_type_present == 0, params->name,
- arg_name);
- pkt_type_present = 1;
-
- /* ipv4 */
- if (strcmp(arg_value, "ipv4") == 0) {
- p->n_rule_fields = RTE_DIM(field_format_ipv4);
- p->field_format = field_format_ipv4;
- p->field_format_size =
- sizeof(field_format_ipv4);
- continue;
- }
-
- /* vlan_ipv4 */
- if (strcmp(arg_value, "vlan_ipv4") == 0) {
- p->n_rule_fields =
- RTE_DIM(field_format_vlan_ipv4);
- p->field_format = field_format_vlan_ipv4;
- p->field_format_size =
- sizeof(field_format_vlan_ipv4);
- continue;
- }
-
- /* qinq_ipv4 */
- if (strcmp(arg_value, "qinq_ipv4") == 0) {
- p->n_rule_fields =
- RTE_DIM(field_format_qinq_ipv4);
- p->field_format = field_format_qinq_ipv4;
- p->field_format_size =
- sizeof(field_format_qinq_ipv4);
- continue;
- }
-
- /* other */
- PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
- arg_name, arg_value);
- }
-
- /* other */
- PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
- }
-
- return 0;
-}
-
-static void *
-pipeline_firewall_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct pipeline *p;
- struct pipeline_firewall *p_fw;
- uint32_t size, i;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_firewall));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- p_fw = (struct pipeline_firewall *) p;
- if (p == NULL)
- return NULL;
-
- strcpy(p->name, params->name);
- p->log_level = params->log_level;
-
- PLOG(p, HIGH, "Firewall");
-
- /* Parse arguments */
- if (pipeline_firewall_parse_args(p_fw, params))
- return NULL;
-
- /* Pipeline */
- {
- struct rte_pipeline_params pipeline_params = {
- .name = params->name,
- .socket_id = params->socket_id,
- .offset_port_id = 0,
- };
-
- p->p = rte_pipeline_create(&pipeline_params);
- if (p->p == NULL) {
- rte_free(p);
- return NULL;
- }
- }
-
- /* Input ports */
- p->n_ports_in = params->n_ports_in;
- for (i = 0; i < p->n_ports_in; i++) {
- struct rte_pipeline_port_in_params port_params = {
- .ops = pipeline_port_in_params_get_ops(
- &params->port_in[i]),
- .arg_create = pipeline_port_in_params_convert(
- &params->port_in[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = params->port_in[i].burst_size,
- };
-
- int status = rte_pipeline_port_in_create(p->p,
- &port_params,
- &p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Output ports */
- p->n_ports_out = params->n_ports_out;
- for (i = 0; i < p->n_ports_out; i++) {
- struct rte_pipeline_port_out_params port_params = {
- .ops = pipeline_port_out_params_get_ops(
- &params->port_out[i]),
- .arg_create = pipeline_port_out_params_convert(
- &params->port_out[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- int status = rte_pipeline_port_out_create(p->p,
- &port_params,
- &p->port_out_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Tables */
- p->n_tables = 1;
- {
- struct rte_table_acl_params table_acl_params = {
- .name = params->name,
- .n_rules = p_fw->n_rules,
- .n_rule_fields = p_fw->n_rule_fields,
- };
-
- 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 =
- sizeof(struct firewall_table_entry) -
- sizeof(struct rte_pipeline_table_entry),
- };
-
- int status;
-
- memcpy(table_acl_params.field_format,
- p_fw->field_format,
- p_fw->field_format_size);
-
- status = rte_pipeline_table_create(p->p,
- &table_params,
- &p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Connecting input ports to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_connect_to_table(p->p,
- p->port_in_id[i],
- p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_enable(p->p,
- p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p->p) < 0) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
-
- /* Message queues */
- p->n_msgq = params->n_msgq;
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_in[i] = params->msgq_in[i];
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_out[i] = params->msgq_out[i];
-
- /* Message handlers */
- memcpy(p->handlers, handlers, sizeof(p->handlers));
- memcpy(p_fw->custom_handlers,
- custom_handlers,
- sizeof(p_fw->custom_handlers));
-
- return p;
-}
-
-static int
-pipeline_firewall_free(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- rte_pipeline_free(p->p);
- rte_free(p);
- return 0;
-}
-
-static int
-pipeline_firewall_timer(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- pipeline_msg_req_handle(p);
- rte_pipeline_flush(p->p);
-
- return 0;
-}
-
-void *
-pipeline_firewall_msg_req_custom_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_firewall *p_fw = (struct pipeline_firewall *) p;
- struct pipeline_custom_msg_req *req = msg;
- pipeline_msg_req_handler f_handle;
-
- f_handle = (req->subtype < PIPELINE_FIREWALL_MSG_REQS) ?
- p_fw->custom_handlers[req->subtype] :
- pipeline_msg_req_invalid_handler;
-
- if (f_handle == NULL)
- f_handle = pipeline_msg_req_invalid_handler;
-
- return f_handle(p, req);
-}
-
-void *
-pipeline_firewall_msg_req_add_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_firewall_add_msg_req *req = msg;
- struct pipeline_firewall_add_msg_rsp *rsp = msg;
-
- struct rte_table_acl_rule_add_params params;
- struct firewall_table_entry entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->port_id]},
- },
- };
-
- memset(&params, 0, sizeof(params));
-
- switch (req->key.type) {
- case PIPELINE_FIREWALL_IPV4_5TUPLE:
- params.priority = req->priority;
- params.field_value[0].value.u8 =
- req->key.key.ipv4_5tuple.proto;
- params.field_value[0].mask_range.u8 =
- req->key.key.ipv4_5tuple.proto_mask;
- params.field_value[1].value.u32 =
- req->key.key.ipv4_5tuple.src_ip;
- params.field_value[1].mask_range.u32 =
- req->key.key.ipv4_5tuple.src_ip_mask;
- params.field_value[2].value.u32 =
- req->key.key.ipv4_5tuple.dst_ip;
- params.field_value[2].mask_range.u32 =
- req->key.key.ipv4_5tuple.dst_ip_mask;
- params.field_value[3].value.u16 =
- req->key.key.ipv4_5tuple.src_port_from;
- params.field_value[3].mask_range.u16 =
- req->key.key.ipv4_5tuple.src_port_to;
- params.field_value[4].value.u16 =
- req->key.key.ipv4_5tuple.dst_port_from;
- params.field_value[4].mask_range.u16 =
- req->key.key.ipv4_5tuple.dst_port_to;
- break;
-
- default:
- rsp->status = -1; /* Error */
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_add(p->p,
- p->table_id[0],
- &params,
- (struct rte_pipeline_table_entry *) &entry,
- &rsp->key_found,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-void *
-pipeline_firewall_msg_req_del_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_firewall_del_msg_req *req = msg;
- struct pipeline_firewall_del_msg_rsp *rsp = msg;
-
- struct rte_table_acl_rule_delete_params params;
-
- memset(&params, 0, sizeof(params));
-
- switch (req->key.type) {
- case PIPELINE_FIREWALL_IPV4_5TUPLE:
- params.field_value[0].value.u8 =
- req->key.key.ipv4_5tuple.proto;
- params.field_value[0].mask_range.u8 =
- req->key.key.ipv4_5tuple.proto_mask;
- params.field_value[1].value.u32 =
- req->key.key.ipv4_5tuple.src_ip;
- params.field_value[1].mask_range.u32 =
- req->key.key.ipv4_5tuple.src_ip_mask;
- params.field_value[2].value.u32 =
- req->key.key.ipv4_5tuple.dst_ip;
- params.field_value[2].mask_range.u32 =
- req->key.key.ipv4_5tuple.dst_ip_mask;
- params.field_value[3].value.u16 =
- req->key.key.ipv4_5tuple.src_port_from;
- params.field_value[3].mask_range.u16 =
- req->key.key.ipv4_5tuple.src_port_to;
- params.field_value[4].value.u16 =
- req->key.key.ipv4_5tuple.dst_port_from;
- params.field_value[4].mask_range.u16 =
- req->key.key.ipv4_5tuple.dst_port_to;
- break;
-
- default:
- rsp->status = -1; /* Error */
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- p->table_id[0],
- &params,
- &rsp->key_found,
- NULL);
-
- return rsp;
-}
-
-static void *
-pipeline_firewall_msg_req_add_bulk_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_firewall_add_bulk_msg_req *req = msg;
- struct pipeline_firewall_add_bulk_msg_rsp *rsp = msg;
-
- struct rte_table_acl_rule_add_params *params[req->n_keys];
- struct firewall_table_entry *entries[req->n_keys];
-
- uint32_t i, n_keys;
-
- n_keys = req->n_keys;
-
- for (i = 0; i < n_keys; i++) {
- entries[i] = rte_zmalloc(NULL,
- sizeof(struct firewall_table_entry),
- RTE_CACHE_LINE_SIZE);
- if (entries[i] == NULL) {
- rsp->status = -1;
- return rsp;
- }
-
- params[i] = rte_zmalloc(NULL,
- sizeof(struct rte_table_acl_rule_add_params),
- RTE_CACHE_LINE_SIZE);
- if (params[i] == NULL) {
- rsp->status = -1;
- return rsp;
- }
-
- entries[i]->head.action = RTE_PIPELINE_ACTION_PORT;
- entries[i]->head.port_id = p->port_out_id[req->port_ids[i]];
-
- switch (req->keys[i].type) {
- case PIPELINE_FIREWALL_IPV4_5TUPLE:
- params[i]->priority = req->priorities[i];
- params[i]->field_value[0].value.u8 =
- req->keys[i].key.ipv4_5tuple.proto;
- params[i]->field_value[0].mask_range.u8 =
- req->keys[i].key.ipv4_5tuple.proto_mask;
- params[i]->field_value[1].value.u32 =
- req->keys[i].key.ipv4_5tuple.src_ip;
- params[i]->field_value[1].mask_range.u32 =
- req->keys[i].key.ipv4_5tuple.src_ip_mask;
- params[i]->field_value[2].value.u32 =
- req->keys[i].key.ipv4_5tuple.dst_ip;
- params[i]->field_value[2].mask_range.u32 =
- req->keys[i].key.ipv4_5tuple.dst_ip_mask;
- params[i]->field_value[3].value.u16 =
- req->keys[i].key.ipv4_5tuple.src_port_from;
- params[i]->field_value[3].mask_range.u16 =
- req->keys[i].key.ipv4_5tuple.src_port_to;
- params[i]->field_value[4].value.u16 =
- req->keys[i].key.ipv4_5tuple.dst_port_from;
- params[i]->field_value[4].mask_range.u16 =
- req->keys[i].key.ipv4_5tuple.dst_port_to;
- break;
-
- default:
- rsp->status = -1; /* Error */
-
- for (i = 0; i < n_keys; i++) {
- rte_free(entries[i]);
- rte_free(params[i]);
- }
-
- return rsp;
- }
- }
-
- rsp->status = rte_pipeline_table_entry_add_bulk(p->p, p->table_id[0],
- (void *)params, (struct rte_pipeline_table_entry **)entries,
- n_keys, req->keys_found,
- (struct rte_pipeline_table_entry **)req->entries_ptr);
-
- for (i = 0; i < n_keys; i++) {
- rte_free(entries[i]);
- rte_free(params[i]);
- }
-
- return rsp;
-}
-
-static void *
-pipeline_firewall_msg_req_del_bulk_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_firewall_del_bulk_msg_req *req = msg;
- struct pipeline_firewall_del_bulk_msg_rsp *rsp = msg;
-
- struct rte_table_acl_rule_delete_params *params[req->n_keys];
-
- uint32_t i, n_keys;
-
- n_keys = req->n_keys;
-
- for (i = 0; i < n_keys; i++) {
- params[i] = rte_zmalloc(NULL,
- sizeof(struct rte_table_acl_rule_delete_params),
- RTE_CACHE_LINE_SIZE);
- if (params[i] == NULL) {
- rsp->status = -1;
- return rsp;
- }
-
- switch (req->keys[i].type) {
- case PIPELINE_FIREWALL_IPV4_5TUPLE:
- params[i]->field_value[0].value.u8 =
- req->keys[i].key.ipv4_5tuple.proto;
- params[i]->field_value[0].mask_range.u8 =
- req->keys[i].key.ipv4_5tuple.proto_mask;
- params[i]->field_value[1].value.u32 =
- req->keys[i].key.ipv4_5tuple.src_ip;
- params[i]->field_value[1].mask_range.u32 =
- req->keys[i].key.ipv4_5tuple.src_ip_mask;
- params[i]->field_value[2].value.u32 =
- req->keys[i].key.ipv4_5tuple.dst_ip;
- params[i]->field_value[2].mask_range.u32 =
- req->keys[i].key.ipv4_5tuple.dst_ip_mask;
- params[i]->field_value[3].value.u16 =
- req->keys[i].key.ipv4_5tuple.src_port_from;
- params[i]->field_value[3].mask_range.u16 =
- req->keys[i].key.ipv4_5tuple.src_port_to;
- params[i]->field_value[4].value.u16 =
- req->keys[i].key.ipv4_5tuple.dst_port_from;
- params[i]->field_value[4].mask_range.u16 =
- req->keys[i].key.ipv4_5tuple.dst_port_to;
- break;
-
- default:
- rsp->status = -1; /* Error */
-
- for (i = 0; i < n_keys; i++)
- rte_free(params[i]);
-
- return rsp;
- }
- }
-
- rsp->status = rte_pipeline_table_entry_delete_bulk(p->p, p->table_id[0],
- (void **)&params, n_keys, req->keys_found, NULL);
-
- for (i = 0; i < n_keys; i++)
- rte_free(params[i]);
-
- return rsp;
-}
-
-void *
-pipeline_firewall_msg_req_add_default_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_firewall_add_default_msg_req *req = msg;
- struct pipeline_firewall_add_default_msg_rsp *rsp = msg;
-
- struct firewall_table_entry default_entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->port_id]},
- },
- };
-
- rsp->status = rte_pipeline_table_default_entry_add(p->p,
- p->table_id[0],
- (struct rte_pipeline_table_entry *) &default_entry,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-void *
-pipeline_firewall_msg_req_del_default_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_firewall_del_default_msg_rsp *rsp = msg;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- p->table_id[0],
- NULL);
-
- return rsp;
-}
-
-struct pipeline_be_ops pipeline_firewall_be_ops = {
- .f_init = pipeline_firewall_init,
- .f_free = pipeline_firewall_free,
- .f_run = NULL,
- .f_timer = pipeline_firewall_timer,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall_be.h b/examples/ip_pipeline/pipeline/pipeline_firewall_be.h
deleted file mode 100644
index 246f0a6d..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_firewall_be.h
+++ /dev/null
@@ -1,147 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_FIREWALL_BE_H__
-#define __INCLUDE_PIPELINE_FIREWALL_BE_H__
-
-#include "pipeline_common_be.h"
-
-enum pipeline_firewall_key_type {
- PIPELINE_FIREWALL_IPV4_5TUPLE,
-};
-
-struct pipeline_firewall_key_ipv4_5tuple {
- uint32_t src_ip;
- uint32_t src_ip_mask;
- uint32_t dst_ip;
- uint32_t dst_ip_mask;
- uint16_t src_port_from;
- uint16_t src_port_to;
- uint16_t dst_port_from;
- uint16_t dst_port_to;
- uint8_t proto;
- uint8_t proto_mask;
-};
-
-struct pipeline_firewall_key {
- enum pipeline_firewall_key_type type;
- union {
- struct pipeline_firewall_key_ipv4_5tuple ipv4_5tuple;
- } key;
-};
-
-enum pipeline_firewall_msg_req_type {
- PIPELINE_FIREWALL_MSG_REQ_ADD = 0,
- PIPELINE_FIREWALL_MSG_REQ_DEL,
- PIPELINE_FIREWALL_MSG_REQ_ADD_BULK,
- PIPELINE_FIREWALL_MSG_REQ_DEL_BULK,
- PIPELINE_FIREWALL_MSG_REQ_ADD_DEFAULT,
- PIPELINE_FIREWALL_MSG_REQ_DEL_DEFAULT,
- PIPELINE_FIREWALL_MSG_REQS
-};
-
-/*
- * MSG ADD
- */
-struct pipeline_firewall_add_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_firewall_msg_req_type subtype;
-
- /* key */
- struct pipeline_firewall_key key;
-
- /* data */
- int32_t priority;
- uint32_t port_id;
-};
-
-struct pipeline_firewall_add_msg_rsp {
- int status;
- int key_found;
- void *entry_ptr;
-};
-
-/*
- * MSG DEL
- */
-struct pipeline_firewall_del_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_firewall_msg_req_type subtype;
-
- /* key */
- struct pipeline_firewall_key key;
-};
-
-struct pipeline_firewall_del_msg_rsp {
- int status;
- int key_found;
-};
-
-/*
- * MSG ADD BULK
- */
-struct pipeline_firewall_add_bulk_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_firewall_msg_req_type subtype;
-
- struct pipeline_firewall_key *keys;
- uint32_t n_keys;
-
- uint32_t *priorities;
- uint32_t *port_ids;
- int *keys_found;
- void **entries_ptr;
-};
-struct pipeline_firewall_add_bulk_msg_rsp {
- int status;
-};
-
-/*
- * MSG DEL BULK
- */
-struct pipeline_firewall_del_bulk_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_firewall_msg_req_type subtype;
-
- /* key */
- struct pipeline_firewall_key *keys;
- uint32_t n_keys;
- int *keys_found;
-};
-
-struct pipeline_firewall_del_bulk_msg_rsp {
- int status;
-};
-
-/*
- * MSG ADD DEFAULT
- */
-struct pipeline_firewall_add_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_firewall_msg_req_type subtype;
-
- /* data */
- uint32_t port_id;
-};
-
-struct pipeline_firewall_add_default_msg_rsp {
- int status;
- void *entry_ptr;
-};
-
-/*
- * MSG DEL DEFAULT
- */
-struct pipeline_firewall_del_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_firewall_msg_req_type subtype;
-};
-
-struct pipeline_firewall_del_default_msg_rsp {
- int status;
-};
-
-extern struct pipeline_be_ops pipeline_firewall_be_ops;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
deleted file mode 100644
index 021aee18..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
+++ /dev/null
@@ -1,1286 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <netinet/in.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_hexdump.h>
-#include <rte_malloc.h>
-#include <cmdline_rdline.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-
-#include "app.h"
-#include "pipeline_common_fe.h"
-#include "pipeline_flow_actions.h"
-#include "hash_func.h"
-#include "parser.h"
-
-/*
- * Flow actions pipeline
- */
-#ifndef N_FLOWS_BULK
-#define N_FLOWS_BULK 4096
-#endif
-
-struct app_pipeline_fa_flow {
- struct pipeline_fa_flow_params params;
- void *entry_ptr;
-};
-
-struct app_pipeline_fa_dscp {
- uint32_t traffic_class;
- enum rte_meter_color color;
-};
-
-struct app_pipeline_fa {
- /* Parameters */
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- struct pipeline_fa_params params;
-
- /* Flows */
- struct app_pipeline_fa_dscp dscp[PIPELINE_FA_N_DSCP];
- struct app_pipeline_fa_flow *flows;
-} __rte_cache_aligned;
-
-static void*
-app_pipeline_fa_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct app_pipeline_fa *p;
- uint32_t size, i;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_fa));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p == NULL)
- return NULL;
-
- /* Initialization */
- p->n_ports_in = params->n_ports_in;
- p->n_ports_out = params->n_ports_out;
- if (pipeline_fa_parse_args(&p->params, params)) {
- rte_free(p);
- return NULL;
- }
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(
- p->params.n_flows * sizeof(struct app_pipeline_fa_flow));
- p->flows = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p->flows == NULL) {
- rte_free(p);
- return NULL;
- }
-
- /* Initialization of flow table */
- for (i = 0; i < p->params.n_flows; i++)
- pipeline_fa_flow_params_set_default(&p->flows[i].params);
-
- /* Initialization of DSCP table */
- for (i = 0; i < RTE_DIM(p->dscp); i++) {
- p->dscp[i].traffic_class = 0;
- p->dscp[i].color = e_RTE_METER_GREEN;
- }
-
- return (void *) p;
-}
-
-static int
-app_pipeline_fa_free(void *pipeline)
-{
- struct app_pipeline_fa *p = pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- rte_free(p->flows);
- rte_free(p);
-
- return 0;
-}
-
-static int
-flow_params_check(struct app_pipeline_fa *p,
- __rte_unused uint32_t meter_update_mask,
- uint32_t policer_update_mask,
- uint32_t port_update,
- struct pipeline_fa_flow_params *params)
-{
- uint32_t mask, i;
-
- /* Meter */
-
- /* Policer */
- for (i = 0, mask = 1; i < PIPELINE_FA_N_TC_MAX; i++, mask <<= 1) {
- struct pipeline_fa_policer_params *p = &params->p[i];
- uint32_t j;
-
- if ((mask & policer_update_mask) == 0)
- continue;
-
- for (j = 0; j < e_RTE_METER_COLORS; j++) {
- struct pipeline_fa_policer_action *action =
- &p->action[j];
-
- if ((action->drop == 0) &&
- (action->color >= e_RTE_METER_COLORS))
- return -1;
- }
- }
-
- /* Port */
- if (port_update && (params->port_id >= p->n_ports_out))
- return -1;
-
- return 0;
-}
-
-int
-app_pipeline_fa_flow_config(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t flow_id,
- uint32_t meter_update_mask,
- uint32_t policer_update_mask,
- uint32_t port_update,
- struct pipeline_fa_flow_params *params)
-{
- struct app_pipeline_fa *p;
- struct app_pipeline_fa_flow *flow;
-
- struct pipeline_fa_flow_config_msg_req *req;
- struct pipeline_fa_flow_config_msg_rsp *rsp;
-
- uint32_t i, mask;
-
- /* Check input arguments */
- if ((app == NULL) ||
- ((meter_update_mask == 0) &&
- (policer_update_mask == 0) &&
- (port_update == 0)) ||
- (meter_update_mask >= (1 << PIPELINE_FA_N_TC_MAX)) ||
- (policer_update_mask >= (1 << PIPELINE_FA_N_TC_MAX)) ||
- (params == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id,
- &pipeline_flow_actions);
- if (p == NULL)
- return -1;
-
- if (flow_params_check(p,
- meter_update_mask,
- policer_update_mask,
- port_update,
- params) != 0)
- return -1;
-
- flow_id %= p->params.n_flows;
- flow = &p->flows[flow_id];
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FA_MSG_REQ_FLOW_CONFIG;
- req->entry_ptr = flow->entry_ptr;
- req->flow_id = flow_id;
- req->meter_update_mask = meter_update_mask;
- req->policer_update_mask = policer_update_mask;
- req->port_update = port_update;
- memcpy(&req->params, params, sizeof(*params));
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status ||
- (rsp->entry_ptr == NULL)) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Commit flow */
- for (i = 0, mask = 1; i < PIPELINE_FA_N_TC_MAX; i++, mask <<= 1) {
- if ((mask & meter_update_mask) == 0)
- continue;
-
- memcpy(&flow->params.m[i], &params->m[i], sizeof(params->m[i]));
- }
-
- for (i = 0, mask = 1; i < PIPELINE_FA_N_TC_MAX; i++, mask <<= 1) {
- if ((mask & policer_update_mask) == 0)
- continue;
-
- memcpy(&flow->params.p[i], &params->p[i], sizeof(params->p[i]));
- }
-
- if (port_update)
- flow->params.port_id = params->port_id;
-
- flow->entry_ptr = rsp->entry_ptr;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_fa_flow_config_bulk(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t *flow_id,
- uint32_t n_flows,
- uint32_t meter_update_mask,
- uint32_t policer_update_mask,
- uint32_t port_update,
- struct pipeline_fa_flow_params *params)
-{
- struct app_pipeline_fa *p;
- struct pipeline_fa_flow_config_bulk_msg_req *req;
- struct pipeline_fa_flow_config_bulk_msg_rsp *rsp;
- void **req_entry_ptr;
- uint32_t *req_flow_id;
- uint32_t i;
- int status;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (flow_id == NULL) ||
- (n_flows == 0) ||
- ((meter_update_mask == 0) &&
- (policer_update_mask == 0) &&
- (port_update == 0)) ||
- (meter_update_mask >= (1 << PIPELINE_FA_N_TC_MAX)) ||
- (policer_update_mask >= (1 << PIPELINE_FA_N_TC_MAX)) ||
- (params == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id,
- &pipeline_flow_actions);
- if (p == NULL)
- return -1;
-
- for (i = 0; i < n_flows; i++) {
- struct pipeline_fa_flow_params *flow_params = &params[i];
-
- if (flow_params_check(p,
- meter_update_mask,
- policer_update_mask,
- port_update,
- flow_params) != 0)
- return -1;
- }
-
- /* Allocate and write request */
- req_entry_ptr = (void **) rte_malloc(NULL,
- n_flows * sizeof(void *),
- RTE_CACHE_LINE_SIZE);
- if (req_entry_ptr == NULL)
- return -1;
-
- req_flow_id = (uint32_t *) rte_malloc(NULL,
- n_flows * sizeof(uint32_t),
- RTE_CACHE_LINE_SIZE);
- if (req_flow_id == NULL) {
- rte_free(req_entry_ptr);
- return -1;
- }
-
- for (i = 0; i < n_flows; i++) {
- uint32_t fid = flow_id[i] % p->params.n_flows;
- struct app_pipeline_fa_flow *flow = &p->flows[fid];
-
- req_flow_id[i] = fid;
- req_entry_ptr[i] = flow->entry_ptr;
- }
-
- req = app_msg_alloc(app);
- if (req == NULL) {
- rte_free(req_flow_id);
- rte_free(req_entry_ptr);
- return -1;
- }
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FA_MSG_REQ_FLOW_CONFIG_BULK;
- req->entry_ptr = req_entry_ptr;
- req->flow_id = req_flow_id;
- req->n_flows = n_flows;
- req->meter_update_mask = meter_update_mask;
- req->policer_update_mask = policer_update_mask;
- req->port_update = port_update;
- req->params = params;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL) {
- rte_free(req_flow_id);
- rte_free(req_entry_ptr);
- return -1;
- }
-
- /* Read response */
- status = (rsp->n_flows == n_flows) ? 0 : -1;
-
- /* Commit flows */
- for (i = 0; i < rsp->n_flows; i++) {
- uint32_t fid = flow_id[i] % p->params.n_flows;
- struct app_pipeline_fa_flow *flow = &p->flows[fid];
- struct pipeline_fa_flow_params *flow_params = &params[i];
- void *entry_ptr = req_entry_ptr[i];
- uint32_t j, mask;
-
- for (j = 0, mask = 1; j < PIPELINE_FA_N_TC_MAX;
- j++, mask <<= 1) {
- if ((mask & meter_update_mask) == 0)
- continue;
-
- memcpy(&flow->params.m[j],
- &flow_params->m[j],
- sizeof(flow_params->m[j]));
- }
-
- for (j = 0, mask = 1; j < PIPELINE_FA_N_TC_MAX;
- j++, mask <<= 1) {
- if ((mask & policer_update_mask) == 0)
- continue;
-
- memcpy(&flow->params.p[j],
- &flow_params->p[j],
- sizeof(flow_params->p[j]));
- }
-
- if (port_update)
- flow->params.port_id = flow_params->port_id;
-
- flow->entry_ptr = entry_ptr;
- }
-
- /* Free response */
- app_msg_free(app, rsp);
- rte_free(req_flow_id);
- rte_free(req_entry_ptr);
-
- return status;
-}
-
-int
-app_pipeline_fa_dscp_config(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t dscp,
- uint32_t traffic_class,
- enum rte_meter_color color)
-{
- struct app_pipeline_fa *p;
-
- struct pipeline_fa_dscp_config_msg_req *req;
- struct pipeline_fa_dscp_config_msg_rsp *rsp;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (dscp >= PIPELINE_FA_N_DSCP) ||
- (traffic_class >= PIPELINE_FA_N_TC_MAX) ||
- (color >= e_RTE_METER_COLORS))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id,
- &pipeline_flow_actions);
- if (p == NULL)
- return -1;
-
- if (p->params.dscp_enabled == 0)
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FA_MSG_REQ_DSCP_CONFIG;
- req->dscp = dscp;
- req->traffic_class = traffic_class;
- req->color = color;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Commit DSCP */
- p->dscp[dscp].traffic_class = traffic_class;
- p->dscp[dscp].color = color;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_fa_flow_policer_stats_read(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t flow_id,
- uint32_t policer_id,
- int clear,
- struct pipeline_fa_policer_stats *stats)
-{
- struct app_pipeline_fa *p;
- struct app_pipeline_fa_flow *flow;
-
- struct pipeline_fa_policer_stats_msg_req *req;
- struct pipeline_fa_policer_stats_msg_rsp *rsp;
-
- /* Check input arguments */
- if ((app == NULL) || (stats == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id,
- &pipeline_flow_actions);
- if (p == NULL)
- return -1;
-
- flow_id %= p->params.n_flows;
- flow = &p->flows[flow_id];
-
- if ((policer_id >= p->params.n_meters_per_flow) ||
- (flow->entry_ptr == NULL))
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FA_MSG_REQ_POLICER_STATS_READ;
- req->entry_ptr = flow->entry_ptr;
- req->policer_id = policer_id;
- req->clear = clear;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- memcpy(stats, &rsp->stats, sizeof(*stats));
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-static const char *
-color_to_string(enum rte_meter_color color)
-{
- switch (color) {
- case e_RTE_METER_GREEN: return "G";
- case e_RTE_METER_YELLOW: return "Y";
- case e_RTE_METER_RED: return "R";
- default: return "?";
- }
-}
-
-static int
-string_to_color(char *s, enum rte_meter_color *c)
-{
- if (strcmp(s, "G") == 0) {
- *c = e_RTE_METER_GREEN;
- return 0;
- }
-
- if (strcmp(s, "Y") == 0) {
- *c = e_RTE_METER_YELLOW;
- return 0;
- }
-
- if (strcmp(s, "R") == 0) {
- *c = e_RTE_METER_RED;
- return 0;
- }
-
- return -1;
-}
-
-static const char *
-policer_action_to_string(struct pipeline_fa_policer_action *a)
-{
- if (a->drop)
- return "D";
-
- return color_to_string(a->color);
-}
-
-static int
-string_to_policer_action(char *s, struct pipeline_fa_policer_action *a)
-{
- if (strcmp(s, "G") == 0) {
- a->drop = 0;
- a->color = e_RTE_METER_GREEN;
- return 0;
- }
-
- if (strcmp(s, "Y") == 0) {
- a->drop = 0;
- a->color = e_RTE_METER_YELLOW;
- return 0;
- }
-
- if (strcmp(s, "R") == 0) {
- a->drop = 0;
- a->color = e_RTE_METER_RED;
- return 0;
- }
-
- if (strcmp(s, "D") == 0) {
- a->drop = 1;
- a->color = e_RTE_METER_GREEN;
- return 0;
- }
-
- return -1;
-}
-
-static void
-print_flow(struct app_pipeline_fa *p,
- uint32_t flow_id,
- struct app_pipeline_fa_flow *flow)
-{
- uint32_t i;
-
- printf("Flow ID = %" PRIu32 "\n", flow_id);
-
- for (i = 0; i < p->params.n_meters_per_flow; i++) {
- struct rte_meter_trtcm_params *meter = &flow->params.m[i];
- struct pipeline_fa_policer_params *policer = &flow->params.p[i];
-
- printf("\ttrTCM [CIR = %" PRIu64
- ", CBS = %" PRIu64 ", PIR = %" PRIu64
- ", PBS = %" PRIu64 "] Policer [G : %s, Y : %s, R : %s]\n",
- meter->cir,
- meter->cbs,
- meter->pir,
- meter->pbs,
- policer_action_to_string(&policer->action[e_RTE_METER_GREEN]),
- policer_action_to_string(&policer->action[e_RTE_METER_YELLOW]),
- policer_action_to_string(&policer->action[e_RTE_METER_RED]));
- }
-
- printf("\tPort %u (entry_ptr = %p)\n",
- flow->params.port_id,
- flow->entry_ptr);
-}
-
-
-static int
-app_pipeline_fa_flow_ls(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_fa *p;
- uint32_t i;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id,
- &pipeline_flow_actions);
- if (p == NULL)
- return -1;
-
- for (i = 0; i < p->params.n_flows; i++) {
- struct app_pipeline_fa_flow *flow = &p->flows[i];
-
- print_flow(p, i, flow);
- }
-
- return 0;
-}
-
-static int
-app_pipeline_fa_dscp_ls(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_fa *p;
- uint32_t i;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id,
- &pipeline_flow_actions);
- if (p == NULL)
- return -1;
-
- if (p->params.dscp_enabled == 0)
- return -1;
-
- for (i = 0; i < RTE_DIM(p->dscp); i++) {
- struct app_pipeline_fa_dscp *dscp = &p->dscp[i];
-
- printf("DSCP = %2" PRIu32 ": Traffic class = %" PRIu32
- ", Color = %s\n",
- i,
- dscp->traffic_class,
- color_to_string(dscp->color));
- }
-
- return 0;
-}
-
-int
-app_pipeline_fa_load_file(char *filename,
- uint32_t *flow_ids,
- struct pipeline_fa_flow_params *p,
- uint32_t *n_flows,
- uint32_t *line)
-{
- FILE *f = NULL;
- char file_buf[1024];
- uint32_t i, l;
-
- /* Check input arguments */
- if ((filename == NULL) ||
- (flow_ids == NULL) ||
- (p == NULL) ||
- (n_flows == NULL) ||
- (*n_flows == 0) ||
- (line == NULL)) {
- if (line)
- *line = 0;
- return -1;
- }
-
- /* Open input file */
- f = fopen(filename, "r");
- if (f == NULL) {
- *line = 0;
- return -1;
- }
-
- /* Read file */
- for (i = 0, l = 1; i < *n_flows; l++) {
- char *tokens[64];
- uint32_t n_tokens = RTE_DIM(tokens);
-
- int status;
-
- if (fgets(file_buf, sizeof(file_buf), f) == NULL)
- break;
-
- status = parse_tokenize_string(file_buf, tokens, &n_tokens);
- if (status)
- goto error1;
-
- if ((n_tokens == 0) || (tokens[0][0] == '#'))
- continue;
-
-
- if ((n_tokens != 64) ||
- /* flow */
- strcmp(tokens[0], "flow") ||
- parser_read_uint32(&flow_ids[i], tokens[1]) ||
-
- /* meter & policer 0 */
- strcmp(tokens[2], "meter") ||
- strcmp(tokens[3], "0") ||
- strcmp(tokens[4], "trtcm") ||
- parser_read_uint64(&p[i].m[0].cir, tokens[5]) ||
- parser_read_uint64(&p[i].m[0].pir, tokens[6]) ||
- parser_read_uint64(&p[i].m[0].cbs, tokens[7]) ||
- parser_read_uint64(&p[i].m[0].pbs, tokens[8]) ||
- strcmp(tokens[9], "policer") ||
- strcmp(tokens[10], "0") ||
- strcmp(tokens[11], "g") ||
- string_to_policer_action(tokens[12],
- &p[i].p[0].action[e_RTE_METER_GREEN]) ||
- strcmp(tokens[13], "y") ||
- string_to_policer_action(tokens[14],
- &p[i].p[0].action[e_RTE_METER_YELLOW]) ||
- strcmp(tokens[15], "r") ||
- string_to_policer_action(tokens[16],
- &p[i].p[0].action[e_RTE_METER_RED]) ||
-
- /* meter & policer 1 */
- strcmp(tokens[17], "meter") ||
- strcmp(tokens[18], "1") ||
- strcmp(tokens[19], "trtcm") ||
- parser_read_uint64(&p[i].m[1].cir, tokens[20]) ||
- parser_read_uint64(&p[i].m[1].pir, tokens[21]) ||
- parser_read_uint64(&p[i].m[1].cbs, tokens[22]) ||
- parser_read_uint64(&p[i].m[1].pbs, tokens[23]) ||
- strcmp(tokens[24], "policer") ||
- strcmp(tokens[25], "1") ||
- strcmp(tokens[26], "g") ||
- string_to_policer_action(tokens[27],
- &p[i].p[1].action[e_RTE_METER_GREEN]) ||
- strcmp(tokens[28], "y") ||
- string_to_policer_action(tokens[29],
- &p[i].p[1].action[e_RTE_METER_YELLOW]) ||
- strcmp(tokens[30], "r") ||
- string_to_policer_action(tokens[31],
- &p[i].p[1].action[e_RTE_METER_RED]) ||
-
- /* meter & policer 2 */
- strcmp(tokens[32], "meter") ||
- strcmp(tokens[33], "2") ||
- strcmp(tokens[34], "trtcm") ||
- parser_read_uint64(&p[i].m[2].cir, tokens[35]) ||
- parser_read_uint64(&p[i].m[2].pir, tokens[36]) ||
- parser_read_uint64(&p[i].m[2].cbs, tokens[37]) ||
- parser_read_uint64(&p[i].m[2].pbs, tokens[38]) ||
- strcmp(tokens[39], "policer") ||
- strcmp(tokens[40], "2") ||
- strcmp(tokens[41], "g") ||
- string_to_policer_action(tokens[42],
- &p[i].p[2].action[e_RTE_METER_GREEN]) ||
- strcmp(tokens[43], "y") ||
- string_to_policer_action(tokens[44],
- &p[i].p[2].action[e_RTE_METER_YELLOW]) ||
- strcmp(tokens[45], "r") ||
- string_to_policer_action(tokens[46],
- &p[i].p[2].action[e_RTE_METER_RED]) ||
-
- /* meter & policer 3 */
- strcmp(tokens[47], "meter") ||
- strcmp(tokens[48], "3") ||
- strcmp(tokens[49], "trtcm") ||
- parser_read_uint64(&p[i].m[3].cir, tokens[50]) ||
- parser_read_uint64(&p[i].m[3].pir, tokens[51]) ||
- parser_read_uint64(&p[i].m[3].cbs, tokens[52]) ||
- parser_read_uint64(&p[i].m[3].pbs, tokens[53]) ||
- strcmp(tokens[54], "policer") ||
- strcmp(tokens[55], "3") ||
- strcmp(tokens[56], "g") ||
- string_to_policer_action(tokens[57],
- &p[i].p[3].action[e_RTE_METER_GREEN]) ||
- strcmp(tokens[58], "y") ||
- string_to_policer_action(tokens[59],
- &p[i].p[3].action[e_RTE_METER_YELLOW]) ||
- strcmp(tokens[60], "r") ||
- string_to_policer_action(tokens[61],
- &p[i].p[3].action[e_RTE_METER_RED]) ||
-
- /* port */
- strcmp(tokens[62], "port") ||
- parser_read_uint32(&p[i].port_id, tokens[63]))
- goto error1;
-
- i++;
- }
-
- /* Close file */
- *n_flows = i;
- fclose(f);
- return 0;
-
-error1:
- *line = l;
- fclose(f);
- return -1;
-}
-
-/*
- * action
- *
- * flow meter, policer and output port configuration:
- * p <pipelineid> action flow <flowid> meter <meterid> trtcm <cir> <pir> <cbs> <pbs>
- *
- * p <pipelineid> action flow <flowid> policer <policerid> g <gaction> y <yaction> r <raction>
- * <action> is one of the following:
- * G = recolor to green
- * Y = recolor as yellow
- * R = recolor as red
- * D = drop
- *
- * p <pipelineid> action flow <flowid> port <port ID>
- *
- * p <pipelineid> action flow bulk <file>
- *
- * flow policer stats read:
- * p <pipelineid> action flow <flowid> stats
- *
- * flow ls:
- * p <pipelineid> action flow ls
- *
- * dscp table configuration:
- * p <pipelineid> action dscp <dscpid> class <class ID> color <color>
- *
- * dscp table ls:
- * p <pipelineid> action dscp ls
-**/
-
-struct cmd_action_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t action_string;
- cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_action_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_action_result *params = parsed_result;
- struct app_params *app = data;
-
- char *tokens[16];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
- if (status != 0) {
- printf(CMD_MSG_TOO_MANY_ARGS, "action");
- return;
- }
-
- /* action flow meter */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "flow") == 0) &&
- strcmp(tokens[1], "bulk") &&
- strcmp(tokens[1], "ls") &&
- (strcmp(tokens[2], "meter") == 0)) {
- struct pipeline_fa_flow_params flow_params;
- uint32_t flow_id, meter_id;
-
- if (n_tokens != 9) {
- printf(CMD_MSG_MISMATCH_ARGS, "action flow meter");
- return;
- }
-
- memset(&flow_params, 0, sizeof(flow_params));
-
- if (parser_read_uint32(&flow_id, tokens[1])) {
- printf(CMD_MSG_INVALID_ARG, "flowid");
- return;
- }
-
- if (parser_read_uint32(&meter_id, tokens[3]) ||
- (meter_id >= PIPELINE_FA_N_TC_MAX)) {
- printf(CMD_MSG_INVALID_ARG, "meterid");
- return;
- }
-
- if (strcmp(tokens[4], "trtcm")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "trtcm");
- return;
- }
-
- if (parser_read_uint64(&flow_params.m[meter_id].cir, tokens[5])) {
- printf(CMD_MSG_INVALID_ARG, "cir");
- return;
- }
-
- if (parser_read_uint64(&flow_params.m[meter_id].pir, tokens[6])) {
- printf(CMD_MSG_INVALID_ARG, "pir");
- return;
- }
-
- if (parser_read_uint64(&flow_params.m[meter_id].cbs, tokens[7])) {
- printf(CMD_MSG_INVALID_ARG, "cbs");
- return;
- }
-
- if (parser_read_uint64(&flow_params.m[meter_id].pbs, tokens[8])) {
- printf(CMD_MSG_INVALID_ARG, "pbs");
- return;
- }
-
- status = app_pipeline_fa_flow_config(app,
- params->pipeline_id,
- flow_id,
- 1 << meter_id,
- 0,
- 0,
- &flow_params);
- if (status)
- printf(CMD_MSG_FAIL, "action flow meter");
-
- return;
- } /* action flow meter */
-
- /* action flow policer */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "flow") == 0) &&
- strcmp(tokens[1], "bulk") &&
- strcmp(tokens[1], "ls") &&
- (strcmp(tokens[2], "policer") == 0)) {
- struct pipeline_fa_flow_params flow_params;
- uint32_t flow_id, policer_id;
-
- if (n_tokens != 10) {
- printf(CMD_MSG_MISMATCH_ARGS, "action flow policer");
- return;
- }
-
- memset(&flow_params, 0, sizeof(flow_params));
-
- if (parser_read_uint32(&flow_id, tokens[1])) {
- printf(CMD_MSG_INVALID_ARG, "flowid");
- return;
- }
-
- if (parser_read_uint32(&policer_id, tokens[3]) ||
- (policer_id >= PIPELINE_FA_N_TC_MAX)) {
- printf(CMD_MSG_INVALID_ARG, "policerid");
- return;
- }
-
- if (strcmp(tokens[4], "g")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "g");
- return;
- }
-
- if (string_to_policer_action(tokens[5],
- &flow_params.p[policer_id].action[e_RTE_METER_GREEN])) {
- printf(CMD_MSG_INVALID_ARG, "gaction");
- return;
- }
-
- if (strcmp(tokens[6], "y")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "y");
- return;
- }
-
- if (string_to_policer_action(tokens[7],
- &flow_params.p[policer_id].action[e_RTE_METER_YELLOW])) {
- printf(CMD_MSG_INVALID_ARG, "yaction");
- return;
- }
-
- if (strcmp(tokens[8], "r")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "r");
- return;
- }
-
- if (string_to_policer_action(tokens[9],
- &flow_params.p[policer_id].action[e_RTE_METER_RED])) {
- printf(CMD_MSG_INVALID_ARG, "raction");
- return;
- }
-
- status = app_pipeline_fa_flow_config(app,
- params->pipeline_id,
- flow_id,
- 0,
- 1 << policer_id,
- 0,
- &flow_params);
- if (status != 0)
- printf(CMD_MSG_FAIL, "action flow policer");
-
- return;
- } /* action flow policer */
-
- /* action flow port */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "flow") == 0) &&
- strcmp(tokens[1], "bulk") &&
- strcmp(tokens[1], "ls") &&
- (strcmp(tokens[2], "port") == 0)) {
- struct pipeline_fa_flow_params flow_params;
- uint32_t flow_id, port_id;
-
- if (n_tokens != 4) {
- printf(CMD_MSG_MISMATCH_ARGS, "action flow port");
- return;
- }
-
- memset(&flow_params, 0, sizeof(flow_params));
-
- if (parser_read_uint32(&flow_id, tokens[1])) {
- printf(CMD_MSG_INVALID_ARG, "flowid");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[3])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- flow_params.port_id = port_id;
-
- status = app_pipeline_fa_flow_config(app,
- params->pipeline_id,
- flow_id,
- 0,
- 0,
- 1,
- &flow_params);
- if (status)
- printf(CMD_MSG_FAIL, "action flow port");
-
- return;
- } /* action flow port */
-
- /* action flow stats */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "flow") == 0) &&
- strcmp(tokens[1], "bulk") &&
- strcmp(tokens[1], "ls") &&
- (strcmp(tokens[2], "stats") == 0)) {
- struct pipeline_fa_policer_stats stats;
- uint32_t flow_id, policer_id;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "action flow stats");
- return;
- }
-
- if (parser_read_uint32(&flow_id, tokens[1])) {
- printf(CMD_MSG_INVALID_ARG, "flowid");
- return;
- }
-
- for (policer_id = 0;
- policer_id < PIPELINE_FA_N_TC_MAX;
- policer_id++) {
- status = app_pipeline_fa_flow_policer_stats_read(app,
- params->pipeline_id,
- flow_id,
- policer_id,
- 1,
- &stats);
- if (status != 0) {
- printf(CMD_MSG_FAIL, "action flow stats");
- return;
- }
-
- /* Display stats */
- printf("\tPolicer: %" PRIu32
- "\tPkts G: %" PRIu64
- "\tPkts Y: %" PRIu64
- "\tPkts R: %" PRIu64
- "\tPkts D: %" PRIu64 "\n",
- policer_id,
- stats.n_pkts[e_RTE_METER_GREEN],
- stats.n_pkts[e_RTE_METER_YELLOW],
- stats.n_pkts[e_RTE_METER_RED],
- stats.n_pkts_drop);
- }
-
- return;
- } /* action flow stats */
-
- /* action flow bulk */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "flow") == 0) &&
- (strcmp(tokens[1], "bulk") == 0)) {
- struct pipeline_fa_flow_params *flow_params;
- uint32_t *flow_ids, n_flows, line;
- char *filename;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "action flow bulk");
- return;
- }
-
- filename = tokens[2];
-
- n_flows = APP_PIPELINE_FA_MAX_RECORDS_IN_FILE;
- flow_ids = malloc(n_flows * sizeof(uint32_t));
- if (flow_ids == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- return;
- }
-
- flow_params = malloc(n_flows * sizeof(struct pipeline_fa_flow_params));
- if (flow_params == NULL) {
- printf(CMD_MSG_OUT_OF_MEMORY);
- free(flow_ids);
- return;
- }
-
- status = app_pipeline_fa_load_file(filename,
- flow_ids,
- flow_params,
- &n_flows,
- &line);
- if (status) {
- printf(CMD_MSG_FILE_ERR, filename, line);
- free(flow_params);
- free(flow_ids);
- return;
- }
-
- status = app_pipeline_fa_flow_config_bulk(app,
- params->pipeline_id,
- flow_ids,
- n_flows,
- 0xF,
- 0xF,
- 1,
- flow_params);
- if (status)
- printf(CMD_MSG_FAIL, "action flow bulk");
-
- free(flow_params);
- free(flow_ids);
- return;
- } /* action flow bulk */
-
- /* action flow ls */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "flow") == 0) &&
- (strcmp(tokens[1], "ls") == 0)) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "action flow ls");
- return;
- }
-
- status = app_pipeline_fa_flow_ls(app,
- params->pipeline_id);
- if (status)
- printf(CMD_MSG_FAIL, "action flow ls");
-
- return;
- } /* action flow ls */
-
- /* action dscp */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "dscp") == 0) &&
- strcmp(tokens[1], "ls")) {
- uint32_t dscp_id, tc_id;
- enum rte_meter_color color;
-
- if (n_tokens != 6) {
- printf(CMD_MSG_MISMATCH_ARGS, "action dscp");
- return;
- }
-
- if (parser_read_uint32(&dscp_id, tokens[1])) {
- printf(CMD_MSG_INVALID_ARG, "dscpid");
- return;
- }
-
- if (strcmp(tokens[2], "class")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "class");
- return;
- }
-
- if (parser_read_uint32(&tc_id, tokens[3])) {
- printf(CMD_MSG_INVALID_ARG, "classid");
- return;
- }
-
- if (strcmp(tokens[4], "color")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "color");
- return;
- }
-
- if (string_to_color(tokens[5], &color)) {
- printf(CMD_MSG_INVALID_ARG, "colorid");
- return;
- }
-
- status = app_pipeline_fa_dscp_config(app,
- params->pipeline_id,
- dscp_id,
- tc_id,
- color);
- if (status != 0)
- printf(CMD_MSG_FAIL, "action dscp");
-
- return;
- } /* action dscp */
-
- /* action dscp ls */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "dscp") == 0) &&
- (strcmp(tokens[1], "ls") == 0)) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "action dscp ls");
- return;
- }
-
- status = app_pipeline_fa_dscp_ls(app,
- params->pipeline_id);
- if (status)
- printf(CMD_MSG_FAIL, "action dscp ls");
-
- return;
- } /* action dscp ls */
-
- printf(CMD_MSG_FAIL, "action");
-}
-
-static cmdline_parse_token_string_t cmd_action_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_action_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_action_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_action_result, pipeline_id, UINT32);
-
-static cmdline_parse_token_string_t cmd_action_action_string =
- TOKEN_STRING_INITIALIZER(struct cmd_action_result, action_string, "action");
-
-static cmdline_parse_token_string_t cmd_action_multi_string =
- TOKEN_STRING_INITIALIZER(struct cmd_action_result, multi_string,
- TOKEN_STRING_MULTI);
-
-cmdline_parse_inst_t cmd_action = {
- .f = cmd_action_parsed,
- .data = NULL,
- .help_str = "flow actions (meter, policer, policer stats, dscp table)",
- .tokens = {
- (void *) &cmd_action_p_string,
- (void *) &cmd_action_pipeline_id,
- (void *) &cmd_action_action_string,
- (void *) &cmd_action_multi_string,
- NULL,
- },
-};
-
-static cmdline_parse_ctx_t pipeline_cmds[] = {
- (cmdline_parse_inst_t *) &cmd_action,
- NULL,
-};
-
-static struct pipeline_fe_ops pipeline_flow_actions_fe_ops = {
- .f_init = app_pipeline_fa_init,
- .f_post_init = NULL,
- .f_free = app_pipeline_fa_free,
- .f_track = app_pipeline_track_default,
- .cmds = pipeline_cmds,
-};
-
-struct pipeline_type pipeline_flow_actions = {
- .name = "FLOW_ACTIONS",
- .be_ops = &pipeline_flow_actions_be_ops,
- .fe_ops = &pipeline_flow_actions_fe_ops,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions.h b/examples/ip_pipeline/pipeline/pipeline_flow_actions.h
deleted file mode 100644
index 885923e4..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_FLOW_ACTIONS_H__
-#define __INCLUDE_PIPELINE_FLOW_ACTIONS_H__
-
-#include <rte_meter.h>
-
-#include "pipeline.h"
-#include "pipeline_flow_actions_be.h"
-
-int
-app_pipeline_fa_flow_config(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t flow_id,
- uint32_t meter_update_mask,
- uint32_t policer_update_mask,
- uint32_t port_update,
- struct pipeline_fa_flow_params *params);
-
-int
-app_pipeline_fa_flow_config_bulk(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t *flow_id,
- uint32_t n_flows,
- uint32_t meter_update_mask,
- uint32_t policer_update_mask,
- uint32_t port_update,
- struct pipeline_fa_flow_params *params);
-
-int
-app_pipeline_fa_dscp_config(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t dscp,
- uint32_t traffic_class,
- enum rte_meter_color color);
-
-int
-app_pipeline_fa_flow_policer_stats_read(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t flow_id,
- uint32_t policer_id,
- int clear,
- struct pipeline_fa_policer_stats *stats);
-
-#ifndef APP_PIPELINE_FA_MAX_RECORDS_IN_FILE
-#define APP_PIPELINE_FA_MAX_RECORDS_IN_FILE 65536
-#endif
-
-int
-app_pipeline_fa_load_file(char *filename,
- uint32_t *flow_ids,
- struct pipeline_fa_flow_params *p,
- uint32_t *n_flows,
- uint32_t *line);
-
-extern struct pipeline_type pipeline_flow_actions;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
deleted file mode 100644
index 9599b7d8..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
+++ /dev/null
@@ -1,960 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_cycles.h>
-#include <rte_table_array.h>
-#include <rte_byteorder.h>
-#include <rte_ip.h>
-
-#include "pipeline_actions_common.h"
-#include "pipeline_flow_actions_be.h"
-#include "parser.h"
-#include "hash_func.h"
-
-int
-pipeline_fa_flow_params_set_default(struct pipeline_fa_flow_params *params)
-{
- uint32_t i;
-
- if (params == NULL)
- return -1;
-
- for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++) {
- struct rte_meter_trtcm_params *m = &params->m[i];
-
- m->cir = 1;
- m->cbs = 1;
- m->pir = 1;
- m->pbs = 2;
- }
-
- for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++) {
- struct pipeline_fa_policer_params *p = &params->p[i];
- uint32_t j;
-
- for (j = 0; j < e_RTE_METER_COLORS; j++) {
- struct pipeline_fa_policer_action *a = &p->action[j];
-
- a->drop = 0;
- a->color = (enum rte_meter_color) j;
- }
- }
-
- params->port_id = 0;
-
- return 0;
-}
-
-struct dscp_entry {
- uint32_t traffic_class;
- enum rte_meter_color color;
-};
-
-struct pipeline_flow_actions {
- struct pipeline p;
- struct pipeline_fa_params params;
- pipeline_msg_req_handler custom_handlers[PIPELINE_FA_MSG_REQS];
-
- struct dscp_entry dscp[PIPELINE_FA_N_DSCP];
-} __rte_cache_aligned;
-
-static void *
-pipeline_fa_msg_req_custom_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler handlers[] = {
- [PIPELINE_MSG_REQ_PING] =
- pipeline_msg_req_ping_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_IN] =
- pipeline_msg_req_stats_port_in_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
- pipeline_msg_req_stats_port_out_handler,
- [PIPELINE_MSG_REQ_STATS_TABLE] =
- pipeline_msg_req_stats_table_handler,
- [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
- pipeline_msg_req_port_in_enable_handler,
- [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
- pipeline_msg_req_port_in_disable_handler,
- [PIPELINE_MSG_REQ_CUSTOM] =
- pipeline_fa_msg_req_custom_handler,
-};
-
-static void *
-pipeline_fa_msg_req_flow_config_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_fa_msg_req_flow_config_bulk_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_fa_msg_req_dscp_config_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_fa_msg_req_policer_stats_read_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler custom_handlers[] = {
- [PIPELINE_FA_MSG_REQ_FLOW_CONFIG] =
- pipeline_fa_msg_req_flow_config_handler,
- [PIPELINE_FA_MSG_REQ_FLOW_CONFIG_BULK] =
- pipeline_fa_msg_req_flow_config_bulk_handler,
- [PIPELINE_FA_MSG_REQ_DSCP_CONFIG] =
- pipeline_fa_msg_req_dscp_config_handler,
- [PIPELINE_FA_MSG_REQ_POLICER_STATS_READ] =
- pipeline_fa_msg_req_policer_stats_read_handler,
-};
-
-/*
- * Flow table
- */
-struct meter_policer {
- struct rte_meter_trtcm meter;
- struct pipeline_fa_policer_params policer;
- struct pipeline_fa_policer_stats stats;
-};
-
-struct flow_table_entry {
- struct rte_pipeline_table_entry head;
- struct meter_policer mp[PIPELINE_FA_N_TC_MAX];
-};
-
-static int
-flow_table_entry_set_meter(struct flow_table_entry *entry,
- uint32_t meter_id,
- struct pipeline_fa_flow_params *params)
-{
- struct rte_meter_trtcm *meter = &entry->mp[meter_id].meter;
- struct rte_meter_trtcm_params *meter_params = &params->m[meter_id];
-
- return rte_meter_trtcm_config(meter, meter_params);
-}
-
-static void
-flow_table_entry_set_policer(struct flow_table_entry *entry,
- uint32_t policer_id,
- struct pipeline_fa_flow_params *params)
-{
- struct pipeline_fa_policer_params *p0 = &entry->mp[policer_id].policer;
- struct pipeline_fa_policer_params *p1 = &params->p[policer_id];
-
- memcpy(p0, p1, sizeof(*p0));
-}
-
-static void
-flow_table_entry_set_port_id(struct pipeline_flow_actions *p,
- struct flow_table_entry *entry,
- struct pipeline_fa_flow_params *params)
-{
- entry->head.action = RTE_PIPELINE_ACTION_PORT;
- entry->head.port_id = p->p.port_out_id[params->port_id];
-}
-
-static int
-flow_table_entry_set_default(struct pipeline_flow_actions *p,
- struct flow_table_entry *entry)
-{
- struct pipeline_fa_flow_params params;
- uint32_t i;
-
- pipeline_fa_flow_params_set_default(&params);
-
- memset(entry, 0, sizeof(*entry));
-
- flow_table_entry_set_port_id(p, entry, &params);
-
- for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++) {
- int status;
-
- status = flow_table_entry_set_meter(entry, i, &params);
- if (status)
- return status;
- }
-
- for (i = 0; i < PIPELINE_FA_N_TC_MAX; i++)
- flow_table_entry_set_policer(entry, i, &params);
-
- return 0;
-}
-
-static inline uint64_t
-pkt_work(
- struct rte_mbuf *pkt,
- struct rte_pipeline_table_entry *table_entry,
- void *arg,
- uint64_t time)
-{
- struct pipeline_flow_actions *p = arg;
- struct flow_table_entry *entry =
- (struct flow_table_entry *) table_entry;
-
- struct ipv4_hdr *pkt_ip = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT32_PTR(pkt, p->params.ip_hdr_offset);
- enum rte_meter_color *pkt_color = (enum rte_meter_color *)
- RTE_MBUF_METADATA_UINT32_PTR(pkt, p->params.color_offset);
-
- /* Read (IP header) */
- uint32_t total_length = rte_bswap16(pkt_ip->total_length);
- uint32_t dscp = pkt_ip->type_of_service >> 2;
-
- uint32_t tc = p->dscp[dscp].traffic_class;
- enum rte_meter_color color = p->dscp[dscp].color;
-
- struct rte_meter_trtcm *meter = &entry->mp[tc].meter;
- struct pipeline_fa_policer_params *policer = &entry->mp[tc].policer;
- struct pipeline_fa_policer_stats *stats = &entry->mp[tc].stats;
-
- /* Read (entry), compute */
- enum rte_meter_color color2 = rte_meter_trtcm_color_aware_check(meter,
- time,
- total_length,
- color);
-
- enum rte_meter_color color3 = policer->action[color2].color;
- uint64_t drop = policer->action[color2].drop;
-
- /* Read (entry), write (entry, color) */
- stats->n_pkts[color3] += drop ^ 1LLU;
- stats->n_pkts_drop += drop;
- *pkt_color = color3;
-
- return drop;
-}
-
-static inline uint64_t
-pkt4_work(
- struct rte_mbuf **pkts,
- struct rte_pipeline_table_entry **table_entries,
- void *arg,
- uint64_t time)
-{
- struct pipeline_flow_actions *p = arg;
-
- struct flow_table_entry *entry0 =
- (struct flow_table_entry *) table_entries[0];
- struct flow_table_entry *entry1 =
- (struct flow_table_entry *) table_entries[1];
- struct flow_table_entry *entry2 =
- (struct flow_table_entry *) table_entries[2];
- struct flow_table_entry *entry3 =
- (struct flow_table_entry *) table_entries[3];
-
- struct ipv4_hdr *pkt0_ip = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[0], p->params.ip_hdr_offset);
- struct ipv4_hdr *pkt1_ip = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[1], p->params.ip_hdr_offset);
- struct ipv4_hdr *pkt2_ip = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[2], p->params.ip_hdr_offset);
- struct ipv4_hdr *pkt3_ip = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[3], p->params.ip_hdr_offset);
-
- enum rte_meter_color *pkt0_color = (enum rte_meter_color *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[0], p->params.color_offset);
- enum rte_meter_color *pkt1_color = (enum rte_meter_color *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[1], p->params.color_offset);
- enum rte_meter_color *pkt2_color = (enum rte_meter_color *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[2], p->params.color_offset);
- enum rte_meter_color *pkt3_color = (enum rte_meter_color *)
- RTE_MBUF_METADATA_UINT32_PTR(pkts[3], p->params.color_offset);
-
- /* Read (IP header) */
- uint32_t total_length0 = rte_bswap16(pkt0_ip->total_length);
- uint32_t dscp0 = pkt0_ip->type_of_service >> 2;
-
- uint32_t total_length1 = rte_bswap16(pkt1_ip->total_length);
- uint32_t dscp1 = pkt1_ip->type_of_service >> 2;
-
- uint32_t total_length2 = rte_bswap16(pkt2_ip->total_length);
- uint32_t dscp2 = pkt2_ip->type_of_service >> 2;
-
- uint32_t total_length3 = rte_bswap16(pkt3_ip->total_length);
- uint32_t dscp3 = pkt3_ip->type_of_service >> 2;
-
- uint32_t tc0 = p->dscp[dscp0].traffic_class;
- enum rte_meter_color color0 = p->dscp[dscp0].color;
-
- uint32_t tc1 = p->dscp[dscp1].traffic_class;
- enum rte_meter_color color1 = p->dscp[dscp1].color;
-
- uint32_t tc2 = p->dscp[dscp2].traffic_class;
- enum rte_meter_color color2 = p->dscp[dscp2].color;
-
- uint32_t tc3 = p->dscp[dscp3].traffic_class;
- enum rte_meter_color color3 = p->dscp[dscp3].color;
-
- struct rte_meter_trtcm *meter0 = &entry0->mp[tc0].meter;
- struct pipeline_fa_policer_params *policer0 = &entry0->mp[tc0].policer;
- struct pipeline_fa_policer_stats *stats0 = &entry0->mp[tc0].stats;
-
- struct rte_meter_trtcm *meter1 = &entry1->mp[tc1].meter;
- struct pipeline_fa_policer_params *policer1 = &entry1->mp[tc1].policer;
- struct pipeline_fa_policer_stats *stats1 = &entry1->mp[tc1].stats;
-
- struct rte_meter_trtcm *meter2 = &entry2->mp[tc2].meter;
- struct pipeline_fa_policer_params *policer2 = &entry2->mp[tc2].policer;
- struct pipeline_fa_policer_stats *stats2 = &entry2->mp[tc2].stats;
-
- struct rte_meter_trtcm *meter3 = &entry3->mp[tc3].meter;
- struct pipeline_fa_policer_params *policer3 = &entry3->mp[tc3].policer;
- struct pipeline_fa_policer_stats *stats3 = &entry3->mp[tc3].stats;
-
- /* Read (entry), compute, write (entry) */
- enum rte_meter_color color2_0 = rte_meter_trtcm_color_aware_check(
- meter0,
- time,
- total_length0,
- color0);
-
- enum rte_meter_color color2_1 = rte_meter_trtcm_color_aware_check(
- meter1,
- time,
- total_length1,
- color1);
-
- enum rte_meter_color color2_2 = rte_meter_trtcm_color_aware_check(
- meter2,
- time,
- total_length2,
- color2);
-
- enum rte_meter_color color2_3 = rte_meter_trtcm_color_aware_check(
- meter3,
- time,
- total_length3,
- color3);
-
- enum rte_meter_color color3_0 = policer0->action[color2_0].color;
- enum rte_meter_color color3_1 = policer1->action[color2_1].color;
- enum rte_meter_color color3_2 = policer2->action[color2_2].color;
- enum rte_meter_color color3_3 = policer3->action[color2_3].color;
-
- uint64_t drop0 = policer0->action[color2_0].drop;
- uint64_t drop1 = policer1->action[color2_1].drop;
- uint64_t drop2 = policer2->action[color2_2].drop;
- uint64_t drop3 = policer3->action[color2_3].drop;
-
- /* Read (entry), write (entry, color) */
- stats0->n_pkts[color3_0] += drop0 ^ 1LLU;
- stats0->n_pkts_drop += drop0;
-
- stats1->n_pkts[color3_1] += drop1 ^ 1LLU;
- stats1->n_pkts_drop += drop1;
-
- stats2->n_pkts[color3_2] += drop2 ^ 1LLU;
- stats2->n_pkts_drop += drop2;
-
- stats3->n_pkts[color3_3] += drop3 ^ 1LLU;
- stats3->n_pkts_drop += drop3;
-
- *pkt0_color = color3_0;
- *pkt1_color = color3_1;
- *pkt2_color = color3_2;
- *pkt3_color = color3_3;
-
- return drop0 | (drop1 << 1) | (drop2 << 2) | (drop3 << 3);
-}
-
-PIPELINE_TABLE_AH_HIT_DROP_TIME(fa_table_ah_hit, pkt_work, pkt4_work);
-
-static rte_pipeline_table_action_handler_hit
-get_fa_table_ah_hit(__rte_unused struct pipeline_flow_actions *p)
-{
- return fa_table_ah_hit;
-}
-
-/*
- * Argument parsing
- */
-int
-pipeline_fa_parse_args(struct pipeline_fa_params *p,
- struct pipeline_params *params)
-{
- uint32_t n_flows_present = 0;
- uint32_t n_meters_per_flow_present = 0;
- uint32_t flow_id_offset_present = 0;
- uint32_t ip_hdr_offset_present = 0;
- uint32_t color_offset_present = 0;
- uint32_t i;
-
- /* Default values */
- p->n_meters_per_flow = 1;
- p->dscp_enabled = 0;
-
- for (i = 0; i < params->n_args; i++) {
- char *arg_name = params->args_name[i];
- char *arg_value = params->args_value[i];
-
- /* n_flows */
- if (strcmp(arg_name, "n_flows") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- n_flows_present == 0, params->name,
- arg_name);
- n_flows_present = 1;
-
- status = parser_read_uint32(&p->n_flows,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
- (p->n_flows != 0)), params->name,
- arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* n_meters_per_flow */
- if (strcmp(arg_name, "n_meters_per_flow") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- n_meters_per_flow_present == 0,
- params->name, arg_name);
- n_meters_per_flow_present = 1;
-
- status = parser_read_uint32(&p->n_meters_per_flow,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
- (p->n_meters_per_flow != 0)),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
- (p->n_meters_per_flow <=
- PIPELINE_FA_N_TC_MAX)), params->name,
- arg_name, arg_value);
-
- continue;
- }
-
- /* flow_id_offset */
- if (strcmp(arg_name, "flow_id_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- flow_id_offset_present == 0,
- params->name, arg_name);
- flow_id_offset_present = 1;
-
- status = parser_read_uint32(&p->flow_id_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* ip_hdr_offset */
- if (strcmp(arg_name, "ip_hdr_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- ip_hdr_offset_present == 0,
- params->name, arg_name);
- ip_hdr_offset_present = 1;
-
- status = parser_read_uint32(&p->ip_hdr_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* color_offset */
- if (strcmp(arg_name, "color_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- color_offset_present == 0, params->name,
- arg_name);
- color_offset_present = 1;
-
- status = parser_read_uint32(&p->color_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->dscp_enabled = 1;
-
- continue;
- }
-
- /* Unknown argument */
- PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
- }
-
- /* Check that mandatory arguments are present */
- PIPELINE_PARSE_ERR_MANDATORY((n_flows_present), params->name,
- "n_flows");
- PIPELINE_PARSE_ERR_MANDATORY((flow_id_offset_present),
- params->name, "flow_id_offset");
- PIPELINE_PARSE_ERR_MANDATORY((ip_hdr_offset_present),
- params->name, "ip_hdr_offset");
- PIPELINE_PARSE_ERR_MANDATORY((color_offset_present), params->name,
- "color_offset");
-
- return 0;
-}
-
-static void
-dscp_init(struct pipeline_flow_actions *p)
-{
- uint32_t i;
-
- for (i = 0; i < PIPELINE_FA_N_DSCP; i++) {
- p->dscp[i].traffic_class = 0;
- p->dscp[i].color = e_RTE_METER_GREEN;
- }
-}
-
-static void *pipeline_fa_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct pipeline *p;
- struct pipeline_flow_actions *p_fa;
- uint32_t size, i;
-
- /* Check input arguments */
- if (params == NULL)
- return NULL;
-
- if (params->n_ports_in != params->n_ports_out)
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(
- sizeof(struct pipeline_flow_actions));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p == NULL)
- return NULL;
- p_fa = (struct pipeline_flow_actions *) p;
-
- strcpy(p->name, params->name);
- p->log_level = params->log_level;
-
- PLOG(p, HIGH, "Flow actions");
-
- /* Parse arguments */
- if (pipeline_fa_parse_args(&p_fa->params, params))
- return NULL;
-
- dscp_init(p_fa);
-
- /* Pipeline */
- {
- struct rte_pipeline_params pipeline_params = {
- .name = params->name,
- .socket_id = params->socket_id,
- .offset_port_id = 0,
- };
-
- p->p = rte_pipeline_create(&pipeline_params);
- if (p->p == NULL) {
- rte_free(p);
- return NULL;
- }
- }
-
- /* Input ports */
- p->n_ports_in = params->n_ports_in;
- for (i = 0; i < p->n_ports_in; i++) {
- struct rte_pipeline_port_in_params port_params = {
- .ops = pipeline_port_in_params_get_ops(
- &params->port_in[i]),
- .arg_create = pipeline_port_in_params_convert(
- &params->port_in[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = params->port_in[i].burst_size,
- };
-
- int status = rte_pipeline_port_in_create(p->p,
- &port_params,
- &p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Output ports */
- p->n_ports_out = params->n_ports_out;
- for (i = 0; i < p->n_ports_out; i++) {
- struct rte_pipeline_port_out_params port_params = {
- .ops = pipeline_port_out_params_get_ops(
- &params->port_out[i]),
- .arg_create = pipeline_port_out_params_convert(
- &params->port_out[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- int status = rte_pipeline_port_out_create(p->p,
- &port_params,
- &p->port_out_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Tables */
- p->n_tables = 1;
- {
- struct rte_table_array_params table_array_params = {
- .n_entries = p_fa->params.n_flows,
- .offset = p_fa->params.flow_id_offset,
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_array_ops,
- .arg_create = &table_array_params,
- .f_action_hit = get_fa_table_ah_hit(p_fa),
- .f_action_miss = NULL,
- .arg_ah = p_fa,
- .action_data_size =
- sizeof(struct flow_table_entry) -
- sizeof(struct rte_pipeline_table_entry),
- };
-
- int status;
-
- status = rte_pipeline_table_create(p->p,
- &table_params,
- &p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Connecting input ports to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_connect_to_table(p->p,
- p->port_in_id[i],
- p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_enable(p->p,
- p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Initialize table entries */
- for (i = 0; i < p_fa->params.n_flows; i++) {
- struct rte_table_array_key key = {
- .pos = i,
- };
-
- struct flow_table_entry entry;
- struct rte_pipeline_table_entry *entry_ptr;
- int key_found, status;
-
- flow_table_entry_set_default(p_fa, &entry);
-
- status = rte_pipeline_table_entry_add(p->p,
- p->table_id[0],
- &key,
- (struct rte_pipeline_table_entry *) &entry,
- &key_found,
- &entry_ptr);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p->p) < 0) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
-
- /* Message queues */
- p->n_msgq = params->n_msgq;
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_in[i] = params->msgq_in[i];
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_out[i] = params->msgq_out[i];
-
- /* Message handlers */
- memcpy(p->handlers, handlers, sizeof(p->handlers));
- memcpy(p_fa->custom_handlers,
- custom_handlers,
- sizeof(p_fa->custom_handlers));
-
- return p;
-}
-
-static int
-pipeline_fa_free(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- rte_pipeline_free(p->p);
- rte_free(p);
- return 0;
-}
-
-static int
-pipeline_fa_timer(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- pipeline_msg_req_handle(p);
- rte_pipeline_flush(p->p);
-
- return 0;
-}
-
-void *
-pipeline_fa_msg_req_custom_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_flow_actions *p_fa =
- (struct pipeline_flow_actions *) p;
- struct pipeline_custom_msg_req *req = msg;
- pipeline_msg_req_handler f_handle;
-
- f_handle = (req->subtype < PIPELINE_FA_MSG_REQS) ?
- p_fa->custom_handlers[req->subtype] :
- pipeline_msg_req_invalid_handler;
-
- if (f_handle == NULL)
- f_handle = pipeline_msg_req_invalid_handler;
-
- return f_handle(p, req);
-}
-
-void *
-pipeline_fa_msg_req_flow_config_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_flow_actions *p_fa = (struct pipeline_flow_actions *) p;
- struct pipeline_fa_flow_config_msg_req *req = msg;
- struct pipeline_fa_flow_config_msg_rsp *rsp = msg;
- struct flow_table_entry *entry;
- uint32_t mask, i;
-
- /* Set flow table entry to default if not configured before */
- if (req->entry_ptr == NULL) {
- struct rte_table_array_key key = {
- .pos = req->flow_id % p_fa->params.n_flows,
- };
-
- struct flow_table_entry default_entry;
-
- int key_found, status;
-
- flow_table_entry_set_default(p_fa, &default_entry);
-
- status = rte_pipeline_table_entry_add(p->p,
- p->table_id[0],
- &key,
- (struct rte_pipeline_table_entry *) &default_entry,
- &key_found,
- (struct rte_pipeline_table_entry **) &entry);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
- } else
- entry = (struct flow_table_entry *) req->entry_ptr;
-
- /* Meter */
- for (i = 0, mask = 1; i < PIPELINE_FA_N_TC_MAX; i++, mask <<= 1) {
- int status;
-
- if ((mask & req->meter_update_mask) == 0)
- continue;
-
- status = flow_table_entry_set_meter(entry, i, &req->params);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
- }
-
- /* Policer */
- for (i = 0, mask = 1; i < PIPELINE_FA_N_TC_MAX; i++, mask <<= 1) {
- if ((mask & req->policer_update_mask) == 0)
- continue;
-
- flow_table_entry_set_policer(entry, i, &req->params);
- }
-
- /* Port */
- if (req->port_update)
- flow_table_entry_set_port_id(p_fa, entry, &req->params);
-
- /* Response */
- rsp->status = 0;
- rsp->entry_ptr = (void *) entry;
- return rsp;
-}
-
-void *
-pipeline_fa_msg_req_flow_config_bulk_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_flow_actions *p_fa = (struct pipeline_flow_actions *) p;
- struct pipeline_fa_flow_config_bulk_msg_req *req = msg;
- struct pipeline_fa_flow_config_bulk_msg_rsp *rsp = msg;
- uint32_t i;
-
- for (i = 0; i < req->n_flows; i++) {
- struct flow_table_entry *entry;
- uint32_t j, mask;
-
- /* Set flow table entry to default if not configured before */
- if (req->entry_ptr[i] == NULL) {
- struct rte_table_array_key key = {
- .pos = req->flow_id[i] % p_fa->params.n_flows,
- };
-
- struct flow_table_entry entry_to_add;
-
- int key_found, status;
-
- flow_table_entry_set_default(p_fa, &entry_to_add);
-
- status = rte_pipeline_table_entry_add(p->p,
- p->table_id[0],
- &key,
- (struct rte_pipeline_table_entry *) &entry_to_add,
- &key_found,
- (struct rte_pipeline_table_entry **) &entry);
- if (status) {
- rsp->n_flows = i;
- return rsp;
- }
-
- req->entry_ptr[i] = (void *) entry;
- } else
- entry = (struct flow_table_entry *) req->entry_ptr[i];
-
- /* Meter */
- for (j = 0, mask = 1;
- j < PIPELINE_FA_N_TC_MAX;
- j++, mask <<= 1) {
- int status;
-
- if ((mask & req->meter_update_mask) == 0)
- continue;
-
- status = flow_table_entry_set_meter(entry,
- j, &req->params[i]);
- if (status) {
- rsp->n_flows = i;
- return rsp;
- }
- }
-
- /* Policer */
- for (j = 0, mask = 1;
- j < PIPELINE_FA_N_TC_MAX;
- j++, mask <<= 1) {
- if ((mask & req->policer_update_mask) == 0)
- continue;
-
- flow_table_entry_set_policer(entry,
- j, &req->params[i]);
- }
-
- /* Port */
- if (req->port_update)
- flow_table_entry_set_port_id(p_fa,
- entry, &req->params[i]);
- }
-
- /* Response */
- rsp->n_flows = i;
- return rsp;
-}
-
-void *
-pipeline_fa_msg_req_dscp_config_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_flow_actions *p_fa = (struct pipeline_flow_actions *) p;
- struct pipeline_fa_dscp_config_msg_req *req = msg;
- struct pipeline_fa_dscp_config_msg_rsp *rsp = msg;
-
- /* Check request */
- if ((req->dscp >= PIPELINE_FA_N_DSCP) ||
- (req->traffic_class >= PIPELINE_FA_N_TC_MAX) ||
- (req->color >= e_RTE_METER_COLORS)) {
- rsp->status = -1;
- return rsp;
- }
-
- p_fa->dscp[req->dscp].traffic_class = req->traffic_class;
- p_fa->dscp[req->dscp].color = req->color;
- rsp->status = 0;
- return rsp;
-}
-
-void *
-pipeline_fa_msg_req_policer_stats_read_handler(__rte_unused struct pipeline *p,
- void *msg)
-{
- struct pipeline_fa_policer_stats_msg_req *req = msg;
- struct pipeline_fa_policer_stats_msg_rsp *rsp = msg;
-
- struct flow_table_entry *entry = req->entry_ptr;
- uint32_t policer_id = req->policer_id;
- int clear = req->clear;
-
- /* Check request */
- if ((req->entry_ptr == NULL) ||
- (req->policer_id >= PIPELINE_FA_N_TC_MAX)) {
- rsp->status = -1;
- return rsp;
- }
-
- memcpy(&rsp->stats,
- &entry->mp[policer_id].stats,
- sizeof(rsp->stats));
- if (clear)
- memset(&entry->mp[policer_id].stats,
- 0, sizeof(entry->mp[policer_id].stats));
- rsp->status = 0;
- return rsp;
-}
-
-struct pipeline_be_ops pipeline_flow_actions_be_ops = {
- .f_init = pipeline_fa_init,
- .f_free = pipeline_fa_free,
- .f_run = NULL,
- .f_timer = pipeline_fa_timer,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.h b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.h
deleted file mode 100644
index ef6cb263..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_FLOW_ACTIONS_BE_H__
-#define __INCLUDE_PIPELINE_FLOW_ACTIONS_BE_H__
-
-#include <rte_meter.h>
-
-#include "pipeline_common_be.h"
-
-#ifndef PIPELINE_FA_N_TC_MAX
-#define PIPELINE_FA_N_TC_MAX 4
-#endif
-
-#define PIPELINE_FA_N_DSCP 64
-
-struct pipeline_fa_params {
- uint32_t n_flows;
- uint32_t n_meters_per_flow;
- uint32_t flow_id_offset;
- uint32_t ip_hdr_offset;
- uint32_t color_offset;
- uint32_t dscp_enabled;
-};
-
-int
-pipeline_fa_parse_args(struct pipeline_fa_params *p,
- struct pipeline_params *params);
-
-struct pipeline_fa_policer_action {
- uint32_t drop;
- enum rte_meter_color color;
-};
-
-struct pipeline_fa_policer_params {
- struct pipeline_fa_policer_action action[e_RTE_METER_COLORS];
-};
-
-struct pipeline_fa_flow_params {
- struct rte_meter_trtcm_params m[PIPELINE_FA_N_TC_MAX];
- struct pipeline_fa_policer_params p[PIPELINE_FA_N_TC_MAX];
- uint32_t port_id;
-};
-
-int
-pipeline_fa_flow_params_set_default(struct pipeline_fa_flow_params *params);
-
-struct pipeline_fa_policer_stats {
- uint64_t n_pkts[e_RTE_METER_COLORS];
- uint64_t n_pkts_drop;
-};
-
-enum pipeline_fa_msg_req_type {
- PIPELINE_FA_MSG_REQ_FLOW_CONFIG = 0,
- PIPELINE_FA_MSG_REQ_FLOW_CONFIG_BULK,
- PIPELINE_FA_MSG_REQ_DSCP_CONFIG,
- PIPELINE_FA_MSG_REQ_POLICER_STATS_READ,
- PIPELINE_FA_MSG_REQS,
-};
-
-/*
- * MSG FLOW CONFIG
- */
-struct pipeline_fa_flow_config_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fa_msg_req_type subtype;
-
- void *entry_ptr;
- uint32_t flow_id;
-
- uint32_t meter_update_mask;
- uint32_t policer_update_mask;
- uint32_t port_update;
- struct pipeline_fa_flow_params params;
-};
-
-struct pipeline_fa_flow_config_msg_rsp {
- int status;
- void *entry_ptr;
-};
-
-/*
- * MSG FLOW CONFIG BULK
- */
-struct pipeline_fa_flow_config_bulk_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fa_msg_req_type subtype;
-
- void **entry_ptr;
- uint32_t *flow_id;
- uint32_t n_flows;
-
- uint32_t meter_update_mask;
- uint32_t policer_update_mask;
- uint32_t port_update;
- struct pipeline_fa_flow_params *params;
-};
-
-struct pipeline_fa_flow_config_bulk_msg_rsp {
- uint32_t n_flows;
-};
-
-/*
- * MSG DSCP CONFIG
- */
-struct pipeline_fa_dscp_config_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fa_msg_req_type subtype;
-
- uint32_t dscp;
- uint32_t traffic_class;
- enum rte_meter_color color;
-};
-
-struct pipeline_fa_dscp_config_msg_rsp {
- int status;
-};
-
-/*
- * MSG POLICER STATS READ
- */
-struct pipeline_fa_policer_stats_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fa_msg_req_type subtype;
-
- void *entry_ptr;
- uint32_t policer_id;
- int clear;
-};
-
-struct pipeline_fa_policer_stats_msg_rsp {
- int status;
- struct pipeline_fa_policer_stats stats;
-};
-
-extern struct pipeline_be_ops pipeline_flow_actions_be_ops;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
deleted file mode 100644
index d39e0fb1..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
+++ /dev/null
@@ -1,1878 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <netinet/in.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_hexdump.h>
-#include <rte_malloc.h>
-#include <cmdline_rdline.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-
-#include "app.h"
-#include "pipeline_common_fe.h"
-#include "pipeline_flow_classification.h"
-#include "hash_func.h"
-#include "parser.h"
-
-/*
- * Key conversion
- */
-
-struct pkt_key_qinq {
- uint16_t ethertype_svlan;
- uint16_t svlan;
- uint16_t ethertype_cvlan;
- uint16_t cvlan;
-} __attribute__((__packed__));
-
-struct pkt_key_ipv4_5tuple {
- uint8_t ttl;
- uint8_t proto;
- uint16_t checksum;
- uint32_t ip_src;
- uint32_t ip_dst;
- uint16_t port_src;
- uint16_t port_dst;
-} __attribute__((__packed__));
-
-struct pkt_key_ipv6_5tuple {
- uint16_t payload_length;
- uint8_t proto;
- uint8_t hop_limit;
- uint8_t ip_src[16];
- uint8_t ip_dst[16];
- uint16_t port_src;
- uint16_t port_dst;
-} __attribute__((__packed__));
-
-static int
-app_pipeline_fc_key_convert(struct pipeline_fc_key *key_in,
- uint8_t *key_out,
- uint32_t *signature)
-{
- uint8_t buffer[PIPELINE_FC_FLOW_KEY_MAX_SIZE];
- uint8_t m[PIPELINE_FC_FLOW_KEY_MAX_SIZE]; /* key mask */
- void *key_buffer = (key_out) ? key_out : buffer;
-
- memset(m, 0xFF, sizeof(m));
- switch (key_in->type) {
- case FLOW_KEY_QINQ:
- {
- struct pkt_key_qinq *qinq = key_buffer;
-
- qinq->ethertype_svlan = 0;
- qinq->svlan = rte_cpu_to_be_16(key_in->key.qinq.svlan);
- qinq->ethertype_cvlan = 0;
- qinq->cvlan = rte_cpu_to_be_16(key_in->key.qinq.cvlan);
-
- if (signature)
- *signature = (uint32_t) hash_default_key8(qinq, m, 8, 0);
- return 0;
- }
-
- case FLOW_KEY_IPV4_5TUPLE:
- {
- struct pkt_key_ipv4_5tuple *ipv4 = key_buffer;
-
- ipv4->ttl = 0;
- ipv4->proto = key_in->key.ipv4_5tuple.proto;
- ipv4->checksum = 0;
- ipv4->ip_src = rte_cpu_to_be_32(key_in->key.ipv4_5tuple.ip_src);
- ipv4->ip_dst = rte_cpu_to_be_32(key_in->key.ipv4_5tuple.ip_dst);
- ipv4->port_src = rte_cpu_to_be_16(key_in->key.ipv4_5tuple.port_src);
- ipv4->port_dst = rte_cpu_to_be_16(key_in->key.ipv4_5tuple.port_dst);
-
- if (signature)
- *signature = (uint32_t) hash_default_key16(ipv4, m, 16, 0);
- return 0;
- }
-
- case FLOW_KEY_IPV6_5TUPLE:
- {
- struct pkt_key_ipv6_5tuple *ipv6 = key_buffer;
-
- memset(ipv6, 0, 64);
- ipv6->payload_length = 0;
- ipv6->proto = key_in->key.ipv6_5tuple.proto;
- ipv6->hop_limit = 0;
- memcpy(&ipv6->ip_src, &key_in->key.ipv6_5tuple.ip_src, 16);
- memcpy(&ipv6->ip_dst, &key_in->key.ipv6_5tuple.ip_dst, 16);
- ipv6->port_src = rte_cpu_to_be_16(key_in->key.ipv6_5tuple.port_src);
- ipv6->port_dst = rte_cpu_to_be_16(key_in->key.ipv6_5tuple.port_dst);
-
- if (signature)
- *signature = (uint32_t) hash_default_key64(ipv6, m, 64, 0);
- return 0;
- }
-
- default:
- return -1;
- }
-}
-
-/*
- * Flow classification pipeline
- */
-
-struct app_pipeline_fc_flow {
- struct pipeline_fc_key key;
- uint32_t port_id;
- uint32_t flow_id;
- uint32_t signature;
- void *entry_ptr;
-
- TAILQ_ENTRY(app_pipeline_fc_flow) node;
-};
-
-#define N_BUCKETS 65536
-
-struct app_pipeline_fc {
- /* Parameters */
- uint32_t n_ports_in;
- uint32_t n_ports_out;
-
- /* Flows */
- TAILQ_HEAD(, app_pipeline_fc_flow) flows[N_BUCKETS];
- uint32_t n_flows;
-
- /* Default flow */
- uint32_t default_flow_present;
- uint32_t default_flow_port_id;
- void *default_flow_entry_ptr;
-};
-
-static struct app_pipeline_fc_flow *
-app_pipeline_fc_flow_find(struct app_pipeline_fc *p,
- struct pipeline_fc_key *key)
-{
- struct app_pipeline_fc_flow *f;
- uint32_t signature, bucket_id;
-
- app_pipeline_fc_key_convert(key, NULL, &signature);
- bucket_id = signature & (N_BUCKETS - 1);
-
- TAILQ_FOREACH(f, &p->flows[bucket_id], node)
- if ((signature == f->signature) &&
- (memcmp(key,
- &f->key,
- sizeof(struct pipeline_fc_key)) == 0))
- return f;
-
- return NULL;
-}
-
-static void*
-app_pipeline_fc_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct app_pipeline_fc *p;
- uint32_t size, i;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct app_pipeline_fc));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p == NULL)
- return NULL;
-
- /* Initialization */
- p->n_ports_in = params->n_ports_in;
- p->n_ports_out = params->n_ports_out;
-
- for (i = 0; i < N_BUCKETS; i++)
- TAILQ_INIT(&p->flows[i]);
- p->n_flows = 0;
-
- return (void *) p;
-}
-
-static int
-app_pipeline_fc_free(void *pipeline)
-{
- struct app_pipeline_fc *p = pipeline;
- uint32_t i;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- for (i = 0; i < N_BUCKETS; i++)
- while (!TAILQ_EMPTY(&p->flows[i])) {
- struct app_pipeline_fc_flow *flow;
-
- flow = TAILQ_FIRST(&p->flows[i]);
- TAILQ_REMOVE(&p->flows[i], flow, node);
- rte_free(flow);
- }
-
- rte_free(p);
- return 0;
-}
-
-static int
-app_pipeline_fc_key_check(struct pipeline_fc_key *key)
-{
- switch (key->type) {
- case FLOW_KEY_QINQ:
- {
- uint16_t svlan = key->key.qinq.svlan;
- uint16_t cvlan = key->key.qinq.cvlan;
-
- if ((svlan & 0xF000) ||
- (cvlan & 0xF000))
- return -1;
-
- return 0;
- }
-
- case FLOW_KEY_IPV4_5TUPLE:
- return 0;
-
- case FLOW_KEY_IPV6_5TUPLE:
- return 0;
-
- default:
- return -1;
- }
-}
-
-int
-app_pipeline_fc_load_file_qinq(char *filename,
- struct pipeline_fc_key *keys,
- uint32_t *port_ids,
- uint32_t *flow_ids,
- uint32_t *n_keys,
- uint32_t *line)
-{
- FILE *f = NULL;
- char file_buf[1024];
- uint32_t i, l;
-
- /* Check input arguments */
- if ((filename == NULL) ||
- (keys == NULL) ||
- (port_ids == NULL) ||
- (flow_ids == NULL) ||
- (n_keys == NULL) ||
- (*n_keys == 0) ||
- (line == NULL)) {
- if (line)
- *line = 0;
- return -1;
- }
-
- /* Open input file */
- f = fopen(filename, "r");
- if (f == NULL) {
- *line = 0;
- return -1;
- }
-
- /* Read file */
- for (i = 0, l = 1; i < *n_keys; l++) {
- char *tokens[32];
- uint32_t n_tokens = RTE_DIM(tokens);
-
- uint16_t svlan, cvlan;
- uint32_t portid, flowid;
- int status;
-
- if (fgets(file_buf, sizeof(file_buf), f) == NULL)
- break;
-
- status = parse_tokenize_string(file_buf, tokens, &n_tokens);
- if (status)
- goto error1;
-
- if ((n_tokens == 0) || (tokens[0][0] == '#'))
- continue;
-
- if ((n_tokens != 7) ||
- strcmp(tokens[0], "qinq") ||
- parser_read_uint16(&svlan, tokens[1]) ||
- parser_read_uint16(&cvlan, tokens[2]) ||
- strcmp(tokens[3], "port") ||
- parser_read_uint32(&portid, tokens[4]) ||
- strcmp(tokens[5], "id") ||
- parser_read_uint32(&flowid, tokens[6]))
- goto error1;
-
- keys[i].type = FLOW_KEY_QINQ;
- keys[i].key.qinq.svlan = svlan;
- keys[i].key.qinq.cvlan = cvlan;
-
- port_ids[i] = portid;
- flow_ids[i] = flowid;
-
- if (app_pipeline_fc_key_check(&keys[i]))
- goto error1;
-
- i++;
- }
-
- /* Close file */
- *n_keys = i;
- fclose(f);
- return 0;
-
-error1:
- *line = l;
- fclose(f);
- return -1;
-}
-
-int
-app_pipeline_fc_load_file_ipv4(char *filename,
- struct pipeline_fc_key *keys,
- uint32_t *port_ids,
- uint32_t *flow_ids,
- uint32_t *n_keys,
- uint32_t *line)
-{
- FILE *f = NULL;
- char file_buf[1024];
- uint32_t i, l;
-
- /* Check input arguments */
- if ((filename == NULL) ||
- (keys == NULL) ||
- (port_ids == NULL) ||
- (flow_ids == NULL) ||
- (n_keys == NULL) ||
- (*n_keys == 0) ||
- (line == NULL)) {
- if (line)
- *line = 0;
- return -1;
- }
-
- /* Open input file */
- f = fopen(filename, "r");
- if (f == NULL) {
- *line = 0;
- return -1;
- }
-
- /* Read file */
- for (i = 0, l = 1; i < *n_keys; l++) {
- char *tokens[32];
- uint32_t n_tokens = RTE_DIM(tokens);
-
- struct in_addr sipaddr, dipaddr;
- uint16_t sport, dport;
- uint8_t proto;
- uint32_t portid, flowid;
- int status;
-
- if (fgets(file_buf, sizeof(file_buf), f) == NULL)
- break;
-
- status = parse_tokenize_string(file_buf, tokens, &n_tokens);
- if (status)
- goto error2;
-
- if ((n_tokens == 0) || (tokens[0][0] == '#'))
- continue;
-
- if ((n_tokens != 10) ||
- strcmp(tokens[0], "ipv4") ||
- parse_ipv4_addr(tokens[1], &sipaddr) ||
- parse_ipv4_addr(tokens[2], &dipaddr) ||
- parser_read_uint16(&sport, tokens[3]) ||
- parser_read_uint16(&dport, tokens[4]) ||
- parser_read_uint8(&proto, tokens[5]) ||
- strcmp(tokens[6], "port") ||
- parser_read_uint32(&portid, tokens[7]) ||
- strcmp(tokens[8], "id") ||
- parser_read_uint32(&flowid, tokens[9]))
- goto error2;
-
- keys[i].type = FLOW_KEY_IPV4_5TUPLE;
- keys[i].key.ipv4_5tuple.ip_src = rte_be_to_cpu_32(sipaddr.s_addr);
- keys[i].key.ipv4_5tuple.ip_dst = rte_be_to_cpu_32(dipaddr.s_addr);
- keys[i].key.ipv4_5tuple.port_src = sport;
- keys[i].key.ipv4_5tuple.port_dst = dport;
- keys[i].key.ipv4_5tuple.proto = proto;
-
- port_ids[i] = portid;
- flow_ids[i] = flowid;
-
- if (app_pipeline_fc_key_check(&keys[i]))
- goto error2;
-
- i++;
- }
-
- /* Close file */
- *n_keys = i;
- fclose(f);
- return 0;
-
-error2:
- *line = l;
- fclose(f);
- return -1;
-}
-
-int
-app_pipeline_fc_load_file_ipv6(char *filename,
- struct pipeline_fc_key *keys,
- uint32_t *port_ids,
- uint32_t *flow_ids,
- uint32_t *n_keys,
- uint32_t *line)
-{
- FILE *f = NULL;
- char file_buf[1024];
- uint32_t i, l;
-
- /* Check input arguments */
- if ((filename == NULL) ||
- (keys == NULL) ||
- (port_ids == NULL) ||
- (flow_ids == NULL) ||
- (n_keys == NULL) ||
- (*n_keys == 0) ||
- (line == NULL)) {
- if (line)
- *line = 0;
- return -1;
- }
-
- /* Open input file */
- f = fopen(filename, "r");
- if (f == NULL) {
- *line = 0;
- return -1;
- }
-
- /* Read file */
- for (i = 0, l = 1; i < *n_keys; l++) {
- char *tokens[32];
- uint32_t n_tokens = RTE_DIM(tokens);
-
- struct in6_addr sipaddr, dipaddr;
- uint16_t sport, dport;
- uint8_t proto;
- uint32_t portid, flowid;
- int status;
-
- if (fgets(file_buf, sizeof(file_buf), f) == NULL)
- break;
-
- status = parse_tokenize_string(file_buf, tokens, &n_tokens);
- if (status)
- goto error3;
-
- if ((n_tokens == 0) || (tokens[0][0] == '#'))
- continue;
-
- if ((n_tokens != 10) ||
- strcmp(tokens[0], "ipv6") ||
- parse_ipv6_addr(tokens[1], &sipaddr) ||
- parse_ipv6_addr(tokens[2], &dipaddr) ||
- parser_read_uint16(&sport, tokens[3]) ||
- parser_read_uint16(&dport, tokens[4]) ||
- parser_read_uint8(&proto, tokens[5]) ||
- strcmp(tokens[6], "port") ||
- parser_read_uint32(&portid, tokens[7]) ||
- strcmp(tokens[8], "id") ||
- parser_read_uint32(&flowid, tokens[9]))
- goto error3;
-
- keys[i].type = FLOW_KEY_IPV6_5TUPLE;
- memcpy(keys[i].key.ipv6_5tuple.ip_src,
- sipaddr.s6_addr,
- sizeof(sipaddr.s6_addr));
- memcpy(keys[i].key.ipv6_5tuple.ip_dst,
- dipaddr.s6_addr,
- sizeof(dipaddr.s6_addr));
- keys[i].key.ipv6_5tuple.port_src = sport;
- keys[i].key.ipv6_5tuple.port_dst = dport;
- keys[i].key.ipv6_5tuple.proto = proto;
-
- port_ids[i] = portid;
- flow_ids[i] = flowid;
-
- if (app_pipeline_fc_key_check(&keys[i]))
- goto error3;
-
- i++;
- }
-
- /* Close file */
- *n_keys = i;
- fclose(f);
- return 0;
-
-error3:
- *line = l;
- fclose(f);
- return -1;
-}
-
-
-
-int
-app_pipeline_fc_add(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_fc_key *key,
- uint32_t port_id,
- uint32_t flow_id)
-{
- struct app_pipeline_fc *p;
- struct app_pipeline_fc_flow *flow;
-
- struct pipeline_fc_add_msg_req *req;
- struct pipeline_fc_add_msg_rsp *rsp;
-
- uint32_t signature;
- int new_flow;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
- if (p == NULL)
- return -1;
-
- if (port_id >= p->n_ports_out)
- return -1;
-
- if (app_pipeline_fc_key_check(key) != 0)
- return -1;
-
- /* Find existing flow or allocate new flow */
- flow = app_pipeline_fc_flow_find(p, key);
- new_flow = (flow == NULL);
- if (flow == NULL) {
- flow = rte_malloc(NULL, sizeof(*flow), RTE_CACHE_LINE_SIZE);
-
- if (flow == NULL)
- return -1;
- }
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD;
- app_pipeline_fc_key_convert(key, req->key, &signature);
- req->port_id = port_id;
- req->flow_id = flow_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL) {
- if (new_flow)
- rte_free(flow);
- return -1;
- }
-
- /* Read response and write flow */
- if (rsp->status ||
- (rsp->entry_ptr == NULL) ||
- ((new_flow == 0) && (rsp->key_found == 0)) ||
- ((new_flow == 1) && (rsp->key_found == 1))) {
- app_msg_free(app, rsp);
- if (new_flow)
- rte_free(flow);
- return -1;
- }
-
- memset(&flow->key, 0, sizeof(flow->key));
- memcpy(&flow->key, key, sizeof(flow->key));
- flow->port_id = port_id;
- flow->flow_id = flow_id;
- flow->signature = signature;
- flow->entry_ptr = rsp->entry_ptr;
-
- /* Commit rule */
- if (new_flow) {
- uint32_t bucket_id = signature & (N_BUCKETS - 1);
-
- TAILQ_INSERT_TAIL(&p->flows[bucket_id], flow, node);
- p->n_flows++;
- }
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_fc_add_bulk(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_fc_key *key,
- uint32_t *port_id,
- uint32_t *flow_id,
- uint32_t n_keys)
-{
- struct app_pipeline_fc *p;
- struct pipeline_fc_add_bulk_msg_req *req;
- struct pipeline_fc_add_bulk_msg_rsp *rsp;
-
- struct app_pipeline_fc_flow **flow;
- uint32_t *signature;
- int *new_flow;
- struct pipeline_fc_add_bulk_flow_req *flow_req;
- struct pipeline_fc_add_bulk_flow_rsp *flow_rsp;
-
- uint32_t i;
- int status;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL) ||
- (port_id == NULL) ||
- (flow_id == NULL) ||
- (n_keys == 0))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
- if (p == NULL)
- return -1;
-
- for (i = 0; i < n_keys; i++)
- if (port_id[i] >= p->n_ports_out)
- return -1;
-
- for (i = 0; i < n_keys; i++)
- if (app_pipeline_fc_key_check(&key[i]) != 0)
- return -1;
-
- /* Memory allocation */
- flow = rte_malloc(NULL,
- n_keys * sizeof(struct app_pipeline_fc_flow *),
- RTE_CACHE_LINE_SIZE);
- if (flow == NULL)
- return -1;
-
- signature = rte_malloc(NULL,
- n_keys * sizeof(uint32_t),
- RTE_CACHE_LINE_SIZE);
- if (signature == NULL) {
- rte_free(flow);
- return -1;
- }
-
- new_flow = rte_malloc(
- NULL,
- n_keys * sizeof(int),
- RTE_CACHE_LINE_SIZE);
- if (new_flow == NULL) {
- rte_free(signature);
- rte_free(flow);
- return -1;
- }
-
- flow_req = rte_malloc(NULL,
- n_keys * sizeof(struct pipeline_fc_add_bulk_flow_req),
- RTE_CACHE_LINE_SIZE);
- if (flow_req == NULL) {
- rte_free(new_flow);
- rte_free(signature);
- rte_free(flow);
- return -1;
- }
-
- flow_rsp = rte_malloc(NULL,
- n_keys * sizeof(struct pipeline_fc_add_bulk_flow_rsp),
- RTE_CACHE_LINE_SIZE);
- if (flow_rsp == NULL) {
- rte_free(flow_req);
- rte_free(new_flow);
- rte_free(signature);
- rte_free(flow);
- return -1;
- }
-
- /* Find existing flow or allocate new flow */
- for (i = 0; i < n_keys; i++) {
- flow[i] = app_pipeline_fc_flow_find(p, &key[i]);
- new_flow[i] = (flow[i] == NULL);
- if (flow[i] == NULL) {
- flow[i] = rte_zmalloc(NULL,
- sizeof(struct app_pipeline_fc_flow),
- RTE_CACHE_LINE_SIZE);
-
- if (flow[i] == NULL) {
- uint32_t j;
-
- for (j = 0; j < i; j++)
- if (new_flow[j])
- rte_free(flow[j]);
-
- rte_free(flow_rsp);
- rte_free(flow_req);
- rte_free(new_flow);
- rte_free(signature);
- rte_free(flow);
- return -1;
- }
- }
- }
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL) {
- for (i = 0; i < n_keys; i++)
- if (new_flow[i])
- rte_free(flow[i]);
-
- rte_free(flow_rsp);
- rte_free(flow_req);
- rte_free(new_flow);
- rte_free(signature);
- rte_free(flow);
- return -1;
- }
-
- for (i = 0; i < n_keys; i++) {
- app_pipeline_fc_key_convert(&key[i],
- flow_req[i].key,
- &signature[i]);
- flow_req[i].port_id = port_id[i];
- flow_req[i].flow_id = flow_id[i];
- }
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD_BULK;
- req->req = flow_req;
- req->rsp = flow_rsp;
- req->n_keys = n_keys;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, 10000);
- if (rsp == NULL) {
- for (i = 0; i < n_keys; i++)
- if (new_flow[i])
- rte_free(flow[i]);
-
- rte_free(flow_rsp);
- rte_free(flow_req);
- rte_free(new_flow);
- rte_free(signature);
- rte_free(flow);
- return -1;
- }
-
- /* Read response */
- status = 0;
-
- for (i = 0; i < rsp->n_keys; i++)
- if ((flow_rsp[i].entry_ptr == NULL) ||
- ((new_flow[i] == 0) && (flow_rsp[i].key_found == 0)) ||
- ((new_flow[i] == 1) && (flow_rsp[i].key_found == 1)))
- status = -1;
-
- if (rsp->n_keys < n_keys)
- status = -1;
-
- /* Commit flows */
- for (i = 0; i < rsp->n_keys; i++) {
- memcpy(&flow[i]->key, &key[i], sizeof(flow[i]->key));
- flow[i]->port_id = port_id[i];
- flow[i]->flow_id = flow_id[i];
- flow[i]->signature = signature[i];
- flow[i]->entry_ptr = flow_rsp[i].entry_ptr;
-
- if (new_flow[i]) {
- uint32_t bucket_id = signature[i] & (N_BUCKETS - 1);
-
- TAILQ_INSERT_TAIL(&p->flows[bucket_id], flow[i], node);
- p->n_flows++;
- }
- }
-
- /* Free resources */
-
- for (i = rsp->n_keys; i < n_keys; i++)
- if (new_flow[i])
- rte_free(flow[i]);
-
- app_msg_free(app, rsp);
- rte_free(flow_rsp);
- rte_free(flow_req);
- rte_free(new_flow);
- rte_free(signature);
- rte_free(flow);
-
- return status;
-}
-
-int
-app_pipeline_fc_del(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_fc_key *key)
-{
- struct app_pipeline_fc *p;
- struct app_pipeline_fc_flow *flow;
-
- struct pipeline_fc_del_msg_req *req;
- struct pipeline_fc_del_msg_rsp *rsp;
-
- uint32_t signature, bucket_id;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
- if (p == NULL)
- return -1;
-
- if (app_pipeline_fc_key_check(key) != 0)
- return -1;
-
- /* Find rule */
- flow = app_pipeline_fc_flow_find(p, key);
- if (flow == NULL)
- return 0;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FC_MSG_REQ_FLOW_DEL;
- app_pipeline_fc_key_convert(key, req->key, &signature);
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status || !rsp->key_found) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Remove rule */
- bucket_id = signature & (N_BUCKETS - 1);
- TAILQ_REMOVE(&p->flows[bucket_id], flow, node);
- p->n_flows--;
- rte_free(flow);
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_fc_add_default(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id)
-{
- struct app_pipeline_fc *p;
-
- struct pipeline_fc_add_default_msg_req *req;
- struct pipeline_fc_add_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
- if (p == NULL)
- return -1;
-
- if (port_id >= p->n_ports_out)
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FC_MSG_REQ_FLOW_ADD_DEFAULT;
- req->port_id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response and write flow */
- if (rsp->status || (rsp->entry_ptr == NULL)) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- p->default_flow_port_id = port_id;
- p->default_flow_entry_ptr = rsp->entry_ptr;
-
- /* Commit route */
- p->default_flow_present = 1;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_fc_del_default(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_fc *p;
-
- struct pipeline_fc_del_default_msg_req *req;
- struct pipeline_fc_del_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
- if (p == NULL)
- return -EINVAL;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_FC_MSG_REQ_FLOW_DEL_DEFAULT;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Commit route */
- p->default_flow_present = 0;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-/*
- * Flow ls
- */
-
-static void
-print_fc_qinq_flow(struct app_pipeline_fc_flow *flow)
-{
- printf("(SVLAN = %" PRIu32 ", "
- "CVLAN = %" PRIu32 ") => "
- "Port = %" PRIu32 ", "
- "Flow ID = %" PRIu32 ", "
- "(signature = 0x%08" PRIx32 ", "
- "entry_ptr = %p)\n",
-
- flow->key.key.qinq.svlan,
- flow->key.key.qinq.cvlan,
- flow->port_id,
- flow->flow_id,
- flow->signature,
- flow->entry_ptr);
-}
-
-static void
-print_fc_ipv4_5tuple_flow(struct app_pipeline_fc_flow *flow)
-{
- printf("(SA = %" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ", "
- "DA = %" PRIu32 ".%" PRIu32 ".%" PRIu32 ".%" PRIu32 ", "
- "SP = %" PRIu32 ", "
- "DP = %" PRIu32 ", "
- "Proto = %" PRIu32 ") => "
- "Port = %" PRIu32 ", "
- "Flow ID = %" PRIu32 " "
- "(signature = 0x%08" PRIx32 ", "
- "entry_ptr = %p)\n",
-
- (flow->key.key.ipv4_5tuple.ip_src >> 24) & 0xFF,
- (flow->key.key.ipv4_5tuple.ip_src >> 16) & 0xFF,
- (flow->key.key.ipv4_5tuple.ip_src >> 8) & 0xFF,
- flow->key.key.ipv4_5tuple.ip_src & 0xFF,
-
- (flow->key.key.ipv4_5tuple.ip_dst >> 24) & 0xFF,
- (flow->key.key.ipv4_5tuple.ip_dst >> 16) & 0xFF,
- (flow->key.key.ipv4_5tuple.ip_dst >> 8) & 0xFF,
- flow->key.key.ipv4_5tuple.ip_dst & 0xFF,
-
- flow->key.key.ipv4_5tuple.port_src,
- flow->key.key.ipv4_5tuple.port_dst,
-
- flow->key.key.ipv4_5tuple.proto,
-
- flow->port_id,
- flow->flow_id,
- flow->signature,
- flow->entry_ptr);
-}
-
-static void
-print_fc_ipv6_5tuple_flow(struct app_pipeline_fc_flow *flow) {
- printf("(SA = %02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
- ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
- ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
- ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32 ", "
- "DA = %02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
- ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
- ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32
- ":%02" PRIx32 "%02" PRIx32 ":%02" PRIx32 "%02" PRIx32 ", "
- "SP = %" PRIu32 ", "
- "DP = %" PRIu32 " "
- "Proto = %" PRIu32 " "
- "=> Port = %" PRIu32 ", "
- "Flow ID = %" PRIu32 " "
- "(signature = 0x%08" PRIx32 ", "
- "entry_ptr = %p)\n",
-
- flow->key.key.ipv6_5tuple.ip_src[0],
- flow->key.key.ipv6_5tuple.ip_src[1],
- flow->key.key.ipv6_5tuple.ip_src[2],
- flow->key.key.ipv6_5tuple.ip_src[3],
- flow->key.key.ipv6_5tuple.ip_src[4],
- flow->key.key.ipv6_5tuple.ip_src[5],
- flow->key.key.ipv6_5tuple.ip_src[6],
- flow->key.key.ipv6_5tuple.ip_src[7],
- flow->key.key.ipv6_5tuple.ip_src[8],
- flow->key.key.ipv6_5tuple.ip_src[9],
- flow->key.key.ipv6_5tuple.ip_src[10],
- flow->key.key.ipv6_5tuple.ip_src[11],
- flow->key.key.ipv6_5tuple.ip_src[12],
- flow->key.key.ipv6_5tuple.ip_src[13],
- flow->key.key.ipv6_5tuple.ip_src[14],
- flow->key.key.ipv6_5tuple.ip_src[15],
-
- flow->key.key.ipv6_5tuple.ip_dst[0],
- flow->key.key.ipv6_5tuple.ip_dst[1],
- flow->key.key.ipv6_5tuple.ip_dst[2],
- flow->key.key.ipv6_5tuple.ip_dst[3],
- flow->key.key.ipv6_5tuple.ip_dst[4],
- flow->key.key.ipv6_5tuple.ip_dst[5],
- flow->key.key.ipv6_5tuple.ip_dst[6],
- flow->key.key.ipv6_5tuple.ip_dst[7],
- flow->key.key.ipv6_5tuple.ip_dst[8],
- flow->key.key.ipv6_5tuple.ip_dst[9],
- flow->key.key.ipv6_5tuple.ip_dst[10],
- flow->key.key.ipv6_5tuple.ip_dst[11],
- flow->key.key.ipv6_5tuple.ip_dst[12],
- flow->key.key.ipv6_5tuple.ip_dst[13],
- flow->key.key.ipv6_5tuple.ip_dst[14],
- flow->key.key.ipv6_5tuple.ip_dst[15],
-
- flow->key.key.ipv6_5tuple.port_src,
- flow->key.key.ipv6_5tuple.port_dst,
-
- flow->key.key.ipv6_5tuple.proto,
-
- flow->port_id,
- flow->flow_id,
- flow->signature,
- flow->entry_ptr);
-}
-
-static void
-print_fc_flow(struct app_pipeline_fc_flow *flow)
-{
- switch (flow->key.type) {
- case FLOW_KEY_QINQ:
- print_fc_qinq_flow(flow);
- break;
-
- case FLOW_KEY_IPV4_5TUPLE:
- print_fc_ipv4_5tuple_flow(flow);
- break;
-
- case FLOW_KEY_IPV6_5TUPLE:
- print_fc_ipv6_5tuple_flow(flow);
- break;
- }
-}
-
-static int
-app_pipeline_fc_ls(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_fc *p;
- struct app_pipeline_fc_flow *flow;
- uint32_t i;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_flow_classification);
- if (p == NULL)
- return -1;
-
- for (i = 0; i < N_BUCKETS; i++)
- TAILQ_FOREACH(flow, &p->flows[i], node)
- print_fc_flow(flow);
-
- if (p->default_flow_present)
- printf("Default flow: port %" PRIu32 " (entry ptr = %p)\n",
- p->default_flow_port_id,
- p->default_flow_entry_ptr);
- else
- printf("Default: DROP\n");
-
- return 0;
-}
-/*
- * flow
- *
- * flow add:
- * p <pipelineid> flow add qinq <svlan> <cvlan> port <portid> id <flowid>
- * p <pipelineid> flow add qinq bulk <file>
- * p <pipelineid> flow add ipv4 <sipaddr> <dipaddr> <sport> <dport> <proto> port <port ID> id <flowid>
- * p <pipelineid> flow add ipv4 bulk <file>
- * p <pipelineid> flow add ipv6 <sipaddr> <dipaddr> <sport> <dport> <proto> port <port ID> id <flowid>
- * p <pipelineid> flow add ipv6 bulk <file>
- *
- * flow add default:
- * p <pipelineid> flow add default <portid>
- *
- * flow del:
- * p <pipelineid> flow del qinq <svlan> <cvlan>
- * p <pipelineid> flow del ipv4 <sipaddr> <dipaddr> <sport> <dport> <proto>
- * p <pipelineid> flow del ipv6 <sipaddr> <dipaddr> <sport> <dport> <proto>
- *
- * flow del default:
- * p <pipelineid> flow del default
- *
- * flow ls:
- * p <pipelineid> flow ls
- */
-
-struct cmd_flow_result {
- cmdline_fixed_string_t p_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t flow_string;
- cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_flow_parsed(void *parsed_result,
- __attribute__((unused)) struct cmdline *cl,
- void *data)
-{
- struct cmd_flow_result *results = parsed_result;
- struct app_params *app = data;
-
- char *tokens[16];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- status = parse_tokenize_string(results->multi_string, tokens, &n_tokens);
- if (status) {
- printf(CMD_MSG_TOO_MANY_ARGS, "flow");
- return;
- }
-
- /* flow add qinq */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "qinq") == 0) &&
- strcmp(tokens[2], "bulk")) {
- struct pipeline_fc_key key;
- uint32_t svlan;
- uint32_t cvlan;
- uint32_t port_id;
- uint32_t flow_id;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 8) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow add qinq");
- return;
- }
-
- if (parser_read_uint32(&svlan, tokens[2]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "svlan");
- return;
- }
-
- if (parser_read_uint32(&cvlan, tokens[3]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "cvlan");
- return;
- }
-
- if (strcmp(tokens[4], "port") != 0) {
- printf(CMD_MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[5]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- if (strcmp(tokens[6], "id") != 0) {
- printf(CMD_MSG_ARG_NOT_FOUND, "id");
- return;
- }
-
- if (parser_read_uint32(&flow_id, tokens[7]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "flowid");
- return;
- }
-
- key.type = FLOW_KEY_QINQ;
- key.key.qinq.svlan = svlan;
- key.key.qinq.cvlan = cvlan;
-
- status = app_pipeline_fc_add(app,
- results->pipeline_id,
- &key,
- port_id,
- flow_id);
- if (status)
- printf(CMD_MSG_FAIL, "flow add qinq");
-
- return;
- } /* flow add qinq */
-
- /* flow add ipv4 */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "ipv4") == 0) &&
- strcmp(tokens[2], "bulk")) {
- struct pipeline_fc_key key;
- struct in_addr sipaddr;
- struct in_addr dipaddr;
- uint32_t sport;
- uint32_t dport;
- uint32_t proto;
- uint32_t port_id;
- uint32_t flow_id;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 11) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow add ipv4");
- return;
- }
-
- if (parse_ipv4_addr(tokens[2], &sipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sipv4addr");
- return;
- }
- if (parse_ipv4_addr(tokens[3], &dipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dipv4addr");
- return;
- }
-
- if (parser_read_uint32(&sport, tokens[4]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sport");
- return;
- }
-
- if (parser_read_uint32(&dport, tokens[5]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dport");
- return;
- }
-
- if (parser_read_uint32(&proto, tokens[6]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "proto");
- return;
- }
-
- if (strcmp(tokens[7], "port") != 0) {
- printf(CMD_MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[8]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- if (strcmp(tokens[9], "id") != 0) {
- printf(CMD_MSG_ARG_NOT_FOUND, "id");
- return;
- }
-
- if (parser_read_uint32(&flow_id, tokens[10]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "flowid");
- return;
- }
-
- key.type = FLOW_KEY_IPV4_5TUPLE;
- key.key.ipv4_5tuple.ip_src = rte_be_to_cpu_32(sipaddr.s_addr);
- key.key.ipv4_5tuple.ip_dst = rte_be_to_cpu_32(dipaddr.s_addr);
- key.key.ipv4_5tuple.port_src = sport;
- key.key.ipv4_5tuple.port_dst = dport;
- key.key.ipv4_5tuple.proto = proto;
-
- status = app_pipeline_fc_add(app,
- results->pipeline_id,
- &key,
- port_id,
- flow_id);
- if (status)
- printf(CMD_MSG_FAIL, "flow add ipv4");
-
- return;
- } /* flow add ipv4 */
-
- /* flow add ipv6 */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "ipv6") == 0) &&
- strcmp(tokens[2], "bulk")) {
- struct pipeline_fc_key key;
- struct in6_addr sipaddr;
- struct in6_addr dipaddr;
- uint32_t sport;
- uint32_t dport;
- uint32_t proto;
- uint32_t port_id;
- uint32_t flow_id;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 11) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow add ipv6");
- return;
- }
-
- if (parse_ipv6_addr(tokens[2], &sipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sipv6addr");
- return;
- }
- if (parse_ipv6_addr(tokens[3], &dipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dipv6addr");
- return;
- }
-
- if (parser_read_uint32(&sport, tokens[4]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sport");
- return;
- }
-
- if (parser_read_uint32(&dport, tokens[5]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dport");
- return;
- }
-
- if (parser_read_uint32(&proto, tokens[6]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "proto");
- return;
- }
-
- if (strcmp(tokens[7], "port") != 0) {
- printf(CMD_MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[8]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- if (strcmp(tokens[9], "id") != 0) {
- printf(CMD_MSG_ARG_NOT_FOUND, "id");
- return;
- }
-
- if (parser_read_uint32(&flow_id, tokens[10]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "flowid");
- return;
- }
-
- key.type = FLOW_KEY_IPV6_5TUPLE;
- memcpy(key.key.ipv6_5tuple.ip_src, (void *)&sipaddr, 16);
- memcpy(key.key.ipv6_5tuple.ip_dst, (void *)&dipaddr, 16);
- key.key.ipv6_5tuple.port_src = sport;
- key.key.ipv6_5tuple.port_dst = dport;
- key.key.ipv6_5tuple.proto = proto;
-
- status = app_pipeline_fc_add(app,
- results->pipeline_id,
- &key,
- port_id,
- flow_id);
- if (status)
- printf(CMD_MSG_FAIL, "flow add ipv6");
-
- return;
- } /* flow add ipv6 */
-
- /* flow add qinq bulk */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "qinq") == 0) &&
- (strcmp(tokens[2], "bulk") == 0)) {
- struct pipeline_fc_key *keys;
- uint32_t *port_ids, *flow_ids, n_keys, line;
- char *filename;
-
- if (n_tokens != 4) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow add qinq bulk");
- return;
- }
-
- filename = tokens[3];
-
- n_keys = APP_PIPELINE_FC_MAX_FLOWS_IN_FILE;
- keys = malloc(n_keys * sizeof(struct pipeline_fc_key));
- if (keys == NULL)
- return;
- memset(keys, 0, n_keys * sizeof(struct pipeline_fc_key));
-
- port_ids = malloc(n_keys * sizeof(uint32_t));
- if (port_ids == NULL) {
- free(keys);
- return;
- }
-
- flow_ids = malloc(n_keys * sizeof(uint32_t));
- if (flow_ids == NULL) {
- free(port_ids);
- free(keys);
- return;
- }
-
- status = app_pipeline_fc_load_file_qinq(filename,
- keys,
- port_ids,
- flow_ids,
- &n_keys,
- &line);
- if (status != 0) {
- printf(CMD_MSG_FILE_ERR, filename, line);
- free(flow_ids);
- free(port_ids);
- free(keys);
- return;
- }
-
- status = app_pipeline_fc_add_bulk(app,
- results->pipeline_id,
- keys,
- port_ids,
- flow_ids,
- n_keys);
- if (status)
- printf(CMD_MSG_FAIL, "flow add qinq bulk");
-
- free(flow_ids);
- free(port_ids);
- free(keys);
- return;
- } /* flow add qinq bulk */
-
- /* flow add ipv4 bulk */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "ipv4") == 0) &&
- (strcmp(tokens[2], "bulk") == 0)) {
- struct pipeline_fc_key *keys;
- uint32_t *port_ids, *flow_ids, n_keys, line;
- char *filename;
-
- if (n_tokens != 4) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow add ipv4 bulk");
- return;
- }
-
- filename = tokens[3];
-
- n_keys = APP_PIPELINE_FC_MAX_FLOWS_IN_FILE;
- keys = malloc(n_keys * sizeof(struct pipeline_fc_key));
- if (keys == NULL)
- return;
- memset(keys, 0, n_keys * sizeof(struct pipeline_fc_key));
-
- port_ids = malloc(n_keys * sizeof(uint32_t));
- if (port_ids == NULL) {
- free(keys);
- return;
- }
-
- flow_ids = malloc(n_keys * sizeof(uint32_t));
- if (flow_ids == NULL) {
- free(port_ids);
- free(keys);
- return;
- }
-
- status = app_pipeline_fc_load_file_ipv4(filename,
- keys,
- port_ids,
- flow_ids,
- &n_keys,
- &line);
- if (status != 0) {
- printf(CMD_MSG_FILE_ERR, filename, line);
- free(flow_ids);
- free(port_ids);
- free(keys);
- return;
- }
-
- status = app_pipeline_fc_add_bulk(app,
- results->pipeline_id,
- keys,
- port_ids,
- flow_ids,
- n_keys);
- if (status)
- printf(CMD_MSG_FAIL, "flow add ipv4 bulk");
-
- free(flow_ids);
- free(port_ids);
- free(keys);
- return;
- } /* flow add ipv4 bulk */
-
- /* flow add ipv6 bulk */
- if ((n_tokens >= 3) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "ipv6") == 0) &&
- (strcmp(tokens[2], "bulk") == 0)) {
- struct pipeline_fc_key *keys;
- uint32_t *port_ids, *flow_ids, n_keys, line;
- char *filename;
-
- if (n_tokens != 4) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow add ipv6 bulk");
- return;
- }
-
- filename = tokens[3];
-
- n_keys = APP_PIPELINE_FC_MAX_FLOWS_IN_FILE;
- keys = malloc(n_keys * sizeof(struct pipeline_fc_key));
- if (keys == NULL)
- return;
- memset(keys, 0, n_keys * sizeof(struct pipeline_fc_key));
-
- port_ids = malloc(n_keys * sizeof(uint32_t));
- if (port_ids == NULL) {
- free(keys);
- return;
- }
-
- flow_ids = malloc(n_keys * sizeof(uint32_t));
- if (flow_ids == NULL) {
- free(port_ids);
- free(keys);
- return;
- }
-
- status = app_pipeline_fc_load_file_ipv6(filename,
- keys,
- port_ids,
- flow_ids,
- &n_keys,
- &line);
- if (status != 0) {
- printf(CMD_MSG_FILE_ERR, filename, line);
- free(flow_ids);
- free(port_ids);
- free(keys);
- return;
- }
-
- status = app_pipeline_fc_add_bulk(app,
- results->pipeline_id,
- keys,
- port_ids,
- flow_ids,
- n_keys);
- if (status)
- printf(CMD_MSG_FAIL, "flow add ipv6 bulk");
-
- free(flow_ids);
- free(port_ids);
- free(keys);
- return;
- } /* flow add ipv6 bulk */
-
- /* flow add default*/
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- uint32_t port_id;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow add default");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[2]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- status = app_pipeline_fc_add_default(app,
- results->pipeline_id,
- port_id);
- if (status)
- printf(CMD_MSG_FAIL, "flow add default");
-
- return;
- } /* flow add default */
-
- /* flow del qinq */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "qinq") == 0)) {
- struct pipeline_fc_key key;
- uint32_t svlan;
- uint32_t cvlan;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 4) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow del qinq");
- return;
- }
-
- if (parser_read_uint32(&svlan, tokens[2]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "svlan");
- return;
- }
-
- if (parser_read_uint32(&cvlan, tokens[3]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "cvlan");
- return;
- }
-
- key.type = FLOW_KEY_QINQ;
- key.key.qinq.svlan = svlan;
- key.key.qinq.cvlan = cvlan;
-
- status = app_pipeline_fc_del(app,
- results->pipeline_id,
- &key);
- if (status)
- printf(CMD_MSG_FAIL, "flow del qinq");
-
- return;
- } /* flow del qinq */
-
- /* flow del ipv4 */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "ipv4") == 0)) {
- struct pipeline_fc_key key;
- struct in_addr sipaddr;
- struct in_addr dipaddr;
- uint32_t sport;
- uint32_t dport;
- uint32_t proto;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 7) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow del ipv4");
- return;
- }
-
- if (parse_ipv4_addr(tokens[2], &sipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sipv4addr");
- return;
- }
- if (parse_ipv4_addr(tokens[3], &dipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dipv4addr");
- return;
- }
-
- if (parser_read_uint32(&sport, tokens[4]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sport");
- return;
- }
-
- if (parser_read_uint32(&dport, tokens[5]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dport");
- return;
- }
-
- if (parser_read_uint32(&proto, tokens[6]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "proto");
- return;
- }
-
- key.type = FLOW_KEY_IPV4_5TUPLE;
- key.key.ipv4_5tuple.ip_src = rte_be_to_cpu_32(sipaddr.s_addr);
- key.key.ipv4_5tuple.ip_dst = rte_be_to_cpu_32(dipaddr.s_addr);
- key.key.ipv4_5tuple.port_src = sport;
- key.key.ipv4_5tuple.port_dst = dport;
- key.key.ipv4_5tuple.proto = proto;
-
- status = app_pipeline_fc_del(app,
- results->pipeline_id,
- &key);
- if (status)
- printf(CMD_MSG_FAIL, "flow del ipv4");
-
- return;
- } /* flow del ipv4 */
-
- /* flow del ipv6 */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "ipv6") == 0)) {
- struct pipeline_fc_key key;
- struct in6_addr sipaddr;
- struct in6_addr dipaddr;
- uint32_t sport;
- uint32_t dport;
- uint32_t proto;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 7) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow del ipv6");
- return;
- }
-
- if (parse_ipv6_addr(tokens[2], &sipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sipv6addr");
- return;
- }
-
- if (parse_ipv6_addr(tokens[3], &dipaddr) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dipv6addr");
- return;
- }
-
- if (parser_read_uint32(&sport, tokens[4]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "sport");
- return;
- }
-
- if (parser_read_uint32(&dport, tokens[5]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "dport");
- return;
- }
-
- if (parser_read_uint32(&proto, tokens[6]) != 0) {
- printf(CMD_MSG_INVALID_ARG, "proto");
- return;
- }
-
- key.type = FLOW_KEY_IPV6_5TUPLE;
- memcpy(key.key.ipv6_5tuple.ip_src, &sipaddr, 16);
- memcpy(key.key.ipv6_5tuple.ip_dst, &dipaddr, 16);
- key.key.ipv6_5tuple.port_src = sport;
- key.key.ipv6_5tuple.port_dst = dport;
- key.key.ipv6_5tuple.proto = proto;
-
- status = app_pipeline_fc_del(app,
- results->pipeline_id,
- &key);
- if (status)
- printf(CMD_MSG_FAIL, "flow del ipv6");
-
- return;
- } /* flow del ipv6 */
-
- /* flow del default*/
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow del default");
- return;
- }
-
- status = app_pipeline_fc_del_default(app,
- results->pipeline_id);
- if (status)
- printf(CMD_MSG_FAIL, "flow del default");
-
- return;
- } /* flow del default */
-
- /* flow ls */
- if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
- if (n_tokens != 1) {
- printf(CMD_MSG_MISMATCH_ARGS, "flow ls");
- return;
- }
-
- status = app_pipeline_fc_ls(app, results->pipeline_id);
- if (status)
- printf(CMD_MSG_FAIL, "flow ls");
-
- return;
- } /* flow ls */
-
- printf(CMD_MSG_MISMATCH_ARGS, "flow");
-}
-
-static cmdline_parse_token_string_t cmd_flow_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_flow_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_flow_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_flow_result, pipeline_id, UINT32);
-
-static cmdline_parse_token_string_t cmd_flow_flow_string =
- TOKEN_STRING_INITIALIZER(struct cmd_flow_result, flow_string, "flow");
-
-static cmdline_parse_token_string_t cmd_flow_multi_string =
- TOKEN_STRING_INITIALIZER(struct cmd_flow_result, multi_string,
- TOKEN_STRING_MULTI);
-
-static cmdline_parse_inst_t cmd_flow = {
- .f = cmd_flow_parsed,
- .data = NULL,
- .help_str = "flow add / add bulk / add default / del / del default / ls",
- .tokens = {
- (void *) &cmd_flow_p_string,
- (void *) &cmd_flow_pipeline_id,
- (void *) &cmd_flow_flow_string,
- (void *) &cmd_flow_multi_string,
- NULL,
- },
-};
-
-static cmdline_parse_ctx_t pipeline_cmds[] = {
- (cmdline_parse_inst_t *) &cmd_flow,
- NULL,
-};
-
-static struct pipeline_fe_ops pipeline_flow_classification_fe_ops = {
- .f_init = app_pipeline_fc_init,
- .f_post_init = NULL,
- .f_free = app_pipeline_fc_free,
- .f_track = app_pipeline_track_default,
- .cmds = pipeline_cmds,
-};
-
-struct pipeline_type pipeline_flow_classification = {
- .name = "FLOW_CLASSIFICATION",
- .be_ops = &pipeline_flow_classification_be_ops,
- .fe_ops = &pipeline_flow_classification_fe_ops,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.h b/examples/ip_pipeline/pipeline/pipeline_flow_classification.h
deleted file mode 100644
index 8c354989..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_H__
-#define __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_H__
-
-#include "pipeline.h"
-#include "pipeline_flow_classification_be.h"
-
-enum flow_key_type {
- FLOW_KEY_QINQ,
- FLOW_KEY_IPV4_5TUPLE,
- FLOW_KEY_IPV6_5TUPLE,
-};
-
-struct flow_key_qinq {
- uint16_t svlan;
- uint16_t cvlan;
-};
-
-struct flow_key_ipv4_5tuple {
- uint32_t ip_src;
- uint32_t ip_dst;
- uint16_t port_src;
- uint16_t port_dst;
- uint32_t proto;
-};
-
-struct flow_key_ipv6_5tuple {
- uint8_t ip_src[16];
- uint8_t ip_dst[16];
- uint16_t port_src;
- uint16_t port_dst;
- uint32_t proto;
-};
-
-struct pipeline_fc_key {
- enum flow_key_type type;
- union {
- struct flow_key_qinq qinq;
- struct flow_key_ipv4_5tuple ipv4_5tuple;
- struct flow_key_ipv6_5tuple ipv6_5tuple;
- } key;
-};
-
-int
-app_pipeline_fc_add(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_fc_key *key,
- uint32_t port_id,
- uint32_t flow_id);
-
-int
-app_pipeline_fc_add_bulk(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_fc_key *key,
- uint32_t *port_id,
- uint32_t *flow_id,
- uint32_t n_keys);
-
-int
-app_pipeline_fc_del(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_fc_key *key);
-
-int
-app_pipeline_fc_add_default(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id);
-
-int
-app_pipeline_fc_del_default(struct app_params *app,
- uint32_t pipeline_id);
-
-#ifndef APP_PIPELINE_FC_MAX_FLOWS_IN_FILE
-#define APP_PIPELINE_FC_MAX_FLOWS_IN_FILE (16 * 1024 * 1024)
-#endif
-
-int
-app_pipeline_fc_load_file_qinq(char *filename,
- struct pipeline_fc_key *keys,
- uint32_t *port_ids,
- uint32_t *flow_ids,
- uint32_t *n_keys,
- uint32_t *line);
-
-int
-app_pipeline_fc_load_file_ipv4(char *filename,
- struct pipeline_fc_key *keys,
- uint32_t *port_ids,
- uint32_t *flow_ids,
- uint32_t *n_keys,
- uint32_t *line);
-
-int
-app_pipeline_fc_load_file_ipv6(char *filename,
- struct pipeline_fc_key *keys,
- uint32_t *port_ids,
- uint32_t *flow_ids,
- uint32_t *n_keys,
- uint32_t *line);
-
-extern struct pipeline_type pipeline_flow_classification;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
deleted file mode 100644
index 097ec346..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.c
+++ /dev/null
@@ -1,723 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_table_hash.h>
-#include <rte_byteorder.h>
-#include <pipeline.h>
-
-#include "pipeline_flow_classification_be.h"
-#include "pipeline_actions_common.h"
-#include "parser.h"
-#include "hash_func.h"
-
-struct pipeline_flow_classification {
- struct pipeline p;
- pipeline_msg_req_handler custom_handlers[PIPELINE_FC_MSG_REQS];
-
- uint32_t n_flows;
- uint32_t key_size;
- uint32_t flow_id;
-
- uint32_t key_offset;
- uint32_t hash_offset;
- uint8_t key_mask[PIPELINE_FC_FLOW_KEY_MAX_SIZE];
- uint32_t key_mask_present;
- uint32_t flow_id_offset;
-
-} __rte_cache_aligned;
-
-static void *
-pipeline_fc_msg_req_custom_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler handlers[] = {
- [PIPELINE_MSG_REQ_PING] =
- pipeline_msg_req_ping_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_IN] =
- pipeline_msg_req_stats_port_in_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
- pipeline_msg_req_stats_port_out_handler,
- [PIPELINE_MSG_REQ_STATS_TABLE] =
- pipeline_msg_req_stats_table_handler,
- [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
- pipeline_msg_req_port_in_enable_handler,
- [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
- pipeline_msg_req_port_in_disable_handler,
- [PIPELINE_MSG_REQ_CUSTOM] =
- pipeline_fc_msg_req_custom_handler,
-};
-
-static void *
-pipeline_fc_msg_req_add_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_fc_msg_req_add_bulk_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_fc_msg_req_del_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_fc_msg_req_add_default_handler(struct pipeline *p, void *msg);
-
-static void *
-pipeline_fc_msg_req_del_default_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler custom_handlers[] = {
- [PIPELINE_FC_MSG_REQ_FLOW_ADD] =
- pipeline_fc_msg_req_add_handler,
- [PIPELINE_FC_MSG_REQ_FLOW_ADD_BULK] =
- pipeline_fc_msg_req_add_bulk_handler,
- [PIPELINE_FC_MSG_REQ_FLOW_DEL] =
- pipeline_fc_msg_req_del_handler,
- [PIPELINE_FC_MSG_REQ_FLOW_ADD_DEFAULT] =
- pipeline_fc_msg_req_add_default_handler,
- [PIPELINE_FC_MSG_REQ_FLOW_DEL_DEFAULT] =
- pipeline_fc_msg_req_del_default_handler,
-};
-
-/*
- * Flow table
- */
-struct flow_table_entry {
- struct rte_pipeline_table_entry head;
-
- uint32_t flow_id;
- uint32_t pad;
-};
-
-rte_table_hash_op_hash hash_func[] = {
- hash_default_key8,
- hash_default_key16,
- hash_default_key24,
- hash_default_key32,
- hash_default_key40,
- hash_default_key48,
- hash_default_key56,
- hash_default_key64
-};
-
-/*
- * Flow table AH - Write flow_id to packet meta-data
- */
-static inline void
-pkt_work_flow_id(
- struct rte_mbuf *pkt,
- struct rte_pipeline_table_entry *table_entry,
- void *arg)
-{
- struct pipeline_flow_classification *p_fc = arg;
- uint32_t *flow_id_ptr =
- RTE_MBUF_METADATA_UINT32_PTR(pkt, p_fc->flow_id_offset);
- struct flow_table_entry *entry =
- (struct flow_table_entry *) table_entry;
-
- /* Read */
- uint32_t flow_id = entry->flow_id;
-
- /* Compute */
-
- /* Write */
- *flow_id_ptr = flow_id;
-}
-
-static inline void
-pkt4_work_flow_id(
- struct rte_mbuf **pkts,
- struct rte_pipeline_table_entry **table_entries,
- void *arg)
-{
- struct pipeline_flow_classification *p_fc = arg;
-
- uint32_t *flow_id_ptr0 =
- RTE_MBUF_METADATA_UINT32_PTR(pkts[0], p_fc->flow_id_offset);
- uint32_t *flow_id_ptr1 =
- RTE_MBUF_METADATA_UINT32_PTR(pkts[1], p_fc->flow_id_offset);
- uint32_t *flow_id_ptr2 =
- RTE_MBUF_METADATA_UINT32_PTR(pkts[2], p_fc->flow_id_offset);
- uint32_t *flow_id_ptr3 =
- RTE_MBUF_METADATA_UINT32_PTR(pkts[3], p_fc->flow_id_offset);
-
- struct flow_table_entry *entry0 =
- (struct flow_table_entry *) table_entries[0];
- struct flow_table_entry *entry1 =
- (struct flow_table_entry *) table_entries[1];
- struct flow_table_entry *entry2 =
- (struct flow_table_entry *) table_entries[2];
- struct flow_table_entry *entry3 =
- (struct flow_table_entry *) table_entries[3];
-
- /* Read */
- uint32_t flow_id0 = entry0->flow_id;
- uint32_t flow_id1 = entry1->flow_id;
- uint32_t flow_id2 = entry2->flow_id;
- uint32_t flow_id3 = entry3->flow_id;
-
- /* Compute */
-
- /* Write */
- *flow_id_ptr0 = flow_id0;
- *flow_id_ptr1 = flow_id1;
- *flow_id_ptr2 = flow_id2;
- *flow_id_ptr3 = flow_id3;
-}
-
-PIPELINE_TABLE_AH_HIT(fc_table_ah_hit,
- pkt_work_flow_id, pkt4_work_flow_id);
-
-static rte_pipeline_table_action_handler_hit
-get_fc_table_ah_hit(struct pipeline_flow_classification *p)
-{
- if (p->flow_id)
- return fc_table_ah_hit;
-
- return NULL;
-}
-
-/*
- * Argument parsing
- */
-static int
-pipeline_fc_parse_args(struct pipeline_flow_classification *p,
- struct pipeline_params *params)
-{
- uint32_t n_flows_present = 0;
- uint32_t key_offset_present = 0;
- uint32_t key_size_present = 0;
- uint32_t hash_offset_present = 0;
- uint32_t key_mask_present = 0;
- uint32_t flow_id_offset_present = 0;
-
- uint32_t i;
- char key_mask_str[PIPELINE_FC_FLOW_KEY_MAX_SIZE * 2 + 1];
-
- p->hash_offset = 0;
-
- /* default values */
- p->flow_id = 0;
-
- for (i = 0; i < params->n_args; i++) {
- char *arg_name = params->args_name[i];
- char *arg_value = params->args_value[i];
-
- /* n_flows */
- if (strcmp(arg_name, "n_flows") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- n_flows_present == 0, params->name,
- arg_name);
- n_flows_present = 1;
-
- status = parser_read_uint32(&p->n_flows,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
- (p->n_flows != 0)), params->name,
- arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* key_offset */
- if (strcmp(arg_name, "key_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- key_offset_present == 0, params->name,
- arg_name);
- key_offset_present = 1;
-
- status = parser_read_uint32(&p->key_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* key_size */
- if (strcmp(arg_name, "key_size") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- key_size_present == 0, params->name,
- arg_name);
- key_size_present = 1;
-
- status = parser_read_uint32(&p->key_size,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
- (p->key_size != 0) &&
- (p->key_size % 8 == 0)),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
- (p->key_size <=
- PIPELINE_FC_FLOW_KEY_MAX_SIZE)),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* key_mask */
- if (strcmp(arg_name, "key_mask") == 0) {
- int mask_str_len = strlen(arg_value);
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- key_mask_present == 0,
- params->name, arg_name);
- key_mask_present = 1;
-
- PIPELINE_ARG_CHECK((mask_str_len <=
- (PIPELINE_FC_FLOW_KEY_MAX_SIZE * 2)),
- "Parse error in section \"%s\": entry "
- "\"%s\" is too long", params->name,
- arg_name);
-
- snprintf(key_mask_str, mask_str_len + 1, "%s",
- arg_value);
-
- continue;
- }
-
- /* hash_offset */
- if (strcmp(arg_name, "hash_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- hash_offset_present == 0, params->name,
- arg_name);
- hash_offset_present = 1;
-
- status = parser_read_uint32(&p->hash_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* flow_id_offset */
- if (strcmp(arg_name, "flowid_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- flow_id_offset_present == 0, params->name,
- arg_name);
- flow_id_offset_present = 1;
-
- status = parser_read_uint32(&p->flow_id_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->flow_id = 1;
-
- continue;
- }
-
- /* Unknown argument */
- PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
- }
-
- /* Check that mandatory arguments are present */
- PIPELINE_PARSE_ERR_MANDATORY((n_flows_present), params->name,
- "n_flows");
- PIPELINE_PARSE_ERR_MANDATORY((key_offset_present), params->name,
- "key_offset");
- PIPELINE_PARSE_ERR_MANDATORY((key_size_present), params->name,
- "key_size");
-
- if (key_mask_present) {
- uint32_t key_size = p->key_size;
- int status;
-
- PIPELINE_ARG_CHECK(((key_size == 8) || (key_size == 16)),
- "Parse error in section \"%s\": entry key_mask "
- "only allowed for key_size of 8 or 16 bytes",
- params->name);
-
- PIPELINE_ARG_CHECK((strlen(key_mask_str) ==
- (key_size * 2)), "Parse error in section "
- "\"%s\": key_mask should have exactly %u hex "
- "digits", params->name, (key_size * 2));
-
- PIPELINE_ARG_CHECK((hash_offset_present == 0), "Parse "
- "error in section \"%s\": entry hash_offset only "
- "allowed when key_mask is not present",
- params->name);
-
- status = parse_hex_string(key_mask_str, p->key_mask,
- &p->key_size);
-
- PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
- (key_size == p->key_size)), params->name,
- "key_mask", key_mask_str);
- }
-
- p->key_mask_present = key_mask_present;
-
- return 0;
-}
-
-static void *pipeline_fc_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct pipeline *p;
- struct pipeline_flow_classification *p_fc;
- uint32_t size, i;
-
- /* Check input arguments */
- if (params == NULL)
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(
- sizeof(struct pipeline_flow_classification));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p == NULL)
- return NULL;
- p_fc = (struct pipeline_flow_classification *) p;
-
- strcpy(p->name, params->name);
- p->log_level = params->log_level;
-
- PLOG(p, HIGH, "Flow classification");
-
- /* Parse arguments */
- if (pipeline_fc_parse_args(p_fc, params))
- return NULL;
-
- /* Pipeline */
- {
- struct rte_pipeline_params pipeline_params = {
- .name = params->name,
- .socket_id = params->socket_id,
- .offset_port_id = 0,
- };
-
- p->p = rte_pipeline_create(&pipeline_params);
- if (p->p == NULL) {
- rte_free(p);
- return NULL;
- }
- }
-
- /* Input ports */
- p->n_ports_in = params->n_ports_in;
- for (i = 0; i < p->n_ports_in; i++) {
- struct rte_pipeline_port_in_params port_params = {
- .ops = pipeline_port_in_params_get_ops(
- &params->port_in[i]),
- .arg_create = pipeline_port_in_params_convert(
- &params->port_in[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = params->port_in[i].burst_size,
- };
-
- int status = rte_pipeline_port_in_create(p->p,
- &port_params,
- &p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Output ports */
- p->n_ports_out = params->n_ports_out;
- for (i = 0; i < p->n_ports_out; i++) {
- struct rte_pipeline_port_out_params port_params = {
- .ops = pipeline_port_out_params_get_ops(
- &params->port_out[i]),
- .arg_create = pipeline_port_out_params_convert(
- &params->port_out[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- int status = rte_pipeline_port_out_create(p->p,
- &port_params,
- &p->port_out_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Tables */
- p->n_tables = 1;
- {
- struct rte_table_hash_params table_hash_params = {
- .name = p->name,
- .key_size = p_fc->key_size,
- .key_offset = p_fc->key_offset,
- .key_mask = (p_fc->key_mask_present) ?
- p_fc->key_mask : NULL,
- .n_keys = p_fc->n_flows,
- .n_buckets = rte_align32pow2(p_fc->n_flows / 4),
- .f_hash = hash_func[(p_fc->key_size / 8) - 1],
- .seed = 0,
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = NULL, /* set below */
- .arg_create = NULL, /* set below */
- .f_action_hit = get_fc_table_ah_hit(p_fc),
- .f_action_miss = NULL,
- .arg_ah = p_fc,
- .action_data_size = sizeof(struct flow_table_entry) -
- sizeof(struct rte_pipeline_table_entry),
- };
-
- int status;
-
- switch (p_fc->key_size) {
- case 8:
- table_params.ops = &rte_table_hash_key8_ext_ops;
- break;
-
- case 16:
- table_params.ops = &rte_table_hash_key16_ext_ops;
- break;
-
- default:
- table_params.ops = &rte_table_hash_ext_ops;
- }
-
- table_params.arg_create = &table_hash_params;
-
- status = rte_pipeline_table_create(p->p,
- &table_params,
- &p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Connecting input ports to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_connect_to_table(p->p,
- p->port_in_id[i],
- p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_enable(p->p,
- p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p->p) < 0) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
-
- /* Message queues */
- p->n_msgq = params->n_msgq;
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_in[i] = params->msgq_in[i];
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_out[i] = params->msgq_out[i];
-
- /* Message handlers */
- memcpy(p->handlers, handlers, sizeof(p->handlers));
- memcpy(p_fc->custom_handlers,
- custom_handlers,
- sizeof(p_fc->custom_handlers));
-
- return p;
-}
-
-static int
-pipeline_fc_free(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- rte_pipeline_free(p->p);
- rte_free(p);
- return 0;
-}
-
-static int
-pipeline_fc_timer(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- pipeline_msg_req_handle(p);
- rte_pipeline_flush(p->p);
-
- return 0;
-}
-
-static void *
-pipeline_fc_msg_req_custom_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_flow_classification *p_fc =
- (struct pipeline_flow_classification *) p;
- struct pipeline_custom_msg_req *req = msg;
- pipeline_msg_req_handler f_handle;
-
- f_handle = (req->subtype < PIPELINE_FC_MSG_REQS) ?
- p_fc->custom_handlers[req->subtype] :
- pipeline_msg_req_invalid_handler;
-
- if (f_handle == NULL)
- f_handle = pipeline_msg_req_invalid_handler;
-
- return f_handle(p, req);
-}
-
-static void *
-pipeline_fc_msg_req_add_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_fc_add_msg_req *req = msg;
- struct pipeline_fc_add_msg_rsp *rsp = msg;
-
- struct flow_table_entry entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->port_id]},
- },
- .flow_id = req->flow_id,
- };
-
- rsp->status = rte_pipeline_table_entry_add(p->p,
- p->table_id[0],
- &req->key,
- (struct rte_pipeline_table_entry *) &entry,
- &rsp->key_found,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-static void *
-pipeline_fc_msg_req_add_bulk_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_fc_add_bulk_msg_req *req = msg;
- struct pipeline_fc_add_bulk_msg_rsp *rsp = msg;
- uint32_t i;
-
- for (i = 0; i < req->n_keys; i++) {
- struct pipeline_fc_add_bulk_flow_req *flow_req = &req->req[i];
- struct pipeline_fc_add_bulk_flow_rsp *flow_rsp = &req->rsp[i];
-
- struct flow_table_entry entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[flow_req->port_id]},
- },
- .flow_id = flow_req->flow_id,
- };
-
- int status = rte_pipeline_table_entry_add(p->p,
- p->table_id[0],
- &flow_req->key,
- (struct rte_pipeline_table_entry *) &entry,
- &flow_rsp->key_found,
- (struct rte_pipeline_table_entry **)
- &flow_rsp->entry_ptr);
-
- if (status)
- break;
- }
-
- rsp->n_keys = i;
-
- return rsp;
-}
-
-static void *
-pipeline_fc_msg_req_del_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_fc_del_msg_req *req = msg;
- struct pipeline_fc_del_msg_rsp *rsp = msg;
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- p->table_id[0],
- &req->key,
- &rsp->key_found,
- NULL);
-
- return rsp;
-}
-
-static void *
-pipeline_fc_msg_req_add_default_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_fc_add_default_msg_req *req = msg;
- struct pipeline_fc_add_default_msg_rsp *rsp = msg;
-
- struct flow_table_entry default_entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->port_id]},
- },
-
- .flow_id = 0,
- };
-
- rsp->status = rte_pipeline_table_default_entry_add(p->p,
- p->table_id[0],
- (struct rte_pipeline_table_entry *) &default_entry,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-static void *
-pipeline_fc_msg_req_del_default_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_fc_del_default_msg_rsp *rsp = msg;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- p->table_id[0],
- NULL);
-
- return rsp;
-}
-
-struct pipeline_be_ops pipeline_flow_classification_be_ops = {
- .f_init = pipeline_fc_init,
- .f_free = pipeline_fc_free,
- .f_run = NULL,
- .f_timer = pipeline_fc_timer,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h b/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h
deleted file mode 100644
index 18f5bb42..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_flow_classification_be.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_BE_H__
-#define __INCLUDE_PIPELINE_FLOW_CLASSIFICATION_BE_H__
-
-#include "pipeline_common_be.h"
-
-enum pipeline_fc_msg_req_type {
- PIPELINE_FC_MSG_REQ_FLOW_ADD = 0,
- PIPELINE_FC_MSG_REQ_FLOW_ADD_BULK,
- PIPELINE_FC_MSG_REQ_FLOW_DEL,
- PIPELINE_FC_MSG_REQ_FLOW_ADD_DEFAULT,
- PIPELINE_FC_MSG_REQ_FLOW_DEL_DEFAULT,
- PIPELINE_FC_MSG_REQS,
-};
-
-#ifndef PIPELINE_FC_FLOW_KEY_MAX_SIZE
-#define PIPELINE_FC_FLOW_KEY_MAX_SIZE 64
-#endif
-
-/*
- * MSG ADD
- */
-struct pipeline_fc_add_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fc_msg_req_type subtype;
-
- uint8_t key[PIPELINE_FC_FLOW_KEY_MAX_SIZE];
-
- uint32_t port_id;
- uint32_t flow_id;
-};
-
-struct pipeline_fc_add_msg_rsp {
- int status;
- int key_found;
- void *entry_ptr;
-};
-
-/*
- * MSG ADD BULK
- */
-struct pipeline_fc_add_bulk_flow_req {
- uint8_t key[PIPELINE_FC_FLOW_KEY_MAX_SIZE];
- uint32_t port_id;
- uint32_t flow_id;
-};
-
-struct pipeline_fc_add_bulk_flow_rsp {
- int key_found;
- void *entry_ptr;
-};
-
-struct pipeline_fc_add_bulk_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fc_msg_req_type subtype;
-
- struct pipeline_fc_add_bulk_flow_req *req;
- struct pipeline_fc_add_bulk_flow_rsp *rsp;
- uint32_t n_keys;
-};
-
-struct pipeline_fc_add_bulk_msg_rsp {
- uint32_t n_keys;
-};
-
-/*
- * MSG DEL
- */
-struct pipeline_fc_del_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fc_msg_req_type subtype;
-
- uint8_t key[PIPELINE_FC_FLOW_KEY_MAX_SIZE];
-};
-
-struct pipeline_fc_del_msg_rsp {
- int status;
- int key_found;
-};
-
-/*
- * MSG ADD DEFAULT
- */
-struct pipeline_fc_add_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fc_msg_req_type subtype;
-
- uint32_t port_id;
-};
-
-struct pipeline_fc_add_default_msg_rsp {
- int status;
- void *entry_ptr;
-};
-
-/*
- * MSG DEL DEFAULT
- */
-struct pipeline_fc_del_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_fc_msg_req_type subtype;
-};
-
-struct pipeline_fc_del_default_msg_rsp {
- int status;
-};
-
-extern struct pipeline_be_ops pipeline_flow_classification_be_ops;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_master.c b/examples/ip_pipeline/pipeline/pipeline_master.c
deleted file mode 100644
index b0d730a6..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_master.c
+++ /dev/null
@@ -1,20 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#include "pipeline_master.h"
-#include "pipeline_master_be.h"
-
-static struct pipeline_fe_ops pipeline_master_fe_ops = {
- .f_init = NULL,
- .f_post_init = NULL,
- .f_free = NULL,
- .f_track = NULL,
- .cmds = NULL,
-};
-
-struct pipeline_type pipeline_master = {
- .name = "MASTER",
- .be_ops = &pipeline_master_be_ops,
- .fe_ops = &pipeline_master_fe_ops,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_master.h b/examples/ip_pipeline/pipeline/pipeline_master.h
deleted file mode 100644
index a5183e33..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_master.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_MASTER_H__
-#define __INCLUDE_PIPELINE_MASTER_H__
-
-#include "pipeline.h"
-
-extern struct pipeline_type pipeline_master;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_master_be.c b/examples/ip_pipeline/pipeline/pipeline_master_be.c
deleted file mode 100644
index c72038ea..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_master_be.c
+++ /dev/null
@@ -1,141 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#include <fcntl.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-
-#include <cmdline_parse.h>
-#include <cmdline_parse_string.h>
-#include <cmdline_socket.h>
-#include <cmdline.h>
-
-#include "app.h"
-#include "pipeline_master_be.h"
-
-struct pipeline_master {
- struct app_params *app;
- struct cmdline *cl;
- int post_init_done;
- int script_file_done;
-} __rte_cache_aligned;
-
-static void*
-pipeline_init(__rte_unused struct pipeline_params *params, void *arg)
-{
- struct app_params *app = (struct app_params *) arg;
- struct pipeline_master *p;
- uint32_t size;
-
- /* Check input arguments */
- if (app == NULL)
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_master));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p == NULL)
- return NULL;
-
- /* Initialization */
- p->app = app;
-
- p->cl = cmdline_stdin_new(app->cmds, "pipeline> ");
- if (p->cl == NULL) {
- rte_free(p);
- return NULL;
- }
-
- p->post_init_done = 0;
- p->script_file_done = 0;
- if (app->script_file == NULL)
- p->script_file_done = 1;
-
- return (void *) p;
-}
-
-static int
-pipeline_free(void *pipeline)
-{
- struct pipeline_master *p = (struct pipeline_master *) pipeline;
-
- if (p == NULL)
- return -EINVAL;
-
- cmdline_stdin_exit(p->cl);
- rte_free(p);
-
- return 0;
-}
-
-static int
-pipeline_run(void *pipeline)
-{
- struct pipeline_master *p = (struct pipeline_master *) pipeline;
- struct app_params *app = p->app;
- int status;
-#ifdef RTE_LIBRTE_KNI
- uint32_t i;
-#endif /* RTE_LIBRTE_KNI */
-
- /* Application post-init phase */
- if (p->post_init_done == 0) {
- app_post_init(app);
-
- p->post_init_done = 1;
- }
-
- /* Run startup script file */
- if (p->script_file_done == 0) {
- struct app_params *app = p->app;
- int fd = open(app->script_file, O_RDONLY);
-
- if (fd < 0)
- printf("Cannot open CLI script file \"%s\"\n",
- app->script_file);
- else {
- struct cmdline *file_cl;
-
- printf("Running CLI script file \"%s\" ...\n",
- app->script_file);
- file_cl = cmdline_new(p->cl->ctx, "", fd, 1);
- cmdline_interact(file_cl);
- close(fd);
- }
-
- p->script_file_done = 1;
- }
-
- /* Command Line Interface (CLI) */
- status = cmdline_poll(p->cl);
- if (status < 0)
- rte_panic("CLI poll error (%" PRId32 ")\n", status);
- else if (status == RDLINE_EXITED) {
- cmdline_stdin_exit(p->cl);
- rte_exit(0, "Bye!\n");
- }
-
-#ifdef RTE_LIBRTE_KNI
- /* Handle KNI requests from Linux kernel */
- for (i = 0; i < app->n_pktq_kni; i++)
- rte_kni_handle_request(app->kni[i]);
-#endif /* RTE_LIBRTE_KNI */
-
- return 0;
-}
-
-static int
-pipeline_timer(__rte_unused void *pipeline)
-{
- return 0;
-}
-
-struct pipeline_be_ops pipeline_master_be_ops = {
- .f_init = pipeline_init,
- .f_free = pipeline_free,
- .f_run = pipeline_run,
- .f_timer = pipeline_timer,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_master_be.h b/examples/ip_pipeline/pipeline/pipeline_master_be.h
deleted file mode 100644
index 847c564c..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_master_be.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_MASTER_BE_H__
-#define __INCLUDE_PIPELINE_MASTER_BE_H__
-
-#include "pipeline_common_be.h"
-
-extern struct pipeline_be_ops pipeline_master_be_ops;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough.c b/examples/ip_pipeline/pipeline/pipeline_passthrough.c
deleted file mode 100644
index 031f5f05..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough.c
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#include "pipeline_passthrough.h"
-#include "pipeline_passthrough_be.h"
-
-static int
-app_pipeline_passthrough_track(struct pipeline_params *p,
- uint32_t port_in,
- uint32_t *port_out)
-{
- struct pipeline_passthrough_params pp;
- int status;
-
- /* Check input arguments */
- if ((p == NULL) ||
- (port_in >= p->n_ports_in) ||
- (port_out == NULL))
- return -1;
-
- status = pipeline_passthrough_parse_args(&pp, p);
- if (status)
- return -1;
-
- if (pp.dma_hash_lb_enabled)
- return -1;
-
- *port_out = port_in / (p->n_ports_in / p->n_ports_out);
- return 0;
-}
-
-static struct pipeline_fe_ops pipeline_passthrough_fe_ops = {
- .f_init = NULL,
- .f_post_init = NULL,
- .f_free = NULL,
- .f_track = app_pipeline_passthrough_track,
- .cmds = NULL,
-};
-
-struct pipeline_type pipeline_passthrough = {
- .name = "PASS-THROUGH",
- .be_ops = &pipeline_passthrough_be_ops,
- .fe_ops = &pipeline_passthrough_fe_ops,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough.h b/examples/ip_pipeline/pipeline/pipeline_passthrough.h
deleted file mode 100644
index 7a7a2fc6..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_PASSTHROUGH_H__
-#define __INCLUDE_PIPELINE_PASSTHROUGH_H__
-
-#include "pipeline.h"
-
-extern struct pipeline_type pipeline_passthrough;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
deleted file mode 100644
index b2bbaedd..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.c
+++ /dev/null
@@ -1,929 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_byteorder.h>
-#include <rte_table_stub.h>
-#include <rte_table_hash.h>
-#include <rte_pipeline.h>
-
-#include "pipeline_passthrough_be.h"
-#include "pipeline_actions_common.h"
-#include "parser.h"
-#include "hash_func.h"
-
-#define SWAP_DIM (PIPELINE_PASSTHROUGH_SWAP_N_FIELDS_MAX * \
- (PIPELINE_PASSTHROUGH_SWAP_FIELD_SIZE_MAX / sizeof(uint64_t)))
-
-struct pipeline_passthrough {
- struct pipeline p;
- struct pipeline_passthrough_params params;
- rte_table_hash_op_hash f_hash;
- uint32_t swap_field0_offset[SWAP_DIM];
- uint32_t swap_field1_offset[SWAP_DIM];
- uint64_t swap_field_mask[SWAP_DIM];
- uint32_t swap_n_fields;
-} __rte_cache_aligned;
-
-static pipeline_msg_req_handler handlers[] = {
- [PIPELINE_MSG_REQ_PING] =
- pipeline_msg_req_ping_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_IN] =
- pipeline_msg_req_stats_port_in_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
- pipeline_msg_req_stats_port_out_handler,
- [PIPELINE_MSG_REQ_STATS_TABLE] =
- pipeline_msg_req_stats_table_handler,
- [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
- pipeline_msg_req_port_in_enable_handler,
- [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
- pipeline_msg_req_port_in_disable_handler,
- [PIPELINE_MSG_REQ_CUSTOM] =
- pipeline_msg_req_invalid_handler,
-};
-
-static __rte_always_inline void
-pkt_work_dma(
- struct rte_mbuf *pkt,
- void *arg,
- uint32_t dma_size,
- uint32_t hash_enabled,
- uint32_t lb_hash,
- uint32_t port_out_pow2)
-{
- struct pipeline_passthrough *p = arg;
-
- uint64_t *dma_dst = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->params.dma_dst_offset);
- uint64_t *dma_src = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->params.dma_src_offset);
- uint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;
- uint32_t *dma_hash = RTE_MBUF_METADATA_UINT32_PTR(pkt,
- p->params.dma_hash_offset);
- uint32_t i;
-
- /* Read (dma_src), compute (dma_dst), write (dma_dst) */
- for (i = 0; i < (dma_size / 8); i++)
- dma_dst[i] = dma_src[i] & dma_mask[i];
-
- /* Read (dma_dst), compute (hash), write (hash) */
- if (hash_enabled) {
- uint32_t hash = p->f_hash(dma_src, dma_mask, dma_size, 0);
- *dma_hash = hash;
-
- if (lb_hash) {
- uint32_t port_out;
-
- if (port_out_pow2)
- port_out
- = hash & (p->p.n_ports_out - 1);
- else
- port_out
- = hash % p->p.n_ports_out;
-
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out, pkt);
- }
- }
-}
-
-static __rte_always_inline void
-pkt4_work_dma(
- struct rte_mbuf **pkts,
- void *arg,
- uint32_t dma_size,
- uint32_t hash_enabled,
- uint32_t lb_hash,
- uint32_t port_out_pow2)
-{
- struct pipeline_passthrough *p = arg;
-
- uint64_t *dma_dst0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->params.dma_dst_offset);
- uint64_t *dma_dst1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->params.dma_dst_offset);
- uint64_t *dma_dst2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->params.dma_dst_offset);
- uint64_t *dma_dst3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->params.dma_dst_offset);
-
- uint64_t *dma_src0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->params.dma_src_offset);
- uint64_t *dma_src1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->params.dma_src_offset);
- uint64_t *dma_src2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->params.dma_src_offset);
- uint64_t *dma_src3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->params.dma_src_offset);
-
- uint64_t *dma_mask = (uint64_t *) p->params.dma_src_mask;
-
- uint32_t *dma_hash0 = RTE_MBUF_METADATA_UINT32_PTR(pkts[0],
- p->params.dma_hash_offset);
- uint32_t *dma_hash1 = RTE_MBUF_METADATA_UINT32_PTR(pkts[1],
- p->params.dma_hash_offset);
- uint32_t *dma_hash2 = RTE_MBUF_METADATA_UINT32_PTR(pkts[2],
- p->params.dma_hash_offset);
- uint32_t *dma_hash3 = RTE_MBUF_METADATA_UINT32_PTR(pkts[3],
- p->params.dma_hash_offset);
-
- uint32_t i;
-
- /* Read (dma_src), compute (dma_dst), write (dma_dst) */
- for (i = 0; i < (dma_size / 8); i++) {
- dma_dst0[i] = dma_src0[i] & dma_mask[i];
- dma_dst1[i] = dma_src1[i] & dma_mask[i];
- dma_dst2[i] = dma_src2[i] & dma_mask[i];
- dma_dst3[i] = dma_src3[i] & dma_mask[i];
- }
-
- /* Read (dma_dst), compute (hash), write (hash) */
- if (hash_enabled) {
- uint32_t hash0 = p->f_hash(dma_src0, dma_mask, dma_size, 0);
- uint32_t hash1 = p->f_hash(dma_src1, dma_mask, dma_size, 0);
- uint32_t hash2 = p->f_hash(dma_src2, dma_mask, dma_size, 0);
- uint32_t hash3 = p->f_hash(dma_src3, dma_mask, dma_size, 0);
-
- *dma_hash0 = hash0;
- *dma_hash1 = hash1;
- *dma_hash2 = hash2;
- *dma_hash3 = hash3;
-
- if (lb_hash) {
- uint32_t port_out0, port_out1, port_out2, port_out3;
-
- if (port_out_pow2) {
- port_out0
- = hash0 & (p->p.n_ports_out - 1);
- port_out1
- = hash1 & (p->p.n_ports_out - 1);
- port_out2
- = hash2 & (p->p.n_ports_out - 1);
- port_out3
- = hash3 & (p->p.n_ports_out - 1);
- } else {
- port_out0
- = hash0 % p->p.n_ports_out;
- port_out1
- = hash1 % p->p.n_ports_out;
- port_out2
- = hash2 % p->p.n_ports_out;
- port_out3
- = hash3 % p->p.n_ports_out;
- }
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out0, pkts[0]);
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out1, pkts[1]);
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out2, pkts[2]);
- rte_pipeline_port_out_packet_insert(p->p.p,
- port_out3, pkts[3]);
- }
- }
-}
-
-static __rte_always_inline void
-pkt_work_swap(
- struct rte_mbuf *pkt,
- void *arg)
-{
- struct pipeline_passthrough *p = arg;
- uint32_t i;
-
- /* Read(field0, field1), compute(field0, field1), write(field0, field1) */
- for (i = 0; i < p->swap_n_fields; i++) {
- uint64_t *field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->swap_field0_offset[i]);
- uint64_t *field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt,
- p->swap_field1_offset[i]);
- uint64_t mask = p->swap_field_mask[i];
-
- uint64_t field0 = *field0_ptr;
- uint64_t field1 = *field1_ptr;
-
- *field0_ptr = (field0 & (~mask)) + (field1 & mask);
- *field1_ptr = (field0 & mask) + (field1 & (~mask));
- }
-}
-
-static __rte_always_inline void
-pkt4_work_swap(
- struct rte_mbuf **pkts,
- void *arg)
-{
- struct pipeline_passthrough *p = arg;
- uint32_t i;
-
- /* Read(field0, field1), compute(field0, field1), write(field0, field1) */
- for (i = 0; i < p->swap_n_fields; i++) {
- uint64_t *pkt0_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->swap_field0_offset[i]);
- uint64_t *pkt1_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->swap_field0_offset[i]);
- uint64_t *pkt2_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->swap_field0_offset[i]);
- uint64_t *pkt3_field0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->swap_field0_offset[i]);
-
- uint64_t *pkt0_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- p->swap_field1_offset[i]);
- uint64_t *pkt1_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- p->swap_field1_offset[i]);
- uint64_t *pkt2_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- p->swap_field1_offset[i]);
- uint64_t *pkt3_field1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- p->swap_field1_offset[i]);
-
- uint64_t mask = p->swap_field_mask[i];
-
- uint64_t pkt0_field0 = *pkt0_field0_ptr;
- uint64_t pkt1_field0 = *pkt1_field0_ptr;
- uint64_t pkt2_field0 = *pkt2_field0_ptr;
- uint64_t pkt3_field0 = *pkt3_field0_ptr;
-
- uint64_t pkt0_field1 = *pkt0_field1_ptr;
- uint64_t pkt1_field1 = *pkt1_field1_ptr;
- uint64_t pkt2_field1 = *pkt2_field1_ptr;
- uint64_t pkt3_field1 = *pkt3_field1_ptr;
-
- *pkt0_field0_ptr = (pkt0_field0 & (~mask)) + (pkt0_field1 & mask);
- *pkt1_field0_ptr = (pkt1_field0 & (~mask)) + (pkt1_field1 & mask);
- *pkt2_field0_ptr = (pkt2_field0 & (~mask)) + (pkt2_field1 & mask);
- *pkt3_field0_ptr = (pkt3_field0 & (~mask)) + (pkt3_field1 & mask);
-
- *pkt0_field1_ptr = (pkt0_field0 & mask) + (pkt0_field1 & (~mask));
- *pkt1_field1_ptr = (pkt1_field0 & mask) + (pkt1_field1 & (~mask));
- *pkt2_field1_ptr = (pkt2_field0 & mask) + (pkt2_field1 & (~mask));
- *pkt3_field1_ptr = (pkt3_field0 & mask) + (pkt3_field1 & (~mask));
- }
-}
-
-#define PKT_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-static inline void \
-pkt_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2( \
- struct rte_mbuf *pkt, \
- void *arg) \
-{ \
- pkt_work_dma(pkt, arg, dma_size, hash_enabled, lb_hash, port_pow2); \
-}
-
-#define PKT4_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-static inline void \
-pkt4_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2( \
- struct rte_mbuf **pkts, \
- void *arg) \
-{ \
- pkt4_work_dma(pkts, arg, dma_size, hash_enabled, lb_hash, port_pow2); \
-}
-
-#define port_in_ah_dma(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT4_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PIPELINE_PORT_IN_AH(port_in_ah_dma_size##dma_size##_hash \
- ##hash_enabled##_lb##lb_hash##_pw##port_pow2, \
- pkt_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2, \
- pkt4_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2)
-
-
-#define port_in_ah_lb(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PKT4_WORK_DMA(dma_size, hash_enabled, lb_hash, port_pow2) \
-PIPELINE_PORT_IN_AH_HIJACK_ALL( \
- port_in_ah_lb_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2, \
- pkt_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2, \
- pkt4_work_dma_size##dma_size##_hash##hash_enabled \
- ##_lb##lb_hash##_pw##port_pow2)
-
-PIPELINE_PORT_IN_AH(port_in_ah_swap, pkt_work_swap, pkt4_work_swap)
-
-
-/* Port in AH DMA(dma_size, hash_enabled, lb_hash, port_pow2) */
-
-port_in_ah_dma(8, 0, 0, 0)
-port_in_ah_dma(8, 1, 0, 0)
-port_in_ah_lb(8, 1, 1, 0)
-port_in_ah_lb(8, 1, 1, 1)
-
-port_in_ah_dma(16, 0, 0, 0)
-port_in_ah_dma(16, 1, 0, 0)
-port_in_ah_lb(16, 1, 1, 0)
-port_in_ah_lb(16, 1, 1, 1)
-
-port_in_ah_dma(24, 0, 0, 0)
-port_in_ah_dma(24, 1, 0, 0)
-port_in_ah_lb(24, 1, 1, 0)
-port_in_ah_lb(24, 1, 1, 1)
-
-port_in_ah_dma(32, 0, 0, 0)
-port_in_ah_dma(32, 1, 0, 0)
-port_in_ah_lb(32, 1, 1, 0)
-port_in_ah_lb(32, 1, 1, 1)
-
-port_in_ah_dma(40, 0, 0, 0)
-port_in_ah_dma(40, 1, 0, 0)
-port_in_ah_lb(40, 1, 1, 0)
-port_in_ah_lb(40, 1, 1, 1)
-
-port_in_ah_dma(48, 0, 0, 0)
-port_in_ah_dma(48, 1, 0, 0)
-port_in_ah_lb(48, 1, 1, 0)
-port_in_ah_lb(48, 1, 1, 1)
-
-port_in_ah_dma(56, 0, 0, 0)
-port_in_ah_dma(56, 1, 0, 0)
-port_in_ah_lb(56, 1, 1, 0)
-port_in_ah_lb(56, 1, 1, 1)
-
-port_in_ah_dma(64, 0, 0, 0)
-port_in_ah_dma(64, 1, 0, 0)
-port_in_ah_lb(64, 1, 1, 0)
-port_in_ah_lb(64, 1, 1, 1)
-
-static rte_pipeline_port_in_action_handler
-get_port_in_ah(struct pipeline_passthrough *p)
-{
- if ((p->params.dma_enabled == 0) &&
- (p->params.swap_enabled == 0))
- return NULL;
-
- if (p->params.swap_enabled)
- return port_in_ah_swap;
-
- if (p->params.dma_hash_enabled) {
- if (p->params.dma_hash_lb_enabled) {
- if (rte_is_power_of_2(p->p.n_ports_out))
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_lb_size8_hash1_lb1_pw1;
- case 16: return port_in_ah_lb_size16_hash1_lb1_pw1;
- case 24: return port_in_ah_lb_size24_hash1_lb1_pw1;
- case 32: return port_in_ah_lb_size32_hash1_lb1_pw1;
- case 40: return port_in_ah_lb_size40_hash1_lb1_pw1;
- case 48: return port_in_ah_lb_size48_hash1_lb1_pw1;
- case 56: return port_in_ah_lb_size56_hash1_lb1_pw1;
- case 64: return port_in_ah_lb_size64_hash1_lb1_pw1;
- default: return NULL;
- }
- else
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_lb_size8_hash1_lb1_pw0;
- case 16: return port_in_ah_lb_size16_hash1_lb1_pw0;
- case 24: return port_in_ah_lb_size24_hash1_lb1_pw0;
- case 32: return port_in_ah_lb_size32_hash1_lb1_pw0;
- case 40: return port_in_ah_lb_size40_hash1_lb1_pw0;
- case 48: return port_in_ah_lb_size48_hash1_lb1_pw0;
- case 56: return port_in_ah_lb_size56_hash1_lb1_pw0;
- case 64: return port_in_ah_lb_size64_hash1_lb1_pw0;
- default: return NULL;
- }
- } else
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_dma_size8_hash1_lb0_pw0;
- case 16: return port_in_ah_dma_size16_hash1_lb0_pw0;
- case 24: return port_in_ah_dma_size24_hash1_lb0_pw0;
- case 32: return port_in_ah_dma_size32_hash1_lb0_pw0;
- case 40: return port_in_ah_dma_size40_hash1_lb0_pw0;
- case 48: return port_in_ah_dma_size48_hash1_lb0_pw0;
- case 56: return port_in_ah_dma_size56_hash1_lb0_pw0;
- case 64: return port_in_ah_dma_size64_hash1_lb0_pw0;
- default: return NULL;
- }
- } else
- switch (p->params.dma_size) {
-
- case 8: return port_in_ah_dma_size8_hash0_lb0_pw0;
- case 16: return port_in_ah_dma_size16_hash0_lb0_pw0;
- case 24: return port_in_ah_dma_size24_hash0_lb0_pw0;
- case 32: return port_in_ah_dma_size32_hash0_lb0_pw0;
- case 40: return port_in_ah_dma_size40_hash0_lb0_pw0;
- case 48: return port_in_ah_dma_size48_hash0_lb0_pw0;
- case 56: return port_in_ah_dma_size56_hash0_lb0_pw0;
- case 64: return port_in_ah_dma_size64_hash0_lb0_pw0;
- default: return NULL;
- }
-}
-
-int
-pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
- struct pipeline_params *params)
-{
- uint32_t dma_dst_offset_present = 0;
- uint32_t dma_src_offset_present = 0;
- uint32_t dma_src_mask_present = 0;
- char dma_mask_str[PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2 + 1];
- uint32_t dma_size_present = 0;
- uint32_t dma_hash_offset_present = 0;
- uint32_t dma_hash_lb_present = 0;
- uint32_t i;
-
- /* default values */
- p->dma_enabled = 0;
- p->dma_hash_enabled = 0;
- p->dma_hash_lb_enabled = 0;
- memset(p->dma_src_mask, 0xFF, sizeof(p->dma_src_mask));
- p->swap_enabled = 0;
- p->swap_n_fields = 0;
-
- for (i = 0; i < params->n_args; i++) {
- char *arg_name = params->args_name[i];
- char *arg_value = params->args_value[i];
-
- /* dma_dst_offset */
- if (strcmp(arg_name, "dma_dst_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_dst_offset_present == 0, params->name,
- arg_name);
- dma_dst_offset_present = 1;
-
- status = parser_read_uint32(&p->dma_dst_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_src_offset */
- if (strcmp(arg_name, "dma_src_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_src_offset_present == 0, params->name,
- arg_name);
- dma_src_offset_present = 1;
-
- status = parser_read_uint32(&p->dma_src_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_size */
- if (strcmp(arg_name, "dma_size") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_size_present == 0, params->name,
- arg_name);
- dma_size_present = 1;
-
- status = parser_read_uint32(&p->dma_size,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
- (p->dma_size != 0) &&
- ((p->dma_size % 8) == 0)),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG(((status != -ERANGE) &&
- (p->dma_size <=
- PIPELINE_PASSTHROUGH_DMA_SIZE_MAX)),
- params->name, arg_name, arg_value);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_src_mask */
- if (strcmp(arg_name, "dma_src_mask") == 0) {
- int mask_str_len = strlen(arg_value);
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_src_mask_present == 0,
- params->name, arg_name);
- dma_src_mask_present = 1;
-
- PIPELINE_ARG_CHECK((mask_str_len <=
- (PIPELINE_PASSTHROUGH_DMA_SIZE_MAX * 2)),
- "Parse error in section \"%s\": entry "
- "\"%s\" too long", params->name,
- arg_name);
-
- snprintf(dma_mask_str, mask_str_len + 1,
- "%s", arg_value);
-
- p->dma_enabled = 1;
-
- continue;
- }
-
- /* dma_hash_offset */
- if (strcmp(arg_name, "dma_hash_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_hash_offset_present == 0,
- params->name, arg_name);
- dma_hash_offset_present = 1;
-
- status = parser_read_uint32(&p->dma_hash_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- p->dma_hash_enabled = 1;
-
- continue;
- }
-
- /* load_balance mode */
- if (strcmp(arg_name, "lb") == 0) {
- PIPELINE_PARSE_ERR_DUPLICATE(
- dma_hash_lb_present == 0,
- params->name, arg_name);
- dma_hash_lb_present = 1;
-
- if (strcmp(arg_value, "hash") &&
- strcmp(arg_value, "HASH"))
-
- PIPELINE_PARSE_ERR_INV_VAL(0,
- params->name,
- arg_name,
- arg_value);
-
- p->dma_hash_lb_enabled = 1;
-
- continue;
- }
-
- /* swap */
- if (strcmp(arg_name, "swap") == 0) {
- uint32_t a, b, n_args;
- int len;
-
- n_args = sscanf(arg_value, "%" SCNu32 " %" SCNu32 "%n",
- &a, &b, &len);
- PIPELINE_PARSE_ERR_INV_VAL(((n_args == 2) &&
- ((size_t) len == strlen(arg_value))),
- params->name, arg_name, arg_value);
-
- p->swap_field0_offset[p->swap_n_fields] = a;
- p->swap_field1_offset[p->swap_n_fields] = b;
- p->swap_n_fields++;
- p->swap_enabled = 1;
-
- continue;
- }
-
- /* any other */
- PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
- }
-
- /* Check correlations between arguments */
- PIPELINE_ARG_CHECK((p->dma_enabled + p->swap_enabled < 2),
- "Parse error in section \"%s\": DMA and SWAP actions are both enabled",
- params->name);
- PIPELINE_ARG_CHECK((dma_dst_offset_present == p->dma_enabled),
- "Parse error in section \"%s\": missing entry "
- "\"dma_dst_offset\"", params->name);
- PIPELINE_ARG_CHECK((dma_src_offset_present == p->dma_enabled),
- "Parse error in section \"%s\": missing entry "
- "\"dma_src_offset\"", params->name);
- PIPELINE_ARG_CHECK((dma_size_present == p->dma_enabled),
- "Parse error in section \"%s\": missing entry "
- "\"dma_size\"", params->name);
- PIPELINE_ARG_CHECK((p->dma_hash_enabled <= p->dma_enabled),
- "Parse error in section \"%s\": missing all DMA entries",
- params->name);
- PIPELINE_ARG_CHECK((p->dma_hash_lb_enabled <= p->dma_hash_enabled),
- "Parse error in section \"%s\": missing all DMA hash entries ",
- params->name);
-
- if (dma_src_mask_present) {
- uint32_t dma_size = p->dma_size;
- int status;
-
- PIPELINE_ARG_CHECK((strlen(dma_mask_str) ==
- (dma_size * 2)), "Parse error in section "
- "\"%s\": dma_src_mask should have exactly %u hex "
- "digits", params->name, (dma_size * 2));
-
- status = parse_hex_string(dma_mask_str, p->dma_src_mask,
- &p->dma_size);
-
- PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
- (dma_size == p->dma_size)), params->name,
- "dma_src_mask", dma_mask_str);
- }
-
- if (p->dma_hash_lb_enabled)
- PIPELINE_ARG_CHECK((params->n_ports_out > 1),
- "Parse error in section \"%s\": entry \"lb\" not "
- "allowed for single output port pipeline",
- params->name);
- else
- PIPELINE_ARG_CHECK(((params->n_ports_in >= params->n_ports_out)
- && ((params->n_ports_in % params->n_ports_out) == 0)),
- "Parse error in section \"%s\": n_ports_in needs to be "
- "a multiple of n_ports_out (lb mode disabled)",
- params->name);
-
- return 0;
-}
-
-static rte_table_hash_op_hash
-get_hash_function(struct pipeline_passthrough *p)
-{
- switch (p->params.dma_size) {
-
- case 8: return hash_default_key8;
- case 16: return hash_default_key16;
- case 24: return hash_default_key24;
- case 32: return hash_default_key32;
- case 40: return hash_default_key40;
- case 48: return hash_default_key48;
- case 56: return hash_default_key56;
- case 64: return hash_default_key64;
- default: return NULL;
- }
-}
-
-static int
-pipeline_passthrough_swap_convert(struct pipeline_passthrough *p)
-{
- uint32_t i;
-
- p->swap_n_fields = 0;
-
- for (i = 0; i < p->params.swap_n_fields; i++) {
- uint32_t offset0 = p->params.swap_field0_offset[i];
- uint32_t offset1 = p->params.swap_field1_offset[i];
- uint32_t size = offset1 - offset0;
- uint32_t j;
-
- /* Check */
- if ((offset0 >= offset1) ||
- (size > PIPELINE_PASSTHROUGH_SWAP_FIELD_SIZE_MAX) ||
- (p->swap_n_fields >= SWAP_DIM))
- return -1;
-
- for (j = 0; j < (size / sizeof(uint64_t)); j++) {
- p->swap_field0_offset[p->swap_n_fields] = offset0;
- p->swap_field1_offset[p->swap_n_fields] = offset1;
- p->swap_field_mask[p->swap_n_fields] = UINT64_MAX;
- p->swap_n_fields++;
- offset0 += sizeof(uint64_t);
- offset1 += sizeof(uint64_t);
- }
- if (size % sizeof(uint64_t)) {
- uint32_t n_bits = (size % sizeof(uint64_t)) * 8;
-
- p->swap_field0_offset[p->swap_n_fields] = offset0;
- p->swap_field1_offset[p->swap_n_fields] = offset1;
- p->swap_field_mask[p->swap_n_fields] =
- RTE_LEN2MASK(n_bits, uint64_t);
- p->swap_n_fields++;
- }
- }
-
- return 0;
-}
-
-static void*
-pipeline_passthrough_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct pipeline *p;
- struct pipeline_passthrough *p_pt;
- uint32_t size, i;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_passthrough));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- p_pt = (struct pipeline_passthrough *) p;
- if (p == NULL)
- return NULL;
-
- strcpy(p->name, params->name);
- p->log_level = params->log_level;
-
- PLOG(p, HIGH, "Pass-through");
-
- /* Parse arguments */
- if (pipeline_passthrough_parse_args(&p_pt->params, params))
- return NULL;
- if (pipeline_passthrough_swap_convert(p_pt))
- return NULL;
- p_pt->f_hash = get_hash_function(p_pt);
-
- /* Pipeline */
- {
- struct rte_pipeline_params pipeline_params = {
- .name = "PASS-THROUGH",
- .socket_id = params->socket_id,
- .offset_port_id = 0,
- };
-
- p->p = rte_pipeline_create(&pipeline_params);
- if (p->p == NULL) {
- rte_free(p);
- return NULL;
- }
- }
-
- p->n_ports_in = params->n_ports_in;
- p->n_ports_out = params->n_ports_out;
- p->n_tables = p->n_ports_in;
-
- /*Input ports*/
- for (i = 0; i < p->n_ports_in; i++) {
- struct rte_pipeline_port_in_params port_params = {
- .ops = pipeline_port_in_params_get_ops(
- &params->port_in[i]),
- .arg_create = pipeline_port_in_params_convert(
- &params->port_in[i]),
- .f_action = get_port_in_ah(p_pt),
- .arg_ah = p_pt,
- .burst_size = params->port_in[i].burst_size,
- };
-
- int status = rte_pipeline_port_in_create(p->p,
- &port_params,
- &p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Output ports */
- for (i = 0; i < p->n_ports_out; i++) {
- struct rte_pipeline_port_out_params port_params = {
- .ops = pipeline_port_out_params_get_ops(
- &params->port_out[i]),
- .arg_create = pipeline_port_out_params_convert(
- &params->port_out[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- int status = rte_pipeline_port_out_create(p->p,
- &port_params,
- &p->port_out_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Tables */
- for (i = 0; i < p->n_ports_in; 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,
- };
-
- int status = rte_pipeline_table_create(p->p,
- &table_params,
- &p->table_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Connecting input ports to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_connect_to_table(p->p,
- p->port_in_id[i],
- p->table_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Add entries to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- uint32_t port_out_id = (p_pt->params.dma_hash_lb_enabled == 0) ?
- (i / (p->n_ports_in / p->n_ports_out)) :
- 0;
-
- struct rte_pipeline_table_entry default_entry = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[port_out_id]},
- };
-
- struct rte_pipeline_table_entry *default_entry_ptr;
-
- int status = rte_pipeline_table_default_entry_add(p->p,
- p->table_id[i],
- &default_entry,
- &default_entry_ptr);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_enable(p->p,
- p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p->p) < 0) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
-
- /* Message queues */
- p->n_msgq = params->n_msgq;
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_in[i] = params->msgq_in[i];
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_out[i] = params->msgq_out[i];
-
- /* Message handlers */
- memcpy(p->handlers, handlers, sizeof(p->handlers));
-
- return p;
-}
-
-static int
-pipeline_passthrough_free(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- rte_pipeline_free(p->p);
- rte_free(p);
- return 0;
-}
-
-static int
-pipeline_passthrough_timer(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- pipeline_msg_req_handle(p);
- rte_pipeline_flush(p->p);
-
- return 0;
-}
-
-struct pipeline_be_ops pipeline_passthrough_be_ops = {
- .f_init = pipeline_passthrough_init,
- .f_free = pipeline_passthrough_free,
- .f_run = NULL,
- .f_timer = pipeline_passthrough_timer,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.h b/examples/ip_pipeline/pipeline/pipeline_passthrough_be.h
deleted file mode 100644
index 94d1d1cf..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_passthrough_be.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_PASSTHROUGH_BE_H__
-#define __INCLUDE_PIPELINE_PASSTHROUGH_BE_H__
-
-#include "pipeline_common_be.h"
-
-#define PIPELINE_PASSTHROUGH_DMA_SIZE_MAX 64
-
-#ifndef PIPELINE_PASSTHROUGH_SWAP_N_FIELDS_MAX
-#define PIPELINE_PASSTHROUGH_SWAP_N_FIELDS_MAX 8
-#endif
-
-#ifndef PIPELINE_PASSTHROUGH_SWAP_FIELD_SIZE_MAX
-#define PIPELINE_PASSTHROUGH_SWAP_FIELD_SIZE_MAX 16
-#endif
-
-struct pipeline_passthrough_params {
- uint32_t dma_enabled;
- uint32_t dma_dst_offset;
- uint32_t dma_src_offset;
- uint8_t dma_src_mask[PIPELINE_PASSTHROUGH_DMA_SIZE_MAX];
- uint32_t dma_size;
-
- uint32_t dma_hash_enabled;
- uint32_t dma_hash_offset;
-
- uint32_t dma_hash_lb_enabled;
-
- uint32_t swap_enabled;
- uint32_t swap_field0_offset[PIPELINE_PASSTHROUGH_SWAP_N_FIELDS_MAX];
- uint32_t swap_field1_offset[PIPELINE_PASSTHROUGH_SWAP_N_FIELDS_MAX];
- uint32_t swap_n_fields;
-};
-
-int
-pipeline_passthrough_parse_args(struct pipeline_passthrough_params *p,
- struct pipeline_params *params);
-
-extern struct pipeline_be_ops pipeline_passthrough_be_ops;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.c b/examples/ip_pipeline/pipeline/pipeline_routing.c
deleted file mode 100644
index 0562c63a..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_routing.c
+++ /dev/null
@@ -1,1613 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-
-#include "app.h"
-#include "pipeline_common_fe.h"
-#include "pipeline_routing.h"
-#include "parser.h"
-
-struct app_pipeline_routing_route {
- struct pipeline_routing_route_key key;
- struct pipeline_routing_route_data data;
- void *entry_ptr;
-
- TAILQ_ENTRY(app_pipeline_routing_route) node;
-};
-
-struct app_pipeline_routing_arp_entry {
- struct pipeline_routing_arp_key key;
- struct ether_addr macaddr;
- void *entry_ptr;
-
- TAILQ_ENTRY(app_pipeline_routing_arp_entry) node;
-};
-
-struct pipeline_routing {
- /* Parameters */
- struct app_params *app;
- uint32_t pipeline_id;
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- struct pipeline_routing_params rp;
-
- /* Links */
- uint32_t link_id[PIPELINE_MAX_PORT_OUT];
-
- /* Routes */
- TAILQ_HEAD(, app_pipeline_routing_route) routes;
- uint32_t n_routes;
-
- uint32_t default_route_present;
- uint32_t default_route_port_id;
- void *default_route_entry_ptr;
-
- /* ARP entries */
- TAILQ_HEAD(, app_pipeline_routing_arp_entry) arp_entries;
- uint32_t n_arp_entries;
-
- uint32_t default_arp_entry_present;
- uint32_t default_arp_entry_port_id;
- void *default_arp_entry_ptr;
-};
-
-static int
-app_pipeline_routing_find_link(struct pipeline_routing *p,
- uint32_t link_id,
- uint32_t *port_id)
-{
- uint32_t i;
-
- for (i = 0; i < p->n_ports_out; i++)
- if (p->link_id[i] == link_id) {
- *port_id = i;
- return 0;
- }
-
- return -1;
-}
-
-static void
-app_pipeline_routing_link_op(__rte_unused struct app_params *app,
- uint32_t link_id,
- uint32_t up,
- void *arg)
-{
- struct pipeline_routing_route_key key0, key1;
- struct pipeline_routing *p = arg;
- struct app_link_params *lp;
- uint32_t port_id, netmask;
- int status;
-
- if (app == NULL)
- return;
-
- APP_PARAM_FIND_BY_ID(app->link_params, "LINK", link_id, lp);
- if (lp == NULL)
- return;
-
- status = app_pipeline_routing_find_link(p,
- link_id,
- &port_id);
- if (status)
- return;
-
- netmask = (~0U) << (32 - lp->depth);
-
- /* Local network (directly attached network) */
- key0.type = PIPELINE_ROUTING_ROUTE_IPV4;
- key0.key.ipv4.ip = lp->ip & netmask;
- key0.key.ipv4.depth = lp->depth;
-
- /* Local termination */
- key1.type = PIPELINE_ROUTING_ROUTE_IPV4;
- key1.key.ipv4.ip = lp->ip;
- key1.key.ipv4.depth = 32;
-
- if (up) {
- struct pipeline_routing_route_data data0, data1;
-
- /* Local network (directly attached network) */
- memset(&data0, 0, sizeof(data0));
- data0.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
- PIPELINE_ROUTING_ROUTE_ARP;
- if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
- data0.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
- if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
- data0.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
- data0.l2.mpls.n_labels = 1;
- }
- data0.port_id = port_id;
-
- if (p->rp.n_arp_entries)
- app_pipeline_routing_add_route(app,
- p->pipeline_id,
- &key0,
- &data0);
-
- /* Local termination */
- memset(&data1, 0, sizeof(data1));
- data1.flags = PIPELINE_ROUTING_ROUTE_LOCAL |
- PIPELINE_ROUTING_ROUTE_ARP;
- if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ)
- data1.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
- if (p->rp.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) {
- data1.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
- data1.l2.mpls.n_labels = 1;
- }
- data1.port_id = p->rp.port_local_dest;
-
- app_pipeline_routing_add_route(app,
- p->pipeline_id,
- &key1,
- &data1);
- } else {
- /* Local network (directly attached network) */
- if (p->rp.n_arp_entries)
- app_pipeline_routing_delete_route(app,
- p->pipeline_id,
- &key0);
-
- /* Local termination */
- app_pipeline_routing_delete_route(app,
- p->pipeline_id,
- &key1);
- }
-}
-
-static int
-app_pipeline_routing_set_link_op(
- struct app_params *app,
- struct pipeline_routing *p)
-{
- uint32_t port_id;
-
- for (port_id = 0; port_id < p->n_ports_out; port_id++) {
- struct app_link_params *link;
- uint32_t link_id;
- int status;
-
- link = app_pipeline_track_pktq_out_to_link(app,
- p->pipeline_id,
- port_id);
- if (link == NULL)
- continue;
-
- link_id = link - app->link_params;
- p->link_id[port_id] = link_id;
-
- status = app_link_set_op(app,
- link_id,
- p->pipeline_id,
- app_pipeline_routing_link_op,
- (void *) p);
- if (status)
- return status;
- }
-
- return 0;
-}
-
-static void *
-app_pipeline_routing_init(struct pipeline_params *params,
- void *arg)
-{
- struct app_params *app = (struct app_params *) arg;
- struct pipeline_routing *p;
- uint32_t pipeline_id, size;
- int status;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- APP_PARAM_GET_ID(params, "PIPELINE", pipeline_id);
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- if (p == NULL)
- return NULL;
-
- /* Initialization */
- p->app = app;
- p->pipeline_id = pipeline_id;
- p->n_ports_in = params->n_ports_in;
- p->n_ports_out = params->n_ports_out;
-
- status = pipeline_routing_parse_args(&p->rp, params);
- if (status) {
- rte_free(p);
- return NULL;
- }
- TAILQ_INIT(&p->routes);
- p->n_routes = 0;
-
- TAILQ_INIT(&p->arp_entries);
- p->n_arp_entries = 0;
-
- app_pipeline_routing_set_link_op(app, p);
-
- return p;
-}
-
-static int
-app_pipeline_routing_post_init(void *pipeline)
-{
- struct pipeline_routing *p = pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- return app_pipeline_routing_set_macaddr(p->app, p->pipeline_id);
-}
-
-static int
-app_pipeline_routing_free(void *pipeline)
-{
- struct pipeline_routing *p = pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- while (!TAILQ_EMPTY(&p->routes)) {
- struct app_pipeline_routing_route *route;
-
- route = TAILQ_FIRST(&p->routes);
- TAILQ_REMOVE(&p->routes, route, node);
- rte_free(route);
- }
-
- while (!TAILQ_EMPTY(&p->arp_entries)) {
- struct app_pipeline_routing_arp_entry *arp_entry;
-
- arp_entry = TAILQ_FIRST(&p->arp_entries);
- TAILQ_REMOVE(&p->arp_entries, arp_entry, node);
- rte_free(arp_entry);
- }
-
- rte_free(p);
- return 0;
-}
-
-static struct app_pipeline_routing_route *
-app_pipeline_routing_find_route(struct pipeline_routing *p,
- const struct pipeline_routing_route_key *key)
-{
- struct app_pipeline_routing_route *it, *found;
-
- found = NULL;
- TAILQ_FOREACH(it, &p->routes, node) {
- if ((key->type == it->key.type) &&
- (key->key.ipv4.ip == it->key.key.ipv4.ip) &&
- (key->key.ipv4.depth == it->key.key.ipv4.depth)) {
- found = it;
- break;
- }
- }
-
- return found;
-}
-
-static struct app_pipeline_routing_arp_entry *
-app_pipeline_routing_find_arp_entry(struct pipeline_routing *p,
- const struct pipeline_routing_arp_key *key)
-{
- struct app_pipeline_routing_arp_entry *it, *found;
-
- found = NULL;
- TAILQ_FOREACH(it, &p->arp_entries, node) {
- if ((key->type == it->key.type) &&
- (key->key.ipv4.port_id == it->key.key.ipv4.port_id) &&
- (key->key.ipv4.ip == it->key.key.ipv4.ip)) {
- found = it;
- break;
- }
- }
-
- return found;
-}
-
-static void
-print_route(const struct app_pipeline_routing_route *route)
-{
- if (route->key.type == PIPELINE_ROUTING_ROUTE_IPV4) {
- const struct pipeline_routing_route_key_ipv4 *key =
- &route->key.key.ipv4;
-
- printf("IP Prefix = %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32 "/%" PRIu32
- " => (Port = %" PRIu32,
-
- (key->ip >> 24) & 0xFF,
- (key->ip >> 16) & 0xFF,
- (key->ip >> 8) & 0xFF,
- key->ip & 0xFF,
-
- key->depth,
- route->data.port_id);
-
- if (route->data.flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- printf(", Local");
- else if (route->data.flags & PIPELINE_ROUTING_ROUTE_ARP)
- printf(
- ", Next Hop IP = %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32,
-
- (route->data.ethernet.ip >> 24) & 0xFF,
- (route->data.ethernet.ip >> 16) & 0xFF,
- (route->data.ethernet.ip >> 8) & 0xFF,
- route->data.ethernet.ip & 0xFF);
- else
- printf(
- ", Next Hop HWaddress = %02" PRIx32
- ":%02" PRIx32 ":%02" PRIx32
- ":%02" PRIx32 ":%02" PRIx32
- ":%02" PRIx32,
-
- route->data.ethernet.macaddr.addr_bytes[0],
- route->data.ethernet.macaddr.addr_bytes[1],
- route->data.ethernet.macaddr.addr_bytes[2],
- route->data.ethernet.macaddr.addr_bytes[3],
- route->data.ethernet.macaddr.addr_bytes[4],
- route->data.ethernet.macaddr.addr_bytes[5]);
-
- if (route->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)
- printf(", QinQ SVLAN = %" PRIu32 " CVLAN = %" PRIu32,
- route->data.l2.qinq.svlan,
- route->data.l2.qinq.cvlan);
-
- if (route->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) {
- uint32_t i;
-
- printf(", MPLS labels");
- for (i = 0; i < route->data.l2.mpls.n_labels; i++)
- printf(" %" PRIu32,
- route->data.l2.mpls.labels[i]);
- }
-
- printf(")\n");
- }
-}
-
-static void
-print_arp_entry(const struct app_pipeline_routing_arp_entry *entry)
-{
- printf("(Port = %" PRIu32 ", IP = %" PRIu32 ".%" PRIu32
- ".%" PRIu32 ".%" PRIu32
- ") => HWaddress = %02" PRIx32 ":%02" PRIx32 ":%02" PRIx32
- ":%02" PRIx32 ":%02" PRIx32 ":%02" PRIx32 "\n",
-
- entry->key.key.ipv4.port_id,
- (entry->key.key.ipv4.ip >> 24) & 0xFF,
- (entry->key.key.ipv4.ip >> 16) & 0xFF,
- (entry->key.key.ipv4.ip >> 8) & 0xFF,
- entry->key.key.ipv4.ip & 0xFF,
-
- entry->macaddr.addr_bytes[0],
- entry->macaddr.addr_bytes[1],
- entry->macaddr.addr_bytes[2],
- entry->macaddr.addr_bytes[3],
- entry->macaddr.addr_bytes[4],
- entry->macaddr.addr_bytes[5]);
-}
-
-static int
-app_pipeline_routing_route_ls(struct app_params *app, uint32_t pipeline_id)
-{
- struct pipeline_routing *p;
- struct app_pipeline_routing_route *it;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -EINVAL;
-
- TAILQ_FOREACH(it, &p->routes, node)
- print_route(it);
-
- if (p->default_route_present)
- printf("Default route: port %" PRIu32 " (entry ptr = %p)\n",
- p->default_route_port_id,
- p->default_route_entry_ptr);
- else
- printf("Default: DROP\n");
-
- return 0;
-}
-
-int
-app_pipeline_routing_add_route(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_routing_route_key *key,
- struct pipeline_routing_route_data *data)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_route_add_msg_req *req;
- struct pipeline_routing_route_add_msg_rsp *rsp;
-
- struct app_pipeline_routing_route *entry;
-
- int new_entry;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL) ||
- (data == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -1;
-
- switch (key->type) {
- case PIPELINE_ROUTING_ROUTE_IPV4:
- {
- uint32_t depth = key->key.ipv4.depth;
- uint32_t netmask;
-
- /* key */
- if ((depth == 0) || (depth > 32))
- return -1;
-
- netmask = (~0U) << (32 - depth);
- key->key.ipv4.ip &= netmask;
-
- /* data */
- if (data->port_id >= p->n_ports_out)
- return -1;
-
- /* Valid range of VLAN tags 12 bits */
- if (data->flags & PIPELINE_ROUTING_ROUTE_QINQ)
- if ((data->l2.qinq.svlan & 0xF000) ||
- (data->l2.qinq.cvlan & 0xF000))
- return -1;
-
- /* Max number of MPLS labels supported */
- if (data->flags & PIPELINE_ROUTING_ROUTE_MPLS) {
- uint32_t i;
-
- if (data->l2.mpls.n_labels >
- PIPELINE_ROUTING_MPLS_LABELS_MAX)
- return -1;
-
- /* Max MPLS label value 20 bits */
- for (i = 0; i < data->l2.mpls.n_labels; i++)
- if (data->l2.mpls.labels[i] & 0xFFF00000)
- return -1;
- }
- }
- break;
-
- default:
- return -1;
- }
-
- /* Find existing rule or allocate new rule */
- entry = app_pipeline_routing_find_route(p, key);
- new_entry = (entry == NULL);
- if (entry == NULL) {
- entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
-
- if (entry == NULL)
- return -1;
- }
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL) {
- if (new_entry)
- rte_free(entry);
- return -1;
- }
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD;
- memcpy(&req->key, key, sizeof(*key));
- memcpy(&req->data, data, sizeof(*data));
-
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL) {
- if (new_entry)
- rte_free(entry);
- return -1;
- }
-
- /* Read response and write entry */
- if (rsp->status ||
- (rsp->entry_ptr == NULL) ||
- ((new_entry == 0) && (rsp->key_found == 0)) ||
- ((new_entry == 1) && (rsp->key_found == 1))) {
- app_msg_free(app, rsp);
- if (new_entry)
- rte_free(entry);
- return -1;
- }
-
- memcpy(&entry->key, key, sizeof(*key));
- memcpy(&entry->data, data, sizeof(*data));
- entry->entry_ptr = rsp->entry_ptr;
-
- /* Commit entry */
- if (new_entry) {
- TAILQ_INSERT_TAIL(&p->routes, entry, node);
- p->n_routes++;
- }
-
- /* Message buffer free */
- app_msg_free(app, rsp);
- return 0;
-}
-
-int
-app_pipeline_routing_delete_route(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_routing_route_key *key)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_route_delete_msg_req *req;
- struct pipeline_routing_route_delete_msg_rsp *rsp;
-
- struct app_pipeline_routing_route *entry;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -1;
-
- switch (key->type) {
- case PIPELINE_ROUTING_ROUTE_IPV4:
- {
- uint32_t depth = key->key.ipv4.depth;
- uint32_t netmask;
-
- /* key */
- if ((depth == 0) || (depth > 32))
- return -1;
-
- netmask = (~0U) << (32 - depth);
- key->key.ipv4.ip &= netmask;
- }
- break;
-
- default:
- return -1;
- }
-
- /* Find rule */
- entry = app_pipeline_routing_find_route(p, key);
- if (entry == NULL)
- return 0;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL;
- memcpy(&req->key, key, sizeof(*key));
-
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status || !rsp->key_found) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Remove route */
- TAILQ_REMOVE(&p->routes, entry, node);
- p->n_routes--;
- rte_free(entry);
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_routing_add_default_route(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_route_add_default_msg_req *req;
- struct pipeline_routing_route_add_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -1;
-
- if (port_id >= p->n_ports_out)
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT;
- req->port_id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response and write route */
- if (rsp->status || (rsp->entry_ptr == NULL)) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- p->default_route_port_id = port_id;
- p->default_route_entry_ptr = rsp->entry_ptr;
-
- /* Commit route */
- p->default_route_present = 1;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_routing_delete_default_route(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_arp_delete_default_msg_req *req;
- struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response and write route */
- if (rsp->status) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Commit route */
- p->default_route_present = 0;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-static int
-app_pipeline_routing_arp_ls(struct app_params *app, uint32_t pipeline_id)
-{
- struct pipeline_routing *p;
- struct app_pipeline_routing_arp_entry *it;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -EINVAL;
-
- TAILQ_FOREACH(it, &p->arp_entries, node)
- print_arp_entry(it);
-
- if (p->default_arp_entry_present)
- printf("Default entry: port %" PRIu32 " (entry ptr = %p)\n",
- p->default_arp_entry_port_id,
- p->default_arp_entry_ptr);
- else
- printf("Default: DROP\n");
-
- return 0;
-}
-
-int
-app_pipeline_routing_add_arp_entry(struct app_params *app, uint32_t pipeline_id,
- struct pipeline_routing_arp_key *key,
- struct ether_addr *macaddr)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_arp_add_msg_req *req;
- struct pipeline_routing_arp_add_msg_rsp *rsp;
-
- struct app_pipeline_routing_arp_entry *entry;
-
- int new_entry;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL) ||
- (macaddr == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -1;
-
- switch (key->type) {
- case PIPELINE_ROUTING_ARP_IPV4:
- {
- uint32_t port_id = key->key.ipv4.port_id;
-
- /* key */
- if (port_id >= p->n_ports_out)
- return -1;
- }
- break;
-
- default:
- return -1;
- }
-
- /* Find existing entry or allocate new */
- entry = app_pipeline_routing_find_arp_entry(p, key);
- new_entry = (entry == NULL);
- if (entry == NULL) {
- entry = rte_malloc(NULL, sizeof(*entry), RTE_CACHE_LINE_SIZE);
-
- if (entry == NULL)
- return -1;
- }
-
- /* Message buffer allocation */
- req = app_msg_alloc(app);
- if (req == NULL) {
- if (new_entry)
- rte_free(entry);
- return -1;
- }
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD;
- memcpy(&req->key, key, sizeof(*key));
- ether_addr_copy(macaddr, &req->macaddr);
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL) {
- if (new_entry)
- rte_free(entry);
- return -1;
- }
-
- /* Read response and write entry */
- if (rsp->status ||
- (rsp->entry_ptr == NULL) ||
- ((new_entry == 0) && (rsp->key_found == 0)) ||
- ((new_entry == 1) && (rsp->key_found == 1))) {
- app_msg_free(app, rsp);
- if (new_entry)
- rte_free(entry);
- return -1;
- }
-
- memcpy(&entry->key, key, sizeof(*key));
- ether_addr_copy(macaddr, &entry->macaddr);
- entry->entry_ptr = rsp->entry_ptr;
-
- /* Commit entry */
- if (new_entry) {
- TAILQ_INSERT_TAIL(&p->arp_entries, entry, node);
- p->n_arp_entries++;
- }
-
- /* Message buffer free */
- app_msg_free(app, rsp);
- return 0;
-}
-
-int
-app_pipeline_routing_delete_arp_entry(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_routing_arp_key *key)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_arp_delete_msg_req *req;
- struct pipeline_routing_arp_delete_msg_rsp *rsp;
-
- struct app_pipeline_routing_arp_entry *entry;
-
- /* Check input arguments */
- if ((app == NULL) ||
- (key == NULL))
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -EINVAL;
-
- switch (key->type) {
- case PIPELINE_ROUTING_ARP_IPV4:
- {
- uint32_t port_id = key->key.ipv4.port_id;
-
- /* key */
- if (port_id >= p->n_ports_out)
- return -1;
- }
- break;
-
- default:
- return -1;
- }
-
- /* Find rule */
- entry = app_pipeline_routing_find_arp_entry(p, key);
- if (entry == NULL)
- return 0;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL;
- memcpy(&req->key, key, sizeof(*key));
-
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response */
- if (rsp->status || !rsp->key_found) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- /* Remove entry */
- TAILQ_REMOVE(&p->arp_entries, entry, node);
- p->n_arp_entries--;
- rte_free(entry);
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_routing_add_default_arp_entry(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_arp_add_default_msg_req *req;
- struct pipeline_routing_arp_add_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -1;
-
- if (port_id >= p->n_ports_out)
- return -1;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT;
- req->port_id = port_id;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- /* Read response and write entry */
- if (rsp->status || rsp->entry_ptr == NULL) {
- app_msg_free(app, rsp);
- return -1;
- }
-
- p->default_arp_entry_port_id = port_id;
- p->default_arp_entry_ptr = rsp->entry_ptr;
-
- /* Commit entry */
- p->default_arp_entry_present = 1;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct pipeline_routing *p;
-
- struct pipeline_routing_arp_delete_default_msg_req *req;
- struct pipeline_routing_arp_delete_default_msg_rsp *rsp;
-
- /* Check input arguments */
- if (app == NULL)
- return -1;
-
- p = app_pipeline_data_fe(app, pipeline_id, &pipeline_routing);
- if (p == NULL)
- return -EINVAL;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -ENOMEM;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT;
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -ETIMEDOUT;
-
- /* Read response and write entry */
- if (rsp->status) {
- app_msg_free(app, rsp);
- return rsp->status;
- }
-
- /* Commit entry */
- p->default_arp_entry_present = 0;
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-int
-app_pipeline_routing_set_macaddr(struct app_params *app,
- uint32_t pipeline_id)
-{
- struct app_pipeline_params *p;
- struct pipeline_routing_set_macaddr_msg_req *req;
- struct pipeline_routing_set_macaddr_msg_rsp *rsp;
- uint32_t port_id;
-
- /* Check input arguments */
- if (app == NULL)
- return -EINVAL;
-
- APP_PARAM_FIND_BY_ID(app->pipeline_params, "PIPELINE", pipeline_id, p);
- if (p == NULL)
- return -EINVAL;
-
- /* Allocate and write request */
- req = app_msg_alloc(app);
- if (req == NULL)
- return -ENOMEM;
-
- req->type = PIPELINE_MSG_REQ_CUSTOM;
- req->subtype = PIPELINE_ROUTING_MSG_REQ_SET_MACADDR;
-
- memset(req->macaddr, 0, sizeof(req->macaddr));
- for (port_id = 0; port_id < p->n_pktq_out; port_id++) {
- struct app_link_params *link;
-
- link = app_pipeline_track_pktq_out_to_link(app,
- pipeline_id,
- port_id);
- if (link)
- req->macaddr[port_id] = link->mac_addr;
- }
-
- /* Send request and wait for response */
- rsp = app_msg_send_recv(app, pipeline_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -ETIMEDOUT;
-
- /* Read response and write entry */
- if (rsp->status) {
- app_msg_free(app, rsp);
- return rsp->status;
- }
-
- /* Free response */
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-/*
- * route
- *
- * route add (ARP = ON/OFF, MPLS = ON/OFF, QINQ = ON/OFF):
- * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr>
- * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr>
- * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> qinq <svlan> <cvlan>
- * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> qinq <svlan> <cvlan>
- * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhmacaddr> mpls <mpls labels>
- * p <pipelineid> route add <ipaddr> <depth> port <portid> ether <nhipaddr> mpls <mpls labels>
- *
- * route add default:
- * p <pipelineid> route add default <portid>
- *
- * route del:
- * p <pipelineid> route del <ipaddr> <depth>
- *
- * route del default:
- * p <pipelineid> route del default
- *
- * route ls:
- * p <pipelineid> route ls
- */
-
-struct cmd_route_result {
- cmdline_fixed_string_t p_string;
- uint32_t p;
- cmdline_fixed_string_t route_string;
- cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_route_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_route_result *params = parsed_result;
- struct app_params *app = data;
-
- char *tokens[16];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
- if (status != 0) {
- printf(CMD_MSG_TOO_MANY_ARGS, "route");
- return;
- }
-
- /* route add */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- strcmp(tokens[1], "default")) {
- struct pipeline_routing_route_key key;
- struct pipeline_routing_route_data route_data;
- struct in_addr ipv4, nh_ipv4;
- struct ether_addr mac_addr;
- uint32_t depth, port_id, svlan, cvlan, i;
- uint32_t mpls_labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
- uint32_t n_labels = RTE_DIM(mpls_labels);
-
- memset(&key, 0, sizeof(key));
- memset(&route_data, 0, sizeof(route_data));
-
- if (n_tokens < 7) {
- printf(CMD_MSG_NOT_ENOUGH_ARGS, "route add");
- return;
- }
-
- if (parse_ipv4_addr(tokens[1], &ipv4)) {
- printf(CMD_MSG_INVALID_ARG, "ipaddr");
- return;
- }
-
- if (parser_read_uint32(&depth, tokens[2])) {
- printf(CMD_MSG_INVALID_ARG, "depth");
- return;
- }
-
- if (strcmp(tokens[3], "port")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "port");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[4])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- if (strcmp(tokens[5], "ether")) {
- printf(CMD_MSG_ARG_NOT_FOUND, "ether");
- return;
- }
-
- if (parse_mac_addr(tokens[6], &mac_addr)) {
- if (parse_ipv4_addr(tokens[6], &nh_ipv4)) {
- printf(CMD_MSG_INVALID_ARG, "nhmacaddr or nhipaddr");
- return;
- }
-
- route_data.flags |= PIPELINE_ROUTING_ROUTE_ARP;
- }
-
- if (n_tokens > 7) {
- if (strcmp(tokens[7], "mpls") == 0) {
- if (n_tokens != 9) {
- printf(CMD_MSG_MISMATCH_ARGS, "route add mpls");
- return;
- }
-
- if (parse_mpls_labels(tokens[8], mpls_labels, &n_labels)) {
- printf(CMD_MSG_INVALID_ARG, "mpls labels");
- return;
- }
-
- route_data.flags |= PIPELINE_ROUTING_ROUTE_MPLS;
- } else if (strcmp(tokens[7], "qinq") == 0) {
- if (n_tokens != 10) {
- printf(CMD_MSG_MISMATCH_ARGS, "route add qinq");
- return;
- }
-
- if (parser_read_uint32(&svlan, tokens[8])) {
- printf(CMD_MSG_INVALID_ARG, "svlan");
- return;
- }
- if (parser_read_uint32(&cvlan, tokens[9])) {
- printf(CMD_MSG_INVALID_ARG, "cvlan");
- return;
- }
-
- route_data.flags |= PIPELINE_ROUTING_ROUTE_QINQ;
- } else {
- printf(CMD_MSG_ARG_NOT_FOUND, "mpls or qinq");
- return;
- }
- }
-
- switch (route_data.flags) {
- case 0:
- route_data.port_id = port_id;
- route_data.ethernet.macaddr = mac_addr;
- break;
-
- case PIPELINE_ROUTING_ROUTE_ARP:
- route_data.port_id = port_id;
- route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
- break;
-
- case PIPELINE_ROUTING_ROUTE_MPLS:
- route_data.port_id = port_id;
- route_data.ethernet.macaddr = mac_addr;
- for (i = 0; i < n_labels; i++)
- route_data.l2.mpls.labels[i] = mpls_labels[i];
- route_data.l2.mpls.n_labels = n_labels;
- break;
-
- case PIPELINE_ROUTING_ROUTE_MPLS | PIPELINE_ROUTING_ROUTE_ARP:
- route_data.port_id = port_id;
- route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
- for (i = 0; i < n_labels; i++)
- route_data.l2.mpls.labels[i] = mpls_labels[i];
- route_data.l2.mpls.n_labels = n_labels;
- break;
-
- case PIPELINE_ROUTING_ROUTE_QINQ:
- route_data.port_id = port_id;
- route_data.ethernet.macaddr = mac_addr;
- route_data.l2.qinq.svlan = svlan;
- route_data.l2.qinq.cvlan = cvlan;
- break;
-
- case PIPELINE_ROUTING_ROUTE_QINQ | PIPELINE_ROUTING_ROUTE_ARP:
- default:
- route_data.port_id = port_id;
- route_data.ethernet.ip = rte_be_to_cpu_32(nh_ipv4.s_addr);
- route_data.l2.qinq.svlan = svlan;
- route_data.l2.qinq.cvlan = cvlan;
- break;
- }
-
- key.type = PIPELINE_ROUTING_ROUTE_IPV4;
- key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
- key.key.ipv4.depth = depth;
-
- status = app_pipeline_routing_add_route(app,
- params->p,
- &key,
- &route_data);
- if (status != 0)
- printf(CMD_MSG_FAIL, "route add");
-
- return;
- } /* route add */
-
- /* route add default */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- uint32_t port_id;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "route add default");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[2])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- status = app_pipeline_routing_add_default_route(app,
- params->p,
- port_id);
- if (status != 0)
- printf(CMD_MSG_FAIL, "route add default");
-
- return;
- } /* route add default */
-
- /* route del*/
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- strcmp(tokens[1], "default")) {
- struct pipeline_routing_route_key key;
- struct in_addr ipv4;
- uint32_t depth;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "route del");
- return;
- }
-
- if (parse_ipv4_addr(tokens[1], &ipv4)) {
- printf(CMD_MSG_INVALID_ARG, "ipaddr");
- return;
- }
-
- if (parser_read_uint32(&depth, tokens[2])) {
- printf(CMD_MSG_INVALID_ARG, "depth");
- return;
- }
-
- key.type = PIPELINE_ROUTING_ROUTE_IPV4;
- key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
- key.key.ipv4.depth = depth;
-
- status = app_pipeline_routing_delete_route(app, params->p, &key);
- if (status != 0)
- printf(CMD_MSG_FAIL, "route del");
-
- return;
- } /* route del */
-
- /* route del default */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "route del default");
- return;
- }
-
- status = app_pipeline_routing_delete_default_route(app,
- params->p);
- if (status != 0)
- printf(CMD_MSG_FAIL, "route del default");
-
- return;
- } /* route del default */
-
- /* route ls */
- if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
- if (n_tokens != 1) {
- printf(CMD_MSG_MISMATCH_ARGS, "route ls");
- return;
- }
-
- status = app_pipeline_routing_route_ls(app, params->p);
- if (status != 0)
- printf(CMD_MSG_FAIL, "route ls");
-
- return;
- } /* route ls */
-
- printf(CMD_MSG_MISMATCH_ARGS, "route");
-}
-
-static cmdline_parse_token_string_t cmd_route_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_route_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_route_p =
- TOKEN_NUM_INITIALIZER(struct cmd_route_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_route_route_string =
- TOKEN_STRING_INITIALIZER(struct cmd_route_result, route_string, "route");
-
-static cmdline_parse_token_string_t cmd_route_multi_string =
- TOKEN_STRING_INITIALIZER(struct cmd_route_result, multi_string,
- TOKEN_STRING_MULTI);
-
-static cmdline_parse_inst_t cmd_route = {
- .f = cmd_route_parsed,
- .data = NULL,
- .help_str = "route add / add default / del / del default / ls",
- .tokens = {
- (void *)&cmd_route_p_string,
- (void *)&cmd_route_p,
- (void *)&cmd_route_route_string,
- (void *)&cmd_route_multi_string,
- NULL,
- },
-};
-
-/*
- * arp
- *
- * arp add:
- * p <pipelineid> arp add <portid> <ipaddr> <macaddr>
- *
- * arp add default:
- * p <pipelineid> arp add default <portid>
- *
- * arp del:
- * p <pipelineid> arp del <portid> <ipaddr>
- *
- * arp del default:
- * p <pipelineid> arp del default
- *
- * arp ls:
- * p <pipelineid> arp ls
- */
-
-struct cmd_arp_result {
- cmdline_fixed_string_t p_string;
- uint32_t p;
- cmdline_fixed_string_t arp_string;
- cmdline_multi_string_t multi_string;
-};
-
-static void
-cmd_arp_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_arp_result *params = parsed_result;
- struct app_params *app = data;
-
- char *tokens[16];
- uint32_t n_tokens = RTE_DIM(tokens);
- int status;
-
- status = parse_tokenize_string(params->multi_string, tokens, &n_tokens);
- if (status != 0) {
- printf(CMD_MSG_TOO_MANY_ARGS, "arp");
- return;
- }
-
- /* arp add */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- strcmp(tokens[1], "default")) {
- struct pipeline_routing_arp_key key;
- struct in_addr ipv4;
- struct ether_addr mac_addr;
- uint32_t port_id;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 4) {
- printf(CMD_MSG_MISMATCH_ARGS, "arp add");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[1])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- if (parse_ipv4_addr(tokens[2], &ipv4)) {
- printf(CMD_MSG_INVALID_ARG, "ipaddr");
- return;
- }
-
- if (parse_mac_addr(tokens[3], &mac_addr)) {
- printf(CMD_MSG_INVALID_ARG, "macaddr");
- return;
- }
-
- key.type = PIPELINE_ROUTING_ARP_IPV4;
- key.key.ipv4.port_id = port_id;
- key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
-
- status = app_pipeline_routing_add_arp_entry(app,
- params->p,
- &key,
- &mac_addr);
- if (status != 0)
- printf(CMD_MSG_FAIL, "arp add");
-
- return;
- } /* arp add */
-
- /* arp add default */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "add") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- uint32_t port_id;
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "arp add default");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[2])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- status = app_pipeline_routing_add_default_arp_entry(app,
- params->p,
- port_id);
- if (status != 0)
- printf(CMD_MSG_FAIL, "arp add default");
-
- return;
- } /* arp add default */
-
- /* arp del*/
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- strcmp(tokens[1], "default")) {
- struct pipeline_routing_arp_key key;
- struct in_addr ipv4;
- uint32_t port_id;
-
- memset(&key, 0, sizeof(key));
-
- if (n_tokens != 3) {
- printf(CMD_MSG_MISMATCH_ARGS, "arp del");
- return;
- }
-
- if (parser_read_uint32(&port_id, tokens[1])) {
- printf(CMD_MSG_INVALID_ARG, "portid");
- return;
- }
-
- if (parse_ipv4_addr(tokens[2], &ipv4)) {
- printf(CMD_MSG_INVALID_ARG, "ipaddr");
- return;
- }
-
- key.type = PIPELINE_ROUTING_ARP_IPV4;
- key.key.ipv4.ip = rte_be_to_cpu_32(ipv4.s_addr);
- key.key.ipv4.port_id = port_id;
-
- status = app_pipeline_routing_delete_arp_entry(app,
- params->p,
- &key);
- if (status != 0)
- printf(CMD_MSG_FAIL, "arp del");
-
- return;
- } /* arp del */
-
- /* arp del default */
- if ((n_tokens >= 2) &&
- (strcmp(tokens[0], "del") == 0) &&
- (strcmp(tokens[1], "default") == 0)) {
- if (n_tokens != 2) {
- printf(CMD_MSG_MISMATCH_ARGS, "arp del default");
- return;
- }
-
- status = app_pipeline_routing_delete_default_arp_entry(app,
- params->p);
- if (status != 0)
- printf(CMD_MSG_FAIL, "arp del default");
-
- return;
- } /* arp del default */
-
- /* arp ls */
- if ((n_tokens >= 1) && (strcmp(tokens[0], "ls") == 0)) {
- if (n_tokens != 1) {
- printf(CMD_MSG_MISMATCH_ARGS, "arp ls");
- return;
- }
-
- status = app_pipeline_routing_arp_ls(app, params->p);
- if (status != 0)
- printf(CMD_MSG_FAIL, "arp ls");
-
- return;
- } /* arp ls */
-
- printf(CMD_MSG_FAIL, "arp");
-}
-
-static cmdline_parse_token_string_t cmd_arp_p_string =
- TOKEN_STRING_INITIALIZER(struct cmd_arp_result, p_string, "p");
-
-static cmdline_parse_token_num_t cmd_arp_p =
- TOKEN_NUM_INITIALIZER(struct cmd_arp_result, p, UINT32);
-
-static cmdline_parse_token_string_t cmd_arp_arp_string =
- TOKEN_STRING_INITIALIZER(struct cmd_arp_result, arp_string, "arp");
-
-static cmdline_parse_token_string_t cmd_arp_multi_string =
- TOKEN_STRING_INITIALIZER(struct cmd_arp_result, multi_string,
- TOKEN_STRING_MULTI);
-
-static cmdline_parse_inst_t cmd_arp = {
- .f = cmd_arp_parsed,
- .data = NULL,
- .help_str = "arp add / add default / del / del default / ls",
- .tokens = {
- (void *)&cmd_arp_p_string,
- (void *)&cmd_arp_p,
- (void *)&cmd_arp_arp_string,
- (void *)&cmd_arp_multi_string,
- NULL,
- },
-};
-
-static cmdline_parse_ctx_t pipeline_cmds[] = {
- (cmdline_parse_inst_t *)&cmd_route,
- (cmdline_parse_inst_t *)&cmd_arp,
- NULL,
-};
-
-static struct pipeline_fe_ops pipeline_routing_fe_ops = {
- .f_init = app_pipeline_routing_init,
- .f_post_init = app_pipeline_routing_post_init,
- .f_free = app_pipeline_routing_free,
- .f_track = app_pipeline_track_default,
- .cmds = pipeline_cmds,
-};
-
-struct pipeline_type pipeline_routing = {
- .name = "ROUTING",
- .be_ops = &pipeline_routing_be_ops,
- .fe_ops = &pipeline_routing_fe_ops,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing.h b/examples/ip_pipeline/pipeline/pipeline_routing.h
deleted file mode 100644
index f2492957..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_routing.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_ROUTING_H__
-#define __INCLUDE_PIPELINE_ROUTING_H__
-
-#include "pipeline.h"
-#include "pipeline_routing_be.h"
-
-/*
- * Route
- */
-
-int
-app_pipeline_routing_add_route(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_routing_route_key *key,
- struct pipeline_routing_route_data *data);
-
-int
-app_pipeline_routing_delete_route(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_routing_route_key *key);
-
-int
-app_pipeline_routing_add_default_route(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id);
-
-int
-app_pipeline_routing_delete_default_route(struct app_params *app,
- uint32_t pipeline_id);
-
-/*
- * ARP
- */
-
-int
-app_pipeline_routing_add_arp_entry(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_routing_arp_key *key,
- struct ether_addr *macaddr);
-
-int
-app_pipeline_routing_delete_arp_entry(struct app_params *app,
- uint32_t pipeline_id,
- struct pipeline_routing_arp_key *key);
-
-int
-app_pipeline_routing_add_default_arp_entry(struct app_params *app,
- uint32_t pipeline_id,
- uint32_t port_id);
-
-int
-app_pipeline_routing_delete_default_arp_entry(struct app_params *app,
- uint32_t pipeline_id);
-
-/*
- * SETTINGS
- */
-int
-app_pipeline_routing_set_macaddr(struct app_params *app,
- uint32_t pipeline_id);
-
-/*
- * Pipeline type
- */
-extern struct pipeline_type pipeline_routing;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.c b/examples/ip_pipeline/pipeline/pipeline_routing_be.c
deleted file mode 100644
index 6258a1a9..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.c
+++ /dev/null
@@ -1,1966 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <rte_common.h>
-#include <rte_malloc.h>
-#include <rte_ip.h>
-#include <rte_byteorder.h>
-#include <rte_table_lpm.h>
-#include <rte_table_hash.h>
-#include <rte_pipeline.h>
-
-#include "pipeline_routing_be.h"
-#include "pipeline_actions_common.h"
-#include "parser.h"
-#include "hash_func.h"
-
-#define MPLS_LABEL(label, exp, s, ttl) \
- (((((uint64_t) (label)) & 0xFFFFFLLU) << 12) | \
- ((((uint64_t) (exp)) & 0x7LLU) << 9) | \
- ((((uint64_t) (s)) & 0x1LLU) << 8) | \
- (((uint64_t) (ttl)) & 0xFFLU))
-
-#define RTE_SCHED_PORT_HIERARCHY(subport, pipe, \
- traffic_class, queue, color) \
- ((((uint64_t) (queue)) & 0x3) | \
- ((((uint64_t) (traffic_class)) & 0x3) << 2) | \
- ((((uint64_t) (color)) & 0x3) << 4) | \
- ((((uint64_t) (subport)) & 0xFFFF) << 16) | \
- ((((uint64_t) (pipe)) & 0xFFFFFFFF) << 32))
-
-
-/* Network Byte Order (NBO) */
-#define SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr, ethertype) \
- (((uint64_t) macaddr) | (((uint64_t) rte_cpu_to_be_16(ethertype)) << 48))
-
-#ifndef PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s
-#define PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s 256
-#endif
-
-struct pipeline_routing {
- struct pipeline p;
- struct pipeline_routing_params params;
- pipeline_msg_req_handler custom_handlers[PIPELINE_ROUTING_MSG_REQS];
- uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
-} __rte_cache_aligned;
-
-/*
- * Message handlers
- */
-static void *
-pipeline_routing_msg_req_custom_handler(struct pipeline *p, void *msg);
-
-static pipeline_msg_req_handler handlers[] = {
- [PIPELINE_MSG_REQ_PING] =
- pipeline_msg_req_ping_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_IN] =
- pipeline_msg_req_stats_port_in_handler,
- [PIPELINE_MSG_REQ_STATS_PORT_OUT] =
- pipeline_msg_req_stats_port_out_handler,
- [PIPELINE_MSG_REQ_STATS_TABLE] =
- pipeline_msg_req_stats_table_handler,
- [PIPELINE_MSG_REQ_PORT_IN_ENABLE] =
- pipeline_msg_req_port_in_enable_handler,
- [PIPELINE_MSG_REQ_PORT_IN_DISABLE] =
- pipeline_msg_req_port_in_disable_handler,
- [PIPELINE_MSG_REQ_CUSTOM] =
- pipeline_routing_msg_req_custom_handler,
-};
-
-static void *
-pipeline_routing_msg_req_route_add_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_route_del_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_route_add_default_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_route_del_default_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_add_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_del_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_add_default_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p,
- void *msg);
-
-static void *
-pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p,
- void *msg);
-
-static pipeline_msg_req_handler custom_handlers[] = {
- [PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD] =
- pipeline_routing_msg_req_route_add_handler,
- [PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL] =
- pipeline_routing_msg_req_route_del_handler,
- [PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT] =
- pipeline_routing_msg_req_route_add_default_handler,
- [PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT] =
- pipeline_routing_msg_req_route_del_default_handler,
- [PIPELINE_ROUTING_MSG_REQ_ARP_ADD] =
- pipeline_routing_msg_req_arp_add_handler,
- [PIPELINE_ROUTING_MSG_REQ_ARP_DEL] =
- pipeline_routing_msg_req_arp_del_handler,
- [PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT] =
- pipeline_routing_msg_req_arp_add_default_handler,
- [PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT] =
- pipeline_routing_msg_req_arp_del_default_handler,
- [PIPELINE_ROUTING_MSG_REQ_SET_MACADDR] =
- pipeline_routing_msg_req_set_macaddr_handler,
-};
-
-/*
- * Routing table
- */
-struct routing_table_entry {
- struct rte_pipeline_table_entry head;
- uint32_t flags;
- uint32_t port_id; /* Output port ID */
- uint32_t ip; /* Next hop IP address (only valid for remote routes) */
-
- /* ether_l2 */
- uint16_t data_offset;
- uint16_t ether_l2_length;
- uint64_t slab[4];
- uint16_t slab_offset[4];
-};
-
-struct layout {
- uint16_t a;
- uint32_t b;
- uint16_t c;
-} __attribute__((__packed__));
-
-#define MACADDR_DST_WRITE(slab_ptr, slab) \
-{ \
- struct layout *dst = (struct layout *) (slab_ptr); \
- struct layout *src = (struct layout *) &(slab); \
- \
- dst->b = src->b; \
- dst->c = src->c; \
-}
-
-static __rte_always_inline void
-pkt_work_routing(
- struct rte_mbuf *pkt,
- struct rte_pipeline_table_entry *table_entry,
- void *arg,
- int arp,
- int qinq,
- int qinq_sched,
- int mpls,
- int mpls_color_mark)
-{
- struct pipeline_routing *p_rt = arg;
-
- struct routing_table_entry *entry =
- (struct routing_table_entry *) table_entry;
-
- struct ipv4_hdr *ip = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p_rt->params.ip_hdr_offset);
-
- enum rte_meter_color pkt_color = (enum rte_meter_color)
- RTE_MBUF_METADATA_UINT32(pkt, p_rt->params.color_offset);
-
- struct pipeline_routing_arp_key_ipv4 *arp_key =
- (struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkt, p_rt->params.arp_key_offset);
-
- uint64_t *slab0_ptr, *slab1_ptr, *slab2_ptr, *slab3_ptr, sched;
- uint32_t ip_da, nh_ip, port_id;
- uint16_t total_length, data_offset, ether_l2_length;
-
- /* Read */
- total_length = rte_bswap16(ip->total_length);
- ip_da = ip->dst_addr;
- data_offset = entry->data_offset;
- ether_l2_length = entry->ether_l2_length;
- slab0_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[0]);
- slab1_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[1]);
- slab2_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[2]);
- slab3_ptr = RTE_MBUF_METADATA_UINT64_PTR(pkt, entry->slab_offset[3]);
-
- if (arp) {
- port_id = entry->port_id;
- nh_ip = entry->ip;
- if (entry->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- nh_ip = ip_da;
- }
-
- /* Compute */
- total_length += ether_l2_length;
-
- if (qinq && qinq_sched) {
- uint32_t dscp = ip->type_of_service >> 2;
- uint32_t svlan, cvlan, tc, tc_q;
-
- if (qinq_sched == 1) {
- uint64_t slab_qinq = rte_bswap64(entry->slab[0]);
-
- svlan = (slab_qinq >> 48) & 0xFFF;
- cvlan = (slab_qinq >> 16) & 0xFFF;
- tc = (dscp >> 2) & 0x3;
- tc_q = dscp & 0x3;
- } else {
- uint32_t ip_src = rte_bswap32(ip->src_addr);
-
- svlan = 0;
- cvlan = (ip_src >> 16) & 0xFFF;
- tc = (ip_src >> 2) & 0x3;
- tc_q = ip_src & 0x3;
- }
- sched = RTE_SCHED_PORT_HIERARCHY(svlan,
- cvlan,
- tc,
- tc_q,
- e_RTE_METER_GREEN);
- }
-
- /* Write */
- pkt->data_off = data_offset;
- pkt->data_len = total_length;
- pkt->pkt_len = total_length;
-
- if ((qinq == 0) && (mpls == 0)) {
- *slab0_ptr = entry->slab[0];
-
- if (arp == 0)
- MACADDR_DST_WRITE(slab1_ptr, entry->slab[1]);
- }
-
- if (qinq) {
- *slab0_ptr = entry->slab[0];
- *slab1_ptr = entry->slab[1];
-
- if (arp == 0)
- MACADDR_DST_WRITE(slab2_ptr, entry->slab[2]);
-
- if (qinq_sched) {
- pkt->hash.sched.lo = sched & 0xFFFFFFFF;
- pkt->hash.sched.hi = sched >> 32;
- }
- }
-
- if (mpls) {
- if (mpls_color_mark) {
- uint64_t mpls_exp = rte_bswap64(
- (MPLS_LABEL(0, pkt_color, 0, 0) << 32) |
- MPLS_LABEL(0, pkt_color, 0, 0));
-
- *slab0_ptr = entry->slab[0] | mpls_exp;
- *slab1_ptr = entry->slab[1] | mpls_exp;
- *slab2_ptr = entry->slab[2];
- } else {
- *slab0_ptr = entry->slab[0];
- *slab1_ptr = entry->slab[1];
- *slab2_ptr = entry->slab[2];
- }
-
- if (arp == 0)
- MACADDR_DST_WRITE(slab3_ptr, entry->slab[3]);
- }
-
- if (arp) {
- arp_key->port_id = port_id;
- arp_key->ip = nh_ip;
- }
-}
-
-static __rte_always_inline void
-pkt4_work_routing(
- struct rte_mbuf **pkts,
- struct rte_pipeline_table_entry **table_entries,
- void *arg,
- int arp,
- int qinq,
- int qinq_sched,
- int mpls,
- int mpls_color_mark)
-{
- struct pipeline_routing *p_rt = arg;
-
- struct routing_table_entry *entry0 =
- (struct routing_table_entry *) table_entries[0];
- struct routing_table_entry *entry1 =
- (struct routing_table_entry *) table_entries[1];
- struct routing_table_entry *entry2 =
- (struct routing_table_entry *) table_entries[2];
- struct routing_table_entry *entry3 =
- (struct routing_table_entry *) table_entries[3];
-
- struct ipv4_hdr *ip0 = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[0],
- p_rt->params.ip_hdr_offset);
- struct ipv4_hdr *ip1 = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[1],
- p_rt->params.ip_hdr_offset);
- struct ipv4_hdr *ip2 = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[2],
- p_rt->params.ip_hdr_offset);
- struct ipv4_hdr *ip3 = (struct ipv4_hdr *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[3],
- p_rt->params.ip_hdr_offset);
-
- enum rte_meter_color pkt0_color = (enum rte_meter_color)
- RTE_MBUF_METADATA_UINT32(pkts[0], p_rt->params.color_offset);
- enum rte_meter_color pkt1_color = (enum rte_meter_color)
- RTE_MBUF_METADATA_UINT32(pkts[1], p_rt->params.color_offset);
- enum rte_meter_color pkt2_color = (enum rte_meter_color)
- RTE_MBUF_METADATA_UINT32(pkts[2], p_rt->params.color_offset);
- enum rte_meter_color pkt3_color = (enum rte_meter_color)
- RTE_MBUF_METADATA_UINT32(pkts[3], p_rt->params.color_offset);
-
- struct pipeline_routing_arp_key_ipv4 *arp_key0 =
- (struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[0],
- p_rt->params.arp_key_offset);
- struct pipeline_routing_arp_key_ipv4 *arp_key1 =
- (struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[1],
- p_rt->params.arp_key_offset);
- struct pipeline_routing_arp_key_ipv4 *arp_key2 =
- (struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[2],
- p_rt->params.arp_key_offset);
- struct pipeline_routing_arp_key_ipv4 *arp_key3 =
- (struct pipeline_routing_arp_key_ipv4 *)
- RTE_MBUF_METADATA_UINT8_PTR(pkts[3],
- p_rt->params.arp_key_offset);
-
- uint64_t *slab0_ptr0, *slab1_ptr0, *slab2_ptr0, *slab3_ptr0;
- uint64_t *slab0_ptr1, *slab1_ptr1, *slab2_ptr1, *slab3_ptr1;
- uint64_t *slab0_ptr2, *slab1_ptr2, *slab2_ptr2, *slab3_ptr2;
- uint64_t *slab0_ptr3, *slab1_ptr3, *slab2_ptr3, *slab3_ptr3;
- uint64_t sched0, sched1, sched2, sched3;
-
- uint32_t ip_da0, nh_ip0, port_id0;
- uint32_t ip_da1, nh_ip1, port_id1;
- uint32_t ip_da2, nh_ip2, port_id2;
- uint32_t ip_da3, nh_ip3, port_id3;
-
- uint16_t total_length0, data_offset0, ether_l2_length0;
- uint16_t total_length1, data_offset1, ether_l2_length1;
- uint16_t total_length2, data_offset2, ether_l2_length2;
- uint16_t total_length3, data_offset3, ether_l2_length3;
-
- /* Read */
- total_length0 = rte_bswap16(ip0->total_length);
- total_length1 = rte_bswap16(ip1->total_length);
- total_length2 = rte_bswap16(ip2->total_length);
- total_length3 = rte_bswap16(ip3->total_length);
-
- ip_da0 = ip0->dst_addr;
- ip_da1 = ip1->dst_addr;
- ip_da2 = ip2->dst_addr;
- ip_da3 = ip3->dst_addr;
-
- data_offset0 = entry0->data_offset;
- data_offset1 = entry1->data_offset;
- data_offset2 = entry2->data_offset;
- data_offset3 = entry3->data_offset;
-
- ether_l2_length0 = entry0->ether_l2_length;
- ether_l2_length1 = entry1->ether_l2_length;
- ether_l2_length2 = entry2->ether_l2_length;
- ether_l2_length3 = entry3->ether_l2_length;
-
- slab0_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- entry0->slab_offset[0]);
- slab1_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- entry0->slab_offset[1]);
- slab2_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- entry0->slab_offset[2]);
- slab3_ptr0 = RTE_MBUF_METADATA_UINT64_PTR(pkts[0],
- entry0->slab_offset[3]);
-
- slab0_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- entry1->slab_offset[0]);
- slab1_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- entry1->slab_offset[1]);
- slab2_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- entry1->slab_offset[2]);
- slab3_ptr1 = RTE_MBUF_METADATA_UINT64_PTR(pkts[1],
- entry1->slab_offset[3]);
-
- slab0_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- entry2->slab_offset[0]);
- slab1_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- entry2->slab_offset[1]);
- slab2_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- entry2->slab_offset[2]);
- slab3_ptr2 = RTE_MBUF_METADATA_UINT64_PTR(pkts[2],
- entry2->slab_offset[3]);
-
- slab0_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- entry3->slab_offset[0]);
- slab1_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- entry3->slab_offset[1]);
- slab2_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- entry3->slab_offset[2]);
- slab3_ptr3 = RTE_MBUF_METADATA_UINT64_PTR(pkts[3],
- entry3->slab_offset[3]);
-
- if (arp) {
- port_id0 = entry0->port_id;
- nh_ip0 = entry0->ip;
- if (entry0->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- nh_ip0 = ip_da0;
-
- port_id1 = entry1->port_id;
- nh_ip1 = entry1->ip;
- if (entry1->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- nh_ip1 = ip_da1;
-
- port_id2 = entry2->port_id;
- nh_ip2 = entry2->ip;
- if (entry2->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- nh_ip2 = ip_da2;
-
- port_id3 = entry3->port_id;
- nh_ip3 = entry3->ip;
- if (entry3->flags & PIPELINE_ROUTING_ROUTE_LOCAL)
- nh_ip3 = ip_da3;
- }
-
- /* Compute */
- total_length0 += ether_l2_length0;
- total_length1 += ether_l2_length1;
- total_length2 += ether_l2_length2;
- total_length3 += ether_l2_length3;
-
- if (qinq && qinq_sched) {
- uint32_t dscp0 = ip0->type_of_service >> 2;
- uint32_t dscp1 = ip1->type_of_service >> 2;
- uint32_t dscp2 = ip2->type_of_service >> 2;
- uint32_t dscp3 = ip3->type_of_service >> 2;
- uint32_t svlan0, cvlan0, tc0, tc_q0;
- uint32_t svlan1, cvlan1, tc1, tc_q1;
- uint32_t svlan2, cvlan2, tc2, tc_q2;
- uint32_t svlan3, cvlan3, tc3, tc_q3;
-
- if (qinq_sched == 1) {
- uint64_t slab_qinq0 = rte_bswap64(entry0->slab[0]);
- uint64_t slab_qinq1 = rte_bswap64(entry1->slab[0]);
- uint64_t slab_qinq2 = rte_bswap64(entry2->slab[0]);
- uint64_t slab_qinq3 = rte_bswap64(entry3->slab[0]);
-
- svlan0 = (slab_qinq0 >> 48) & 0xFFF;
- svlan1 = (slab_qinq1 >> 48) & 0xFFF;
- svlan2 = (slab_qinq2 >> 48) & 0xFFF;
- svlan3 = (slab_qinq3 >> 48) & 0xFFF;
-
- cvlan0 = (slab_qinq0 >> 16) & 0xFFF;
- cvlan1 = (slab_qinq1 >> 16) & 0xFFF;
- cvlan2 = (slab_qinq2 >> 16) & 0xFFF;
- cvlan3 = (slab_qinq3 >> 16) & 0xFFF;
-
- tc0 = (dscp0 >> 2) & 0x3;
- tc1 = (dscp1 >> 2) & 0x3;
- tc2 = (dscp2 >> 2) & 0x3;
- tc3 = (dscp3 >> 2) & 0x3;
-
- tc_q0 = dscp0 & 0x3;
- tc_q1 = dscp1 & 0x3;
- tc_q2 = dscp2 & 0x3;
- tc_q3 = dscp3 & 0x3;
- } else {
- uint32_t ip_src0 = rte_bswap32(ip0->src_addr);
- uint32_t ip_src1 = rte_bswap32(ip1->src_addr);
- uint32_t ip_src2 = rte_bswap32(ip2->src_addr);
- uint32_t ip_src3 = rte_bswap32(ip3->src_addr);
-
- svlan0 = 0;
- svlan1 = 0;
- svlan2 = 0;
- svlan3 = 0;
-
- cvlan0 = (ip_src0 >> 16) & 0xFFF;
- cvlan1 = (ip_src1 >> 16) & 0xFFF;
- cvlan2 = (ip_src2 >> 16) & 0xFFF;
- cvlan3 = (ip_src3 >> 16) & 0xFFF;
-
- tc0 = (ip_src0 >> 2) & 0x3;
- tc1 = (ip_src1 >> 2) & 0x3;
- tc2 = (ip_src2 >> 2) & 0x3;
- tc3 = (ip_src3 >> 2) & 0x3;
-
- tc_q0 = ip_src0 & 0x3;
- tc_q1 = ip_src1 & 0x3;
- tc_q2 = ip_src2 & 0x3;
- tc_q3 = ip_src3 & 0x3;
- }
-
- sched0 = RTE_SCHED_PORT_HIERARCHY(svlan0,
- cvlan0,
- tc0,
- tc_q0,
- e_RTE_METER_GREEN);
- sched1 = RTE_SCHED_PORT_HIERARCHY(svlan1,
- cvlan1,
- tc1,
- tc_q1,
- e_RTE_METER_GREEN);
- sched2 = RTE_SCHED_PORT_HIERARCHY(svlan2,
- cvlan2,
- tc2,
- tc_q2,
- e_RTE_METER_GREEN);
- sched3 = RTE_SCHED_PORT_HIERARCHY(svlan3,
- cvlan3,
- tc3,
- tc_q3,
- e_RTE_METER_GREEN);
-
- }
-
- /* Write */
- pkts[0]->data_off = data_offset0;
- pkts[1]->data_off = data_offset1;
- pkts[2]->data_off = data_offset2;
- pkts[3]->data_off = data_offset3;
-
- pkts[0]->data_len = total_length0;
- pkts[1]->data_len = total_length1;
- pkts[2]->data_len = total_length2;
- pkts[3]->data_len = total_length3;
-
- pkts[0]->pkt_len = total_length0;
- pkts[1]->pkt_len = total_length1;
- pkts[2]->pkt_len = total_length2;
- pkts[3]->pkt_len = total_length3;
-
- if ((qinq == 0) && (mpls == 0)) {
- *slab0_ptr0 = entry0->slab[0];
- *slab0_ptr1 = entry1->slab[0];
- *slab0_ptr2 = entry2->slab[0];
- *slab0_ptr3 = entry3->slab[0];
-
- if (arp == 0) {
- MACADDR_DST_WRITE(slab1_ptr0, entry0->slab[1]);
- MACADDR_DST_WRITE(slab1_ptr1, entry1->slab[1]);
- MACADDR_DST_WRITE(slab1_ptr2, entry2->slab[1]);
- MACADDR_DST_WRITE(slab1_ptr3, entry3->slab[1]);
- }
- }
-
- if (qinq) {
- *slab0_ptr0 = entry0->slab[0];
- *slab0_ptr1 = entry1->slab[0];
- *slab0_ptr2 = entry2->slab[0];
- *slab0_ptr3 = entry3->slab[0];
-
- *slab1_ptr0 = entry0->slab[1];
- *slab1_ptr1 = entry1->slab[1];
- *slab1_ptr2 = entry2->slab[1];
- *slab1_ptr3 = entry3->slab[1];
-
- if (arp == 0) {
- MACADDR_DST_WRITE(slab2_ptr0, entry0->slab[2]);
- MACADDR_DST_WRITE(slab2_ptr1, entry1->slab[2]);
- MACADDR_DST_WRITE(slab2_ptr2, entry2->slab[2]);
- MACADDR_DST_WRITE(slab2_ptr3, entry3->slab[2]);
- }
-
- if (qinq_sched) {
- pkts[0]->hash.sched.lo = sched0 & 0xFFFFFFFF;
- pkts[0]->hash.sched.hi = sched0 >> 32;
- pkts[1]->hash.sched.lo = sched1 & 0xFFFFFFFF;
- pkts[1]->hash.sched.hi = sched1 >> 32;
- pkts[2]->hash.sched.lo = sched2 & 0xFFFFFFFF;
- pkts[2]->hash.sched.hi = sched2 >> 32;
- pkts[3]->hash.sched.lo = sched3 & 0xFFFFFFFF;
- pkts[3]->hash.sched.hi = sched3 >> 32;
- }
- }
-
- if (mpls) {
- if (mpls_color_mark) {
- uint64_t mpls_exp0 = rte_bswap64(
- (MPLS_LABEL(0, pkt0_color, 0, 0) << 32) |
- MPLS_LABEL(0, pkt0_color, 0, 0));
- uint64_t mpls_exp1 = rte_bswap64(
- (MPLS_LABEL(0, pkt1_color, 0, 0) << 32) |
- MPLS_LABEL(0, pkt1_color, 0, 0));
- uint64_t mpls_exp2 = rte_bswap64(
- (MPLS_LABEL(0, pkt2_color, 0, 0) << 32) |
- MPLS_LABEL(0, pkt2_color, 0, 0));
- uint64_t mpls_exp3 = rte_bswap64(
- (MPLS_LABEL(0, pkt3_color, 0, 0) << 32) |
- MPLS_LABEL(0, pkt3_color, 0, 0));
-
- *slab0_ptr0 = entry0->slab[0] | mpls_exp0;
- *slab0_ptr1 = entry1->slab[0] | mpls_exp1;
- *slab0_ptr2 = entry2->slab[0] | mpls_exp2;
- *slab0_ptr3 = entry3->slab[0] | mpls_exp3;
-
- *slab1_ptr0 = entry0->slab[1] | mpls_exp0;
- *slab1_ptr1 = entry1->slab[1] | mpls_exp1;
- *slab1_ptr2 = entry2->slab[1] | mpls_exp2;
- *slab1_ptr3 = entry3->slab[1] | mpls_exp3;
-
- *slab2_ptr0 = entry0->slab[2];
- *slab2_ptr1 = entry1->slab[2];
- *slab2_ptr2 = entry2->slab[2];
- *slab2_ptr3 = entry3->slab[2];
- } else {
- *slab0_ptr0 = entry0->slab[0];
- *slab0_ptr1 = entry1->slab[0];
- *slab0_ptr2 = entry2->slab[0];
- *slab0_ptr3 = entry3->slab[0];
-
- *slab1_ptr0 = entry0->slab[1];
- *slab1_ptr1 = entry1->slab[1];
- *slab1_ptr2 = entry2->slab[1];
- *slab1_ptr3 = entry3->slab[1];
-
- *slab2_ptr0 = entry0->slab[2];
- *slab2_ptr1 = entry1->slab[2];
- *slab2_ptr2 = entry2->slab[2];
- *slab2_ptr3 = entry3->slab[2];
- }
-
- if (arp == 0) {
- MACADDR_DST_WRITE(slab3_ptr0, entry0->slab[3]);
- MACADDR_DST_WRITE(slab3_ptr1, entry1->slab[3]);
- MACADDR_DST_WRITE(slab3_ptr2, entry2->slab[3]);
- MACADDR_DST_WRITE(slab3_ptr3, entry3->slab[3]);
- }
- }
-
- if (arp) {
- arp_key0->port_id = port_id0;
- arp_key1->port_id = port_id1;
- arp_key2->port_id = port_id2;
- arp_key3->port_id = port_id3;
-
- arp_key0->ip = nh_ip0;
- arp_key1->ip = nh_ip1;
- arp_key2->ip = nh_ip2;
- arp_key3->ip = nh_ip3;
- }
-}
-
-#define PKT_WORK_ROUTING_ETHERNET(arp) \
-static inline void \
-pkt_work_routing_ether_arp##arp( \
- struct rte_mbuf *pkt, \
- struct rte_pipeline_table_entry *table_entry, \
- void *arg) \
-{ \
- pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 0, 0);\
-}
-
-#define PKT4_WORK_ROUTING_ETHERNET(arp) \
-static inline void \
-pkt4_work_routing_ether_arp##arp( \
- struct rte_mbuf **pkts, \
- struct rte_pipeline_table_entry **table_entries, \
- void *arg) \
-{ \
- pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 0, 0);\
-}
-
-#define routing_table_ah_hit_ether(arp) \
-PKT_WORK_ROUTING_ETHERNET(arp) \
-PKT4_WORK_ROUTING_ETHERNET(arp) \
-PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_arp##arp, \
- pkt_work_routing_ether_arp##arp, \
- pkt4_work_routing_ether_arp##arp)
-
-routing_table_ah_hit_ether(0)
-routing_table_ah_hit_ether(1)
-
-#define PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
-static inline void \
-pkt_work_routing_ether_qinq_sched##sched##_arp##arp( \
- struct rte_mbuf *pkt, \
- struct rte_pipeline_table_entry *table_entry, \
- void *arg) \
-{ \
- pkt_work_routing(pkt, table_entry, arg, arp, 1, sched, 0, 0);\
-}
-
-#define PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
-static inline void \
-pkt4_work_routing_ether_qinq_sched##sched##_arp##arp( \
- struct rte_mbuf **pkts, \
- struct rte_pipeline_table_entry **table_entries, \
- void *arg) \
-{ \
- pkt4_work_routing(pkts, table_entries, arg, arp, 1, sched, 0, 0);\
-}
-
-#define routing_table_ah_hit_ether_qinq(sched, arp) \
-PKT_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
-PKT4_WORK_ROUTING_ETHERNET_QINQ(sched, arp) \
-PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_qinq_sched##sched##_arp##arp,\
- pkt_work_routing_ether_qinq_sched##sched##_arp##arp, \
- pkt4_work_routing_ether_qinq_sched##sched##_arp##arp)
-
-routing_table_ah_hit_ether_qinq(0, 0)
-routing_table_ah_hit_ether_qinq(1, 0)
-routing_table_ah_hit_ether_qinq(2, 0)
-routing_table_ah_hit_ether_qinq(0, 1)
-routing_table_ah_hit_ether_qinq(1, 1)
-routing_table_ah_hit_ether_qinq(2, 1)
-
-#define PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
-static inline void \
-pkt_work_routing_ether_mpls_color##color##_arp##arp( \
- struct rte_mbuf *pkt, \
- struct rte_pipeline_table_entry *table_entry, \
- void *arg) \
-{ \
- pkt_work_routing(pkt, table_entry, arg, arp, 0, 0, 1, color);\
-}
-
-#define PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
-static inline void \
-pkt4_work_routing_ether_mpls_color##color##_arp##arp( \
- struct rte_mbuf **pkts, \
- struct rte_pipeline_table_entry **table_entries, \
- void *arg) \
-{ \
- pkt4_work_routing(pkts, table_entries, arg, arp, 0, 0, 1, color);\
-}
-
-#define routing_table_ah_hit_ether_mpls(color, arp) \
-PKT_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
-PKT4_WORK_ROUTING_ETHERNET_MPLS(color, arp) \
-PIPELINE_TABLE_AH_HIT(routing_table_ah_hit_ether_mpls_color##color##_arp##arp,\
- pkt_work_routing_ether_mpls_color##color##_arp##arp, \
- pkt4_work_routing_ether_mpls_color##color##_arp##arp)
-
-routing_table_ah_hit_ether_mpls(0, 0)
-routing_table_ah_hit_ether_mpls(1, 0)
-routing_table_ah_hit_ether_mpls(0, 1)
-routing_table_ah_hit_ether_mpls(1, 1)
-
-static rte_pipeline_table_action_handler_hit
-get_routing_table_ah_hit(struct pipeline_routing *p)
-{
- if (p->params.dbg_ah_disable)
- return NULL;
-
- switch (p->params.encap) {
- case PIPELINE_ROUTING_ENCAP_ETHERNET:
- return (p->params.n_arp_entries) ?
- routing_table_ah_hit_ether_arp1 :
- routing_table_ah_hit_ether_arp0;
-
- case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ:
- if (p->params.n_arp_entries)
- switch (p->params.qinq_sched) {
- case 0:
- return routing_table_ah_hit_ether_qinq_sched0_arp1;
- case 1:
- return routing_table_ah_hit_ether_qinq_sched1_arp1;
- case 2:
- return routing_table_ah_hit_ether_qinq_sched2_arp1;
- default:
- return NULL;
- }
- else
- switch (p->params.qinq_sched) {
- case 0:
- return routing_table_ah_hit_ether_qinq_sched0_arp0;
- case 1:
- return routing_table_ah_hit_ether_qinq_sched1_arp0;
- case 2:
- return routing_table_ah_hit_ether_qinq_sched2_arp0;
- default:
- return NULL;
- }
-
- case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS:
- if (p->params.n_arp_entries)
- if (p->params.mpls_color_mark)
- return routing_table_ah_hit_ether_mpls_color1_arp1;
- else
- return routing_table_ah_hit_ether_mpls_color0_arp1;
- else
- if (p->params.mpls_color_mark)
- return routing_table_ah_hit_ether_mpls_color1_arp0;
- else
- return routing_table_ah_hit_ether_mpls_color0_arp0;
-
- default:
- return NULL;
- }
-}
-
-/*
- * ARP table
- */
-struct arp_table_entry {
- struct rte_pipeline_table_entry head;
- uint64_t macaddr;
-};
-
-/**
- * ARP table AH
- */
-static inline void
-pkt_work_arp(
- struct rte_mbuf *pkt,
- struct rte_pipeline_table_entry *table_entry,
- __rte_unused void *arg)
-{
- struct arp_table_entry *entry = (struct arp_table_entry *) table_entry;
-
- /* Read */
- uint64_t macaddr_dst = entry->macaddr;
- uint64_t *slab_ptr = (uint64_t *) ((char *) pkt->buf_addr +
- (pkt->data_off - 2));
-
- /* Compute */
-
- /* Write */
- MACADDR_DST_WRITE(slab_ptr, macaddr_dst);
-}
-
-static inline void
-pkt4_work_arp(
- struct rte_mbuf **pkts,
- struct rte_pipeline_table_entry **table_entries,
- __rte_unused void *arg)
-{
- struct arp_table_entry *entry0 =
- (struct arp_table_entry *) table_entries[0];
- struct arp_table_entry *entry1 =
- (struct arp_table_entry *) table_entries[1];
- struct arp_table_entry *entry2 =
- (struct arp_table_entry *) table_entries[2];
- struct arp_table_entry *entry3 =
- (struct arp_table_entry *) table_entries[3];
-
- /* Read */
- uint64_t macaddr_dst0 = entry0->macaddr;
- uint64_t macaddr_dst1 = entry1->macaddr;
- uint64_t macaddr_dst2 = entry2->macaddr;
- uint64_t macaddr_dst3 = entry3->macaddr;
-
- uint64_t *slab_ptr0 = (uint64_t *) ((char *) pkts[0]->buf_addr +
- (pkts[0]->data_off - 2));
- uint64_t *slab_ptr1 = (uint64_t *) ((char *) pkts[1]->buf_addr +
- (pkts[1]->data_off - 2));
- uint64_t *slab_ptr2 = (uint64_t *) ((char *) pkts[2]->buf_addr +
- (pkts[2]->data_off - 2));
- uint64_t *slab_ptr3 = (uint64_t *) ((char *) pkts[3]->buf_addr +
- (pkts[3]->data_off - 2));
-
- /* Compute */
-
- /* Write */
- MACADDR_DST_WRITE(slab_ptr0, macaddr_dst0);
- MACADDR_DST_WRITE(slab_ptr1, macaddr_dst1);
- MACADDR_DST_WRITE(slab_ptr2, macaddr_dst2);
- MACADDR_DST_WRITE(slab_ptr3, macaddr_dst3);
-}
-
-PIPELINE_TABLE_AH_HIT(arp_table_ah_hit,
- pkt_work_arp,
- pkt4_work_arp);
-
-static rte_pipeline_table_action_handler_hit
-get_arp_table_ah_hit(struct pipeline_routing *p)
-{
- if (p->params.dbg_ah_disable)
- return NULL;
-
- return arp_table_ah_hit;
-}
-
-/*
- * Argument parsing
- */
-int
-pipeline_routing_parse_args(struct pipeline_routing_params *p,
- struct pipeline_params *params)
-{
- uint32_t n_routes_present = 0;
- uint32_t port_local_dest_present = 0;
- uint32_t encap_present = 0;
- uint32_t qinq_sched_present = 0;
- uint32_t mpls_color_mark_present = 0;
- uint32_t n_arp_entries_present = 0;
- uint32_t ip_hdr_offset_present = 0;
- uint32_t arp_key_offset_present = 0;
- uint32_t color_offset_present = 0;
- uint32_t dbg_ah_disable_present = 0;
- uint32_t i;
-
- /* default values */
- p->n_routes = PIPELINE_ROUTING_N_ROUTES_DEFAULT;
- p->port_local_dest = params->n_ports_out - 1;
- p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
- p->qinq_sched = 0;
- p->mpls_color_mark = 0;
- p->n_arp_entries = 0;
- p->dbg_ah_disable = 0;
-
- for (i = 0; i < params->n_args; i++) {
- char *arg_name = params->args_name[i];
- char *arg_value = params->args_value[i];
-
- /* n_routes */
- if (strcmp(arg_name, "n_routes") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- n_routes_present == 0, params->name,
- arg_name);
- n_routes_present = 1;
-
- status = parser_read_uint32(&p->n_routes,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status != -EINVAL) &&
- (p->n_routes != 0)), params->name,
- arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
- /* port_local_dest */
- if (strcmp(arg_name, "port_local_dest") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- port_local_dest_present == 0, params->name,
- arg_name);
- port_local_dest_present = 1;
-
- status = parser_read_uint32(&p->port_local_dest,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL(((status == 0) &&
- (p->port_local_dest < params->n_ports_out)),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* encap */
- if (strcmp(arg_name, "encap") == 0) {
- PIPELINE_PARSE_ERR_DUPLICATE(encap_present == 0,
- params->name, arg_name);
- encap_present = 1;
-
- /* ethernet */
- if (strcmp(arg_value, "ethernet") == 0) {
- p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET;
- continue;
- }
-
- /* ethernet_qinq */
- if (strcmp(arg_value, "ethernet_qinq") == 0) {
- p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ;
- continue;
- }
-
- /* ethernet_mpls */
- if (strcmp(arg_value, "ethernet_mpls") == 0) {
- p->encap = PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS;
- continue;
- }
-
- /* any other */
- PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
- arg_name, arg_value);
- }
-
- /* qinq_sched */
- if (strcmp(arg_name, "qinq_sched") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- qinq_sched_present == 0, params->name,
- arg_name);
- qinq_sched_present = 1;
-
- status = parser_read_arg_bool(arg_value);
- if (status == -EINVAL) {
- if (strcmp(arg_value, "test") == 0) {
- p->qinq_sched = 2;
- continue;
- }
- } else {
- p->qinq_sched = status;
- continue;
- }
-
- PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
- arg_name, arg_value);
- }
-
- /* mpls_color_mark */
- if (strcmp(arg_name, "mpls_color_mark") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- mpls_color_mark_present == 0,
- params->name, arg_name);
- mpls_color_mark_present = 1;
-
-
- status = parser_read_arg_bool(arg_value);
- if (status >= 0) {
- p->mpls_color_mark = status;
- continue;
- }
-
- PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
- arg_name, arg_value);
- }
-
- /* n_arp_entries */
- if (strcmp(arg_name, "n_arp_entries") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- n_arp_entries_present == 0, params->name,
- arg_name);
- n_arp_entries_present = 1;
-
- status = parser_read_uint32(&p->n_arp_entries,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* ip_hdr_offset */
- if (strcmp(arg_name, "ip_hdr_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- ip_hdr_offset_present == 0, params->name,
- arg_name);
- ip_hdr_offset_present = 1;
-
- status = parser_read_uint32(&p->ip_hdr_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* arp_key_offset */
- if (strcmp(arg_name, "arp_key_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- arp_key_offset_present == 0, params->name,
- arg_name);
- arp_key_offset_present = 1;
-
- status = parser_read_uint32(&p->arp_key_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* color_offset */
- if (strcmp(arg_name, "color_offset") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- color_offset_present == 0, params->name,
- arg_name);
- color_offset_present = 1;
-
- status = parser_read_uint32(&p->color_offset,
- arg_value);
- PIPELINE_PARSE_ERR_INV_VAL((status != -EINVAL),
- params->name, arg_name, arg_value);
- PIPELINE_PARSE_ERR_OUT_RNG((status != -ERANGE),
- params->name, arg_name, arg_value);
-
- continue;
- }
-
- /* debug */
- if (strcmp(arg_name, "dbg_ah_disable") == 0) {
- int status;
-
- PIPELINE_PARSE_ERR_DUPLICATE(
- dbg_ah_disable_present == 0, params->name,
- arg_name);
- dbg_ah_disable_present = 1;
-
- status = parser_read_arg_bool(arg_value);
- if (status >= 0) {
- p->dbg_ah_disable = status;
- continue;
- }
-
- PIPELINE_PARSE_ERR_INV_VAL(0, params->name,
- arg_name, arg_value);
-
- continue;
- }
-
- /* any other */
- PIPELINE_PARSE_ERR_INV_ENT(0, params->name, arg_name);
- }
-
- /* Check that mandatory arguments are present */
- PIPELINE_PARSE_ERR_MANDATORY(ip_hdr_offset_present, params->name,
- "ip_hdr_offset");
-
- /* Check relations between arguments */
- switch (p->encap) {
- case PIPELINE_ROUTING_ENCAP_ETHERNET:
- PIPELINE_ARG_CHECK((!p->qinq_sched), "Parse error in "
- "section \"%s\": encap = ethernet, therefore "
- "qinq_sched = yes/test is not allowed",
- params->name);
- PIPELINE_ARG_CHECK((!p->mpls_color_mark), "Parse error "
- "in section \"%s\": encap = ethernet, therefore "
- "mpls_color_mark = yes is not allowed",
- params->name);
- PIPELINE_ARG_CHECK((!color_offset_present), "Parse error "
- "in section \"%s\": encap = ethernet, therefore "
- "color_offset is not allowed",
- params->name);
- break;
-
- case PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ:
- PIPELINE_ARG_CHECK((!p->mpls_color_mark), "Parse error "
- "in section \"%s\": encap = ethernet_qinq, "
- "therefore mpls_color_mark = yes is not allowed",
- params->name);
- PIPELINE_ARG_CHECK((!color_offset_present), "Parse error "
- "in section \"%s\": encap = ethernet_qinq, "
- "therefore color_offset is not allowed",
- params->name);
- break;
-
- case PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS:
- PIPELINE_ARG_CHECK((!p->qinq_sched), "Parse error in "
- "section \"%s\": encap = ethernet_mpls, therefore "
- "qinq_sched = yes/test is not allowed",
- params->name);
- break;
- }
-
- PIPELINE_ARG_CHECK((!(p->n_arp_entries &&
- (!arp_key_offset_present))), "Parse error in section "
- "\"%s\": n_arp_entries is set while "
- "arp_key_offset is not set", params->name);
-
- PIPELINE_ARG_CHECK((!((p->n_arp_entries == 0) &&
- arp_key_offset_present)), "Parse error in section "
- "\"%s\": arp_key_offset present while "
- "n_arp_entries is not set", params->name);
-
- return 0;
-}
-
-static void *
-pipeline_routing_init(struct pipeline_params *params,
- __rte_unused void *arg)
-{
- struct pipeline *p;
- struct pipeline_routing *p_rt;
- uint32_t size, i;
-
- /* Check input arguments */
- if ((params == NULL) ||
- (params->n_ports_in == 0) ||
- (params->n_ports_out == 0))
- return NULL;
-
- /* Memory allocation */
- size = RTE_CACHE_LINE_ROUNDUP(sizeof(struct pipeline_routing));
- p = rte_zmalloc(NULL, size, RTE_CACHE_LINE_SIZE);
- p_rt = (struct pipeline_routing *) p;
- if (p == NULL)
- return NULL;
-
- strcpy(p->name, params->name);
- p->log_level = params->log_level;
-
- PLOG(p, HIGH, "Routing");
-
- /* Parse arguments */
- if (pipeline_routing_parse_args(&p_rt->params, params))
- return NULL;
-
- /* Pipeline */
- {
- struct rte_pipeline_params pipeline_params = {
- .name = params->name,
- .socket_id = params->socket_id,
- .offset_port_id = 0,
- };
-
- p->p = rte_pipeline_create(&pipeline_params);
- if (p->p == NULL) {
- rte_free(p);
- return NULL;
- }
- }
-
- /* Input ports */
- p->n_ports_in = params->n_ports_in;
- for (i = 0; i < p->n_ports_in; i++) {
- struct rte_pipeline_port_in_params port_params = {
- .ops = pipeline_port_in_params_get_ops(
- &params->port_in[i]),
- .arg_create = pipeline_port_in_params_convert(
- &params->port_in[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- .burst_size = params->port_in[i].burst_size,
- };
-
- int status = rte_pipeline_port_in_create(p->p,
- &port_params,
- &p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Output ports */
- p->n_ports_out = params->n_ports_out;
- for (i = 0; i < p->n_ports_out; i++) {
- struct rte_pipeline_port_out_params port_params = {
- .ops = pipeline_port_out_params_get_ops(
- &params->port_out[i]),
- .arg_create = pipeline_port_out_params_convert(
- &params->port_out[i]),
- .f_action = NULL,
- .arg_ah = NULL,
- };
-
- int status = rte_pipeline_port_out_create(p->p,
- &port_params,
- &p->port_out_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Routing table */
- p->n_tables = 1;
- {
- struct rte_table_lpm_params table_lpm_params = {
- .name = p->name,
- .n_rules = p_rt->params.n_routes,
- .number_tbl8s = PIPELINE_ROUTING_LPM_TABLE_NUMBER_TABLE8s,
- .flags = 0,
- .entry_unique_size = sizeof(struct routing_table_entry),
- .offset = p_rt->params.ip_hdr_offset +
- __builtin_offsetof(struct ipv4_hdr, dst_addr),
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_lpm_ops,
- .arg_create = &table_lpm_params,
- .f_action_hit = get_routing_table_ah_hit(p_rt),
- .f_action_miss = NULL,
- .arg_ah = p_rt,
- .action_data_size =
- sizeof(struct routing_table_entry) -
- sizeof(struct rte_pipeline_table_entry),
- };
-
- int status;
-
- status = rte_pipeline_table_create(p->p,
- &table_params,
- &p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* ARP table configuration */
- if (p_rt->params.n_arp_entries) {
- struct rte_table_hash_params table_arp_params = {
- .name = p->name,
- .key_size = 8,
- .key_offset = p_rt->params.arp_key_offset,
- .key_mask = NULL,
- .n_keys = p_rt->params.n_arp_entries,
- .n_buckets =
- rte_align32pow2(p_rt->params.n_arp_entries / 4),
- .f_hash = hash_default_key8,
- .seed = 0,
- };
-
- struct rte_pipeline_table_params table_params = {
- .ops = &rte_table_hash_key8_ext_ops,
- .arg_create = &table_arp_params,
- .f_action_hit = get_arp_table_ah_hit(p_rt),
- .f_action_miss = NULL,
- .arg_ah = p_rt,
- .action_data_size = sizeof(struct arp_table_entry) -
- sizeof(struct rte_pipeline_table_entry),
- };
-
- int status;
-
- status = rte_pipeline_table_create(p->p,
- &table_params,
- &p->table_id[1]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
-
- p->n_tables++;
- }
-
- /* Connecting input ports to tables */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_connect_to_table(p->p,
- p->port_in_id[i],
- p->table_id[0]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Enable input ports */
- for (i = 0; i < p->n_ports_in; i++) {
- int status = rte_pipeline_port_in_enable(p->p,
- p->port_in_id[i]);
-
- if (status) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
- }
-
- /* Check pipeline consistency */
- if (rte_pipeline_check(p->p) < 0) {
- rte_pipeline_free(p->p);
- rte_free(p);
- return NULL;
- }
-
- /* Message queues */
- p->n_msgq = params->n_msgq;
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_in[i] = params->msgq_in[i];
- for (i = 0; i < p->n_msgq; i++)
- p->msgq_out[i] = params->msgq_out[i];
-
- /* Message handlers */
- memcpy(p->handlers, handlers, sizeof(p->handlers));
- memcpy(p_rt->custom_handlers,
- custom_handlers,
- sizeof(p_rt->custom_handlers));
-
- return p;
-}
-
-static int
-pipeline_routing_free(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- /* Check input arguments */
- if (p == NULL)
- return -1;
-
- /* Free resources */
- rte_pipeline_free(p->p);
- rte_free(p);
- return 0;
-}
-
-static int
-pipeline_routing_timer(void *pipeline)
-{
- struct pipeline *p = (struct pipeline *) pipeline;
-
- pipeline_msg_req_handle(p);
- rte_pipeline_flush(p->p);
-
- return 0;
-}
-
-void *
-pipeline_routing_msg_req_custom_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
- struct pipeline_custom_msg_req *req = msg;
- pipeline_msg_req_handler f_handle;
-
- f_handle = (req->subtype < PIPELINE_ROUTING_MSG_REQS) ?
- p_rt->custom_handlers[req->subtype] :
- pipeline_msg_req_invalid_handler;
-
- if (f_handle == NULL)
- f_handle = pipeline_msg_req_invalid_handler;
-
- return f_handle(p, req);
-}
-
-void *
-pipeline_routing_msg_req_route_add_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
- struct pipeline_routing_route_add_msg_req *req = msg;
- struct pipeline_routing_route_add_msg_rsp *rsp = msg;
-
- struct rte_table_lpm_key key = {
- .ip = req->key.key.ipv4.ip,
- .depth = req->key.key.ipv4.depth,
- };
-
- struct routing_table_entry entry_arp0 = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->data.port_id]},
- },
-
- .flags = req->data.flags,
- .port_id = req->data.port_id,
- .ip = 0,
- .data_offset = 0,
- .ether_l2_length = 0,
- .slab = {0},
- .slab_offset = {0},
- };
-
- struct routing_table_entry entry_arp1 = {
- .head = {
- .action = RTE_PIPELINE_ACTION_TABLE,
- {.table_id = p->table_id[1]},
- },
-
- .flags = req->data.flags,
- .port_id = req->data.port_id,
- .ip = rte_bswap32(req->data.ethernet.ip),
- .data_offset = 0,
- .ether_l2_length = 0,
- .slab = {0},
- .slab_offset = {0},
- };
-
- struct rte_pipeline_table_entry *entry = (p_rt->params.n_arp_entries) ?
- (struct rte_pipeline_table_entry *) &entry_arp1 :
- (struct rte_pipeline_table_entry *) &entry_arp0;
-
- if ((req->key.type != PIPELINE_ROUTING_ROUTE_IPV4) ||
- ((p_rt->params.n_arp_entries == 0) &&
- (req->data.flags & PIPELINE_ROUTING_ROUTE_ARP)) ||
- (p_rt->params.n_arp_entries &&
- ((req->data.flags & PIPELINE_ROUTING_ROUTE_ARP) == 0)) ||
- ((p_rt->params.encap != PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
- (req->data.flags & PIPELINE_ROUTING_ROUTE_QINQ)) ||
- ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
- ((req->data.flags & PIPELINE_ROUTING_ROUTE_QINQ) == 0)) ||
- ((p_rt->params.encap != PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
- (req->data.flags & PIPELINE_ROUTING_ROUTE_MPLS)) ||
- ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
- ((req->data.flags & PIPELINE_ROUTING_ROUTE_MPLS) == 0))) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Ether - ARP off */
- if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
- (p_rt->params.n_arp_entries == 0)) {
- uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
- uint64_t macaddr_dst;
- uint64_t ethertype = ETHER_TYPE_IPv4;
-
- macaddr_dst = *((uint64_t *)&(req->data.ethernet.macaddr));
- macaddr_dst = rte_bswap64(macaddr_dst << 16);
-
- entry_arp0.slab[0] =
- SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
- entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
- entry_arp0.slab[1] = rte_bswap64(macaddr_dst);
- entry_arp0.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
-
- entry_arp0.data_offset = entry_arp0.slab_offset[1] + 2
- - sizeof(struct rte_mbuf);
- entry_arp0.ether_l2_length = 14;
- }
-
- /* Ether - ARP on */
- if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET) &&
- p_rt->params.n_arp_entries) {
- uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
- uint64_t ethertype = ETHER_TYPE_IPv4;
-
- entry_arp1.slab[0] =
- SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype);
- entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
- entry_arp1.data_offset = entry_arp1.slab_offset[0] - 6
- - sizeof(struct rte_mbuf);
- entry_arp1.ether_l2_length = 14;
- }
-
- /* Ether QinQ - ARP off */
- if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
- (p_rt->params.n_arp_entries == 0)) {
- uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
- uint64_t macaddr_dst;
- uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
- uint64_t ethertype_vlan = 0x8100;
- uint64_t ethertype_qinq = 0x9100;
- uint64_t svlan = req->data.l2.qinq.svlan;
- uint64_t cvlan = req->data.l2.qinq.cvlan;
-
- macaddr_dst = *((uint64_t *)&(req->data.ethernet.macaddr));
- macaddr_dst = rte_bswap64(macaddr_dst << 16);
-
- entry_arp0.slab[0] = rte_bswap64((svlan << 48) |
- (ethertype_vlan << 32) |
- (cvlan << 16) |
- ethertype_ipv4);
- entry_arp0.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
- entry_arp0.slab[1] =
- SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
- entry_arp0.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
-
- entry_arp0.slab[2] = rte_bswap64(macaddr_dst);
- entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset - 3 * 8;
-
- entry_arp0.data_offset = entry_arp0.slab_offset[2] + 2
- - sizeof(struct rte_mbuf);
- entry_arp0.ether_l2_length = 22;
- }
-
- /* Ether QinQ - ARP on */
- if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ) &&
- p_rt->params.n_arp_entries) {
- uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
- uint64_t ethertype_ipv4 = ETHER_TYPE_IPv4;
- uint64_t ethertype_vlan = 0x8100;
- uint64_t ethertype_qinq = 0x9100;
- uint64_t svlan = req->data.l2.qinq.svlan;
- uint64_t cvlan = req->data.l2.qinq.cvlan;
-
- entry_arp1.slab[0] = rte_bswap64((svlan << 48) |
- (ethertype_vlan << 32) |
- (cvlan << 16) |
- ethertype_ipv4);
- entry_arp1.slab_offset[0] = p_rt->params.ip_hdr_offset - 8;
-
- entry_arp1.slab[1] =
- SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_qinq);
- entry_arp1.slab_offset[1] = p_rt->params.ip_hdr_offset - 2 * 8;
-
- entry_arp1.data_offset = entry_arp1.slab_offset[1] - 6
- - sizeof(struct rte_mbuf);
- entry_arp1.ether_l2_length = 22;
- }
-
- /* Ether MPLS - ARP off */
- if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
- (p_rt->params.n_arp_entries == 0)) {
- uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
- uint64_t macaddr_dst;
- uint64_t ethertype_mpls = 0x8847;
-
- uint64_t label0 = req->data.l2.mpls.labels[0];
- uint64_t label1 = req->data.l2.mpls.labels[1];
- uint64_t label2 = req->data.l2.mpls.labels[2];
- uint64_t label3 = req->data.l2.mpls.labels[3];
- uint32_t n_labels = req->data.l2.mpls.n_labels;
-
- macaddr_dst = *((uint64_t *)&(req->data.ethernet.macaddr));
- macaddr_dst = rte_bswap64(macaddr_dst << 16);
-
- switch (n_labels) {
- case 1:
- entry_arp0.slab[0] = 0;
- entry_arp0.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp0.slab[1] = rte_bswap64(
- MPLS_LABEL(label0, 0, 1, 0));
- entry_arp0.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 8;
- break;
-
- case 2:
- entry_arp0.slab[0] = 0;
- entry_arp0.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp0.slab[1] = rte_bswap64(
- (MPLS_LABEL(label0, 0, 0, 0) << 32) |
- MPLS_LABEL(label1, 0, 1, 0));
- entry_arp0.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 8;
- break;
-
- case 3:
- entry_arp0.slab[0] = rte_bswap64(
- (MPLS_LABEL(label1, 0, 0, 0) << 32) |
- MPLS_LABEL(label2, 0, 1, 0));
- entry_arp0.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp0.slab[1] = rte_bswap64(
- MPLS_LABEL(label0, 0, 0, 0));
- entry_arp0.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 2 * 8;
- break;
-
- case 4:
- entry_arp0.slab[0] = rte_bswap64(
- (MPLS_LABEL(label2, 0, 0, 0) << 32) |
- MPLS_LABEL(label3, 0, 1, 0));
- entry_arp0.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp0.slab[1] = rte_bswap64(
- (MPLS_LABEL(label0, 0, 0, 0) << 32) |
- MPLS_LABEL(label1, 0, 0, 0));
- entry_arp0.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 2 * 8;
- break;
-
- default:
- rsp->status = -1;
- return rsp;
- }
-
- entry_arp0.slab[2] =
- SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
- entry_arp0.slab_offset[2] = p_rt->params.ip_hdr_offset -
- (n_labels * 4 + 8);
-
- entry_arp0.slab[3] = rte_bswap64(macaddr_dst);
- entry_arp0.slab_offset[3] = p_rt->params.ip_hdr_offset -
- (n_labels * 4 + 2 * 8);
-
- entry_arp0.data_offset = entry_arp0.slab_offset[3] + 2
- - sizeof(struct rte_mbuf);
- entry_arp0.ether_l2_length = n_labels * 4 + 14;
- }
-
- /* Ether MPLS - ARP on */
- if ((p_rt->params.encap == PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS) &&
- p_rt->params.n_arp_entries) {
- uint64_t macaddr_src = p_rt->macaddr[req->data.port_id];
- uint64_t ethertype_mpls = 0x8847;
-
- uint64_t label0 = req->data.l2.mpls.labels[0];
- uint64_t label1 = req->data.l2.mpls.labels[1];
- uint64_t label2 = req->data.l2.mpls.labels[2];
- uint64_t label3 = req->data.l2.mpls.labels[3];
- uint32_t n_labels = req->data.l2.mpls.n_labels;
-
- switch (n_labels) {
- case 1:
- entry_arp1.slab[0] = 0;
- entry_arp1.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp1.slab[1] = rte_bswap64(
- MPLS_LABEL(label0, 0, 1, 0));
- entry_arp1.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 8;
- break;
-
- case 2:
- entry_arp1.slab[0] = 0;
- entry_arp1.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp1.slab[1] = rte_bswap64(
- (MPLS_LABEL(label0, 0, 0, 0) << 32) |
- MPLS_LABEL(label1, 0, 1, 0));
- entry_arp1.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 8;
- break;
-
- case 3:
- entry_arp1.slab[0] = rte_bswap64(
- (MPLS_LABEL(label1, 0, 0, 0) << 32) |
- MPLS_LABEL(label2, 0, 1, 0));
- entry_arp1.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp1.slab[1] = rte_bswap64(
- MPLS_LABEL(label0, 0, 0, 0));
- entry_arp1.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 2 * 8;
- break;
-
- case 4:
- entry_arp1.slab[0] = rte_bswap64(
- (MPLS_LABEL(label2, 0, 0, 0) << 32) |
- MPLS_LABEL(label3, 0, 1, 0));
- entry_arp1.slab_offset[0] =
- p_rt->params.ip_hdr_offset - 8;
-
- entry_arp1.slab[1] = rte_bswap64(
- (MPLS_LABEL(label0, 0, 0, 0) << 32) |
- MPLS_LABEL(label1, 0, 0, 0));
- entry_arp1.slab_offset[1] =
- p_rt->params.ip_hdr_offset - 2 * 8;
- break;
-
- default:
- rsp->status = -1;
- return rsp;
- }
-
- entry_arp1.slab[2] =
- SLAB_NBO_MACADDRSRC_ETHERTYPE(macaddr_src, ethertype_mpls);
- entry_arp1.slab_offset[2] = p_rt->params.ip_hdr_offset -
- (n_labels * 4 + 8);
-
- entry_arp1.data_offset = entry_arp1.slab_offset[2] - 6
- - sizeof(struct rte_mbuf);
- entry_arp1.ether_l2_length = n_labels * 4 + 14;
- }
-
- rsp->status = rte_pipeline_table_entry_add(p->p,
- p->table_id[0],
- &key,
- entry,
- &rsp->key_found,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_route_del_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_routing_route_delete_msg_req *req = msg;
- struct pipeline_routing_route_delete_msg_rsp *rsp = msg;
-
- struct rte_table_lpm_key key = {
- .ip = req->key.key.ipv4.ip,
- .depth = req->key.key.ipv4.depth,
- };
-
- if (req->key.type != PIPELINE_ROUTING_ROUTE_IPV4) {
- rsp->status = -1;
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- p->table_id[0],
- &key,
- &rsp->key_found,
- NULL);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_route_add_default_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_routing_route_add_default_msg_req *req = msg;
- struct pipeline_routing_route_add_default_msg_rsp *rsp = msg;
-
- struct routing_table_entry default_entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->port_id]},
- },
-
- .flags = 0,
- .port_id = 0,
- .ip = 0,
- };
-
- rsp->status = rte_pipeline_table_default_entry_add(p->p,
- p->table_id[0],
- (struct rte_pipeline_table_entry *) &default_entry,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_route_del_default_handler(struct pipeline *p,
- void *msg)
-{
- struct pipeline_routing_route_delete_default_msg_rsp *rsp = msg;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- p->table_id[0],
- NULL);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_add_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_routing_arp_add_msg_req *req = msg;
- struct pipeline_routing_arp_add_msg_rsp *rsp = msg;
-
- struct pipeline_routing_arp_key_ipv4 key = {
- .port_id = req->key.key.ipv4.port_id,
- .ip = rte_bswap32(req->key.key.ipv4.ip),
- };
-
- struct arp_table_entry entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->key.key.ipv4.port_id]},
- },
-
- .macaddr = 0, /* set below */
- };
-
- if (req->key.type != PIPELINE_ROUTING_ARP_IPV4) {
- rsp->status = -1;
- return rsp;
- }
-
- entry.macaddr = *((uint64_t *)&(req->macaddr));
- entry.macaddr = entry.macaddr << 16;
-
- rsp->status = rte_pipeline_table_entry_add(p->p,
- p->table_id[1],
- &key,
- (struct rte_pipeline_table_entry *) &entry,
- &rsp->key_found,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_del_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_routing_arp_delete_msg_req *req = msg;
- struct pipeline_routing_arp_delete_msg_rsp *rsp = msg;
-
- struct pipeline_routing_arp_key_ipv4 key = {
- .port_id = req->key.key.ipv4.port_id,
- .ip = rte_bswap32(req->key.key.ipv4.ip),
- };
-
- if (req->key.type != PIPELINE_ROUTING_ARP_IPV4) {
- rsp->status = -1;
- return rsp;
- }
-
- rsp->status = rte_pipeline_table_entry_delete(p->p,
- p->table_id[1],
- &key,
- &rsp->key_found,
- NULL);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_add_default_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_routing_arp_add_default_msg_req *req = msg;
- struct pipeline_routing_arp_add_default_msg_rsp *rsp = msg;
-
- struct arp_table_entry default_entry = {
- .head = {
- .action = RTE_PIPELINE_ACTION_PORT,
- {.port_id = p->port_out_id[req->port_id]},
- },
-
- .macaddr = 0,
- };
-
- rsp->status = rte_pipeline_table_default_entry_add(p->p,
- p->table_id[1],
- (struct rte_pipeline_table_entry *) &default_entry,
- (struct rte_pipeline_table_entry **) &rsp->entry_ptr);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_arp_del_default_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_routing_arp_delete_default_msg_rsp *rsp = msg;
-
- rsp->status = rte_pipeline_table_default_entry_delete(p->p,
- p->table_id[1],
- NULL);
-
- return rsp;
-}
-
-void *
-pipeline_routing_msg_req_set_macaddr_handler(struct pipeline *p, void *msg)
-{
- struct pipeline_routing *p_rt = (struct pipeline_routing *) p;
- struct pipeline_routing_set_macaddr_msg_req *req = msg;
- struct pipeline_routing_set_macaddr_msg_rsp *rsp = msg;
- uint32_t port_id;
-
- for (port_id = 0; port_id < p->n_ports_out; port_id++)
- p_rt->macaddr[port_id] = req->macaddr[port_id];
-
- rsp->status = 0;
-
- return rsp;
-}
-
-struct pipeline_be_ops pipeline_routing_be_ops = {
- .f_init = pipeline_routing_init,
- .f_free = pipeline_routing_free,
- .f_run = NULL,
- .f_timer = pipeline_routing_timer,
-};
diff --git a/examples/ip_pipeline/pipeline/pipeline_routing_be.h b/examples/ip_pipeline/pipeline/pipeline_routing_be.h
deleted file mode 100644
index 7140ee40..00000000
--- a/examples/ip_pipeline/pipeline/pipeline_routing_be.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_ROUTING_BE_H__
-#define __INCLUDE_PIPELINE_ROUTING_BE_H__
-
-#include <rte_ether.h>
-
-#include "pipeline_common_be.h"
-
-/*
- * Pipeline argument parsing
- */
-#ifndef PIPELINE_ROUTING_N_ROUTES_DEFAULT
-#define PIPELINE_ROUTING_N_ROUTES_DEFAULT 4096
-#endif
-
-enum pipeline_routing_encap {
- PIPELINE_ROUTING_ENCAP_ETHERNET = 0,
- PIPELINE_ROUTING_ENCAP_ETHERNET_QINQ,
- PIPELINE_ROUTING_ENCAP_ETHERNET_MPLS,
-};
-
-struct pipeline_routing_params {
- /* routing */
- uint32_t n_routes;
- uint32_t port_local_dest;
-
- /* routing packet encapsulation */
- enum pipeline_routing_encap encap;
- uint32_t qinq_sched;
- uint32_t mpls_color_mark;
-
- /* arp */
- uint32_t n_arp_entries;
-
- /* packet buffer offsets */
- uint32_t ip_hdr_offset;
- uint32_t arp_key_offset;
- uint32_t color_offset;
-
- /* debug */
- uint32_t dbg_ah_disable;
-};
-
-int
-pipeline_routing_parse_args(struct pipeline_routing_params *p,
- struct pipeline_params *params);
-
-/*
- * Route
- */
-enum pipeline_routing_route_key_type {
- PIPELINE_ROUTING_ROUTE_IPV4,
-};
-
-struct pipeline_routing_route_key_ipv4 {
- uint32_t ip;
- uint32_t depth;
-};
-
-struct pipeline_routing_route_key {
- enum pipeline_routing_route_key_type type;
- union {
- struct pipeline_routing_route_key_ipv4 ipv4;
- } key;
-};
-
-enum pipeline_routing_route_flags {
- PIPELINE_ROUTING_ROUTE_LOCAL = 1 << 0, /* 0 = remote; 1 = local */
- PIPELINE_ROUTING_ROUTE_ARP = 1 << 1, /* 0 = ARP OFF; 1 = ARP ON */
- PIPELINE_ROUTING_ROUTE_QINQ = 1 << 2, /* 0 = QINQ OFF; 1 = QINQ ON */
- PIPELINE_ROUTING_ROUTE_MPLS = 1 << 3, /* 0 = MPLS OFF; 1 = MPLS ON */
-};
-
-#define PIPELINE_ROUTING_MPLS_LABELS_MAX 4
-
-struct pipeline_routing_route_data {
- uint32_t flags;
- uint32_t port_id; /* Output port ID */
-
- union {
- /* Next hop IP (valid only when ARP is enabled) */
- uint32_t ip;
-
- /* Next hop MAC address (valid only when ARP disabled */
- struct ether_addr macaddr;
- } ethernet;
-
- union {
- struct {
- uint16_t svlan;
- uint16_t cvlan;
- } qinq;
-
- struct {
- uint32_t labels[PIPELINE_ROUTING_MPLS_LABELS_MAX];
- uint32_t n_labels;
- } mpls;
- } l2;
-};
-
-/*
- * ARP
- */
-enum pipeline_routing_arp_key_type {
- PIPELINE_ROUTING_ARP_IPV4,
-};
-
-struct pipeline_routing_arp_key_ipv4 {
- uint32_t port_id;
- uint32_t ip;
-};
-
-struct pipeline_routing_arp_key {
- enum pipeline_routing_arp_key_type type;
- union {
- struct pipeline_routing_arp_key_ipv4 ipv4;
- } key;
-};
-
-/*
- * Messages
- */
-enum pipeline_routing_msg_req_type {
- PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD,
- PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL,
- PIPELINE_ROUTING_MSG_REQ_ROUTE_ADD_DEFAULT,
- PIPELINE_ROUTING_MSG_REQ_ROUTE_DEL_DEFAULT,
- PIPELINE_ROUTING_MSG_REQ_ARP_ADD,
- PIPELINE_ROUTING_MSG_REQ_ARP_DEL,
- PIPELINE_ROUTING_MSG_REQ_ARP_ADD_DEFAULT,
- PIPELINE_ROUTING_MSG_REQ_ARP_DEL_DEFAULT,
- PIPELINE_ROUTING_MSG_REQ_SET_MACADDR,
- PIPELINE_ROUTING_MSG_REQS
-};
-
-/*
- * MSG ROUTE ADD
- */
-struct pipeline_routing_route_add_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-
- /* key */
- struct pipeline_routing_route_key key;
-
- /* data */
- struct pipeline_routing_route_data data;
-};
-
-struct pipeline_routing_route_add_msg_rsp {
- int status;
- int key_found;
- void *entry_ptr;
-};
-
-/*
- * MSG ROUTE DELETE
- */
-struct pipeline_routing_route_delete_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-
- /* key */
- struct pipeline_routing_route_key key;
-};
-
-struct pipeline_routing_route_delete_msg_rsp {
- int status;
- int key_found;
-};
-
-/*
- * MSG ROUTE ADD DEFAULT
- */
-struct pipeline_routing_route_add_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-
- /* data */
- uint32_t port_id;
-};
-
-struct pipeline_routing_route_add_default_msg_rsp {
- int status;
- void *entry_ptr;
-};
-
-/*
- * MSG ROUTE DELETE DEFAULT
- */
-struct pipeline_routing_route_delete_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-};
-
-struct pipeline_routing_route_delete_default_msg_rsp {
- int status;
-};
-
-/*
- * MSG ARP ADD
- */
-struct pipeline_routing_arp_add_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-
- /* key */
- struct pipeline_routing_arp_key key;
-
- /* data */
- struct ether_addr macaddr;
-};
-
-struct pipeline_routing_arp_add_msg_rsp {
- int status;
- int key_found;
- void *entry_ptr;
-};
-
-/*
- * MSG ARP DELETE
- */
-struct pipeline_routing_arp_delete_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-
- /* key */
- struct pipeline_routing_arp_key key;
-};
-
-struct pipeline_routing_arp_delete_msg_rsp {
- int status;
- int key_found;
-};
-
-/*
- * MSG ARP ADD DEFAULT
- */
-struct pipeline_routing_arp_add_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-
- /* data */
- uint32_t port_id;
-};
-
-struct pipeline_routing_arp_add_default_msg_rsp {
- int status;
- void *entry_ptr;
-};
-
-/*
- * MSG ARP DELETE DEFAULT
- */
-struct pipeline_routing_arp_delete_default_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-};
-
-struct pipeline_routing_arp_delete_default_msg_rsp {
- int status;
-};
-
-/*
- * MSG SET MACADDR
- */
-struct pipeline_routing_set_macaddr_msg_req {
- enum pipeline_msg_req_type type;
- enum pipeline_routing_msg_req_type subtype;
-
- uint64_t macaddr[PIPELINE_MAX_PORT_OUT];
-};
-
-struct pipeline_routing_set_macaddr_msg_rsp {
- int status;
-};
-
-extern struct pipeline_be_ops pipeline_routing_be_ops;
-
-#endif
diff --git a/examples/ip_pipeline/pipeline_be.h b/examples/ip_pipeline/pipeline_be.h
deleted file mode 100644
index 6c0c97a4..00000000
--- a/examples/ip_pipeline/pipeline_be.h
+++ /dev/null
@@ -1,322 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
- */
-
-#ifndef __INCLUDE_PIPELINE_BE_H__
-#define __INCLUDE_PIPELINE_BE_H__
-
-#include <rte_port_ethdev.h>
-#include <rte_port_ring.h>
-#include <rte_port_frag.h>
-#include <rte_port_ras.h>
-#include <rte_port_sched.h>
-#include <rte_port_fd.h>
-#include <rte_port_source_sink.h>
-#ifdef RTE_LIBRTE_KNI
-#include <rte_port_kni.h>
-#endif
-#include <rte_pipeline.h>
-
-enum pipeline_port_in_type {
- PIPELINE_PORT_IN_ETHDEV_READER,
- PIPELINE_PORT_IN_RING_READER,
- PIPELINE_PORT_IN_RING_MULTI_READER,
- PIPELINE_PORT_IN_RING_READER_IPV4_FRAG,
- PIPELINE_PORT_IN_RING_READER_IPV6_FRAG,
- PIPELINE_PORT_IN_SCHED_READER,
- PIPELINE_PORT_IN_FD_READER,
- PIPELINE_PORT_IN_KNI_READER,
- PIPELINE_PORT_IN_SOURCE,
-};
-
-struct pipeline_port_in_params {
- enum pipeline_port_in_type type;
- union {
- struct rte_port_ethdev_reader_params ethdev;
- struct rte_port_ring_reader_params ring;
- struct rte_port_ring_multi_reader_params ring_multi;
- struct rte_port_ring_reader_ipv4_frag_params ring_ipv4_frag;
- struct rte_port_ring_reader_ipv6_frag_params ring_ipv6_frag;
- struct rte_port_sched_reader_params sched;
- struct rte_port_fd_reader_params fd;
-#ifdef RTE_LIBRTE_KNI
- struct rte_port_kni_reader_params kni;
-#endif
- struct rte_port_source_params source;
- } params;
- uint32_t burst_size;
-};
-
-static inline void *
-pipeline_port_in_params_convert(struct pipeline_port_in_params *p)
-{
- switch (p->type) {
- case PIPELINE_PORT_IN_ETHDEV_READER:
- return (void *) &p->params.ethdev;
- case PIPELINE_PORT_IN_RING_READER:
- return (void *) &p->params.ring;
- case PIPELINE_PORT_IN_RING_MULTI_READER:
- return (void *) &p->params.ring_multi;
- case PIPELINE_PORT_IN_RING_READER_IPV4_FRAG:
- return (void *) &p->params.ring_ipv4_frag;
- case PIPELINE_PORT_IN_RING_READER_IPV6_FRAG:
- return (void *) &p->params.ring_ipv6_frag;
- case PIPELINE_PORT_IN_SCHED_READER:
- return (void *) &p->params.sched;
- case PIPELINE_PORT_IN_FD_READER:
- return (void *) &p->params.fd;
-#ifdef RTE_LIBRTE_KNI
- case PIPELINE_PORT_IN_KNI_READER:
- return (void *) &p->params.kni;
-#endif
- case PIPELINE_PORT_IN_SOURCE:
- return (void *) &p->params.source;
- default:
- return NULL;
- }
-}
-
-static inline struct rte_port_in_ops *
-pipeline_port_in_params_get_ops(struct pipeline_port_in_params *p)
-{
- switch (p->type) {
- case PIPELINE_PORT_IN_ETHDEV_READER:
- return &rte_port_ethdev_reader_ops;
- case PIPELINE_PORT_IN_RING_READER:
- return &rte_port_ring_reader_ops;
- case PIPELINE_PORT_IN_RING_MULTI_READER:
- return &rte_port_ring_multi_reader_ops;
- case PIPELINE_PORT_IN_RING_READER_IPV4_FRAG:
- return &rte_port_ring_reader_ipv4_frag_ops;
- case PIPELINE_PORT_IN_RING_READER_IPV6_FRAG:
- return &rte_port_ring_reader_ipv6_frag_ops;
- case PIPELINE_PORT_IN_SCHED_READER:
- return &rte_port_sched_reader_ops;
- case PIPELINE_PORT_IN_FD_READER:
- return &rte_port_fd_reader_ops;
-#ifdef RTE_LIBRTE_KNI
- case PIPELINE_PORT_IN_KNI_READER:
- return &rte_port_kni_reader_ops;
-#endif
- case PIPELINE_PORT_IN_SOURCE:
- return &rte_port_source_ops;
- default:
- return NULL;
- }
-}
-
-enum pipeline_port_out_type {
- PIPELINE_PORT_OUT_ETHDEV_WRITER,
- PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP,
- PIPELINE_PORT_OUT_RING_WRITER,
- PIPELINE_PORT_OUT_RING_MULTI_WRITER,
- PIPELINE_PORT_OUT_RING_WRITER_NODROP,
- PIPELINE_PORT_OUT_RING_MULTI_WRITER_NODROP,
- PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS,
- PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS,
- PIPELINE_PORT_OUT_SCHED_WRITER,
- PIPELINE_PORT_OUT_FD_WRITER,
- PIPELINE_PORT_OUT_KNI_WRITER,
- PIPELINE_PORT_OUT_KNI_WRITER_NODROP,
- PIPELINE_PORT_OUT_SINK,
-};
-
-struct pipeline_port_out_params {
- enum pipeline_port_out_type type;
- union {
- struct rte_port_ethdev_writer_params ethdev;
- struct rte_port_ethdev_writer_nodrop_params ethdev_nodrop;
- struct rte_port_ring_writer_params ring;
- struct rte_port_ring_multi_writer_params ring_multi;
- struct rte_port_ring_writer_nodrop_params ring_nodrop;
- struct rte_port_ring_multi_writer_nodrop_params ring_multi_nodrop;
- struct rte_port_ring_writer_ipv4_ras_params ring_ipv4_ras;
- struct rte_port_ring_writer_ipv6_ras_params ring_ipv6_ras;
- struct rte_port_sched_writer_params sched;
- struct rte_port_fd_writer_params fd;
-#ifdef RTE_LIBRTE_KNI
- struct rte_port_kni_writer_params kni;
- struct rte_port_kni_writer_nodrop_params kni_nodrop;
-#endif
- struct rte_port_sink_params sink;
- } params;
-};
-
-static inline void *
-pipeline_port_out_params_convert(struct pipeline_port_out_params *p)
-{
- switch (p->type) {
- case PIPELINE_PORT_OUT_ETHDEV_WRITER:
- return (void *) &p->params.ethdev;
- case PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP:
- return (void *) &p->params.ethdev_nodrop;
- case PIPELINE_PORT_OUT_RING_WRITER:
- return (void *) &p->params.ring;
- case PIPELINE_PORT_OUT_RING_MULTI_WRITER:
- return (void *) &p->params.ring_multi;
- case PIPELINE_PORT_OUT_RING_WRITER_NODROP:
- return (void *) &p->params.ring_nodrop;
- case PIPELINE_PORT_OUT_RING_MULTI_WRITER_NODROP:
- return (void *) &p->params.ring_multi_nodrop;
- case PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS:
- return (void *) &p->params.ring_ipv4_ras;
- case PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS:
- return (void *) &p->params.ring_ipv6_ras;
- case PIPELINE_PORT_OUT_SCHED_WRITER:
- return (void *) &p->params.sched;
- case PIPELINE_PORT_OUT_FD_WRITER:
- return (void *) &p->params.fd;
-#ifdef RTE_LIBRTE_KNI
- case PIPELINE_PORT_OUT_KNI_WRITER:
- return (void *) &p->params.kni;
- case PIPELINE_PORT_OUT_KNI_WRITER_NODROP:
- return (void *) &p->params.kni_nodrop;
-#endif
- case PIPELINE_PORT_OUT_SINK:
- return (void *) &p->params.sink;
- default:
- return NULL;
- }
-}
-
-static inline void *
-pipeline_port_out_params_get_ops(struct pipeline_port_out_params *p)
-{
- switch (p->type) {
- case PIPELINE_PORT_OUT_ETHDEV_WRITER:
- return &rte_port_ethdev_writer_ops;
- case PIPELINE_PORT_OUT_ETHDEV_WRITER_NODROP:
- return &rte_port_ethdev_writer_nodrop_ops;
- case PIPELINE_PORT_OUT_RING_WRITER:
- return &rte_port_ring_writer_ops;
- case PIPELINE_PORT_OUT_RING_MULTI_WRITER:
- return &rte_port_ring_multi_writer_ops;
- case PIPELINE_PORT_OUT_RING_WRITER_NODROP:
- return &rte_port_ring_writer_nodrop_ops;
- case PIPELINE_PORT_OUT_RING_MULTI_WRITER_NODROP:
- return &rte_port_ring_multi_writer_nodrop_ops;
- case PIPELINE_PORT_OUT_RING_WRITER_IPV4_RAS:
- return &rte_port_ring_writer_ipv4_ras_ops;
- case PIPELINE_PORT_OUT_RING_WRITER_IPV6_RAS:
- return &rte_port_ring_writer_ipv6_ras_ops;
- case PIPELINE_PORT_OUT_SCHED_WRITER:
- return &rte_port_sched_writer_ops;
- case PIPELINE_PORT_OUT_FD_WRITER:
- return &rte_port_fd_writer_ops;
-#ifdef RTE_LIBRTE_KNI
- case PIPELINE_PORT_OUT_KNI_WRITER:
- return &rte_port_kni_writer_ops;
- case PIPELINE_PORT_OUT_KNI_WRITER_NODROP:
- return &rte_port_kni_writer_nodrop_ops;
-#endif
- case PIPELINE_PORT_OUT_SINK:
- return &rte_port_sink_ops;
- default:
- return NULL;
- }
-}
-
-#ifndef PIPELINE_NAME_SIZE
-#define PIPELINE_NAME_SIZE 64
-#endif
-
-#ifndef PIPELINE_TYPE_SIZE
-#define PIPELINE_TYPE_SIZE 64
-#endif
-
-#ifndef PIPELINE_MAX_PORT_IN
-#define PIPELINE_MAX_PORT_IN 64
-#endif
-
-#ifndef PIPELINE_MAX_PORT_OUT
-#define PIPELINE_MAX_PORT_OUT 64
-#endif
-
-#ifndef PIPELINE_MAX_TABLES
-#define PIPELINE_MAX_TABLES 16
-#endif
-
-#ifndef PIPELINE_MAX_MSGQ_IN
-#define PIPELINE_MAX_MSGQ_IN 16
-#endif
-
-#ifndef PIPELINE_MAX_MSGQ_OUT
-#define PIPELINE_MAX_MSGQ_OUT 16
-#endif
-
-#ifndef PIPELINE_MAX_ARGS
-#define PIPELINE_MAX_ARGS 64
-#endif
-
-struct pipeline_params {
- char name[PIPELINE_NAME_SIZE];
- char type[PIPELINE_TYPE_SIZE];
-
- struct pipeline_port_in_params port_in[PIPELINE_MAX_PORT_IN];
- struct pipeline_port_out_params port_out[PIPELINE_MAX_PORT_OUT];
- struct rte_ring *msgq_in[PIPELINE_MAX_MSGQ_IN];
- struct rte_ring *msgq_out[PIPELINE_MAX_MSGQ_OUT];
-
- uint32_t n_ports_in;
- uint32_t n_ports_out;
- uint32_t n_msgq;
-
- int socket_id;
-
- char *args_name[PIPELINE_MAX_ARGS];
- char *args_value[PIPELINE_MAX_ARGS];
- uint32_t n_args;
-
- uint32_t log_level;
-};
-
-/*
- * Pipeline type back-end operations
- */
-
-typedef void* (*pipeline_be_op_init)(struct pipeline_params *params,
- void *arg);
-
-typedef int (*pipeline_be_op_free)(void *pipeline);
-
-typedef int (*pipeline_be_op_run)(void *pipeline);
-
-typedef int (*pipeline_be_op_timer)(void *pipeline);
-
-struct pipeline_be_ops {
- pipeline_be_op_init f_init;
- pipeline_be_op_free f_free;
- pipeline_be_op_run f_run;
- pipeline_be_op_timer f_timer;
-};
-
-/* Pipeline specific config parse error messages */
-#define PIPELINE_ARG_CHECK(exp, fmt, ...) \
-do { \
- if (!(exp)) { \
- fprintf(stderr, fmt "\n", ## __VA_ARGS__); \
- return -1; \
- } \
-} while (0)
-
-#define PIPELINE_PARSE_ERR_INV_VAL(exp, section, entry, val) \
-PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": entry \"%s\" " \
- "has invalid value (\"%s\")", section, entry, val)
-
-#define PIPELINE_PARSE_ERR_OUT_RNG(exp, section, entry, val) \
-PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": entry \"%s\" " \
- "value is out of range (\"%s\")", section, entry, val)
-
-#define PIPELINE_PARSE_ERR_DUPLICATE(exp, section, entry) \
-PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": duplicated " \
- "entry \"%s\"", section, entry)
-
-#define PIPELINE_PARSE_ERR_INV_ENT(exp, section, entry) \
-PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": invalid entry " \
- "\"%s\"", section, entry)
-
-#define PIPELINE_PARSE_ERR_MANDATORY(exp, section, entry) \
-PIPELINE_ARG_CHECK(exp, "Parse error in section \"%s\": mandatory " \
- "entry \"%s\" is missing", section, entry)
-
-#endif
diff --git a/examples/ip_pipeline/swq.c b/examples/ip_pipeline/swq.c
new file mode 100644
index 00000000..7e54a1db
--- /dev/null
+++ b/examples/ip_pipeline/swq.c
@@ -0,0 +1,76 @@
+/* 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
new file mode 100644
index 00000000..c8440ee3
--- /dev/null
+++ b/examples/ip_pipeline/swq.h
@@ -0,0 +1,37 @@
+/* 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
new file mode 100644
index 00000000..11e4ad20
--- /dev/null
+++ b/examples/ip_pipeline/tap.c
@@ -0,0 +1,102 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <netinet/in.h>
+#ifdef RTE_EXEC_ENV_LINUXAPP
+#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_LINUXAPP
+
+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 */
+ snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
+
+ 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
new file mode 100644
index 00000000..0dce72fe
--- /dev/null
+++ b/examples/ip_pipeline/tap.h
@@ -0,0 +1,29 @@
+/* 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
index 9013afd1..7fc03332 100644
--- a/examples/ip_pipeline/thread.c
+++ b/examples/ip_pipeline/thread.c
@@ -1,291 +1,2968 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
*/
+#include <stdlib.h>
+
#include <rte_common.h>
#include <rte_cycles.h>
-#include <rte_pipeline.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 "pipeline_common_be.h"
-#include "app.h"
+#include "common.h"
#include "thread.h"
+#include "pipeline.h"
-#if APP_THREAD_HEADROOM_STATS_COLLECT
-
-#define PIPELINE_RUN_REGULAR(thread, pipeline) \
-do { \
- uint64_t t0 = rte_rdtsc_precise(); \
- int n_pkts = rte_pipeline_run(pipeline->p); \
- \
- if (n_pkts == 0) { \
- uint64_t t1 = rte_rdtsc_precise(); \
- \
- thread->headroom_cycles += t1 - t0; \
- } \
-} while (0)
-
-
-#define PIPELINE_RUN_CUSTOM(thread, data) \
-do { \
- uint64_t t0 = rte_rdtsc_precise(); \
- int n_pkts = data->f_run(data->be); \
- \
- if (n_pkts == 0) { \
- uint64_t t1 = rte_rdtsc_precise(); \
- \
- thread->headroom_cycles += t1 - t0; \
- } \
-} while (0)
-
-#else
-
-#define PIPELINE_RUN_REGULAR(thread, pipeline) \
- rte_pipeline_run(pipeline->p)
-
-#define PIPELINE_RUN_CUSTOM(thread, data) \
- data->f_run(data->be)
+#ifndef THREAD_PIPELINES_MAX
+#define THREAD_PIPELINES_MAX 256
+#endif
+#ifndef THREAD_MSGQ_SIZE
+#define THREAD_MSGQ_SIZE 64
#endif
-static inline void *
-thread_msg_recv(struct rte_ring *r)
+#ifndef THREAD_TIMER_PERIOD_MS
+#define THREAD_TIMER_PERIOD_MS 100
+#endif
+
+/**
+ * Master thead: 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 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;
+} __rte_cache_aligned;
+
+static struct thread_data thread_data[RTE_MAX_LCORE];
+
+/**
+ * Master 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 */
+ if (t->msgq_req)
+ rte_ring_free(t->msgq_req);
+
+ if (t->msgq_rsp)
+ rte_ring_free(t->msgq_rsp);
+ }
+}
+
+int
+thread_init(void)
+{
+ uint32_t i;
+
+ RTE_LCORE_FOREACH_SLAVE(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;
+ }
+
+ /* Master 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);
+}
+
+/**
+ * Master 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;
+};
+
+/**
+ * Master 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* 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)
{
- void *msg;
- int status = rte_ring_sc_dequeue(r, &msg);
+ struct thread_msg_req *req;
+
+ int status = rte_ring_sc_dequeue(msgq_req, (void **) &req);
if (status != 0)
return NULL;
- return msg;
+ return req;
}
static inline void
-thread_msg_send(struct rte_ring *r,
- void *msg)
+thread_msg_send(struct rte_ring *msgq_rsp,
+ struct thread_msg_rsp *rsp)
{
int status;
do {
- status = rte_ring_sp_enqueue(r, msg);
+ 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);
+ }
+}
+
+/**
+ * Master 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_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_match *match;
+ struct table_rule_action *action;
+ void **data;
+ uint32_t n_rules;
+ 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 {
+ enum pipeline_req_type type;
+ uint32_t id; /* Port IN, port OUT or table ID */
+
+ RTE_STD_C11
+ 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_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 {
+ int status;
+
+ RTE_STD_C11
+ 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;
+ };
+};
+
+/**
+ * Master 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status)
+ 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status)
+ 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status)
+ 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
-thread_pipeline_enable(struct app_thread_data *t,
- struct thread_pipeline_enable_msg_req *req)
+action_check(struct table_rule_action *action,
+ struct pipeline *p,
+ uint32_t table_id)
{
- struct app_thread_pipeline_data *p;
+ 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 (req->f_run == NULL) {
- if (t->n_regular >= APP_MAX_THREAD_PIPELINES)
+ if ((action->fwd.action == RTE_PIPELINE_ACTION_TABLE) &&
+ (action->fwd.id >= p->n_tables))
return -1;
- } else {
- if (t->n_custom >= APP_MAX_THREAD_PIPELINES)
+ }
+
+ 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;
}
- p = (req->f_run == NULL) ?
- &t->regular[t->n_regular] :
- &t->custom[t->n_custom];
+ 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;
- p->pipeline_id = req->pipeline_id;
- p->be = req->be;
- p->f_run = req->f_run;
- p->f_timer = req->f_timer;
- p->timer_period = req->timer_period;
- p->deadline = 0;
+ if ((subport_id >= n_subports_per_port) ||
+ (pipe_id >= n_pipes_per_subport))
+ return -1;
+ }
- if (req->f_run == NULL)
- t->n_regular++;
- else
- t->n_custom++;
+ 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
-thread_pipeline_disable(struct app_thread_data *t,
- struct thread_pipeline_disable_msg_req *req)
+action_default_check(struct table_rule_action *action,
+ struct pipeline *p,
+ uint32_t table_id)
{
- uint32_t n_regular = RTE_MIN(t->n_regular, RTE_DIM(t->regular));
- uint32_t n_custom = RTE_MIN(t->n_custom, RTE_DIM(t->custom));
- uint32_t i;
+ if ((action == NULL) ||
+ (action->action_mask != (1LLU << RTE_TABLE_ACTION_FWD)) ||
+ (p == NULL) ||
+ (table_id >= p->n_tables))
+ return -1;
- /* search regular pipelines of current thread */
- for (i = 0; i < n_regular; i++) {
- if (t->regular[i].pipeline_id != req->pipeline_id)
- continue;
+ 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 (i < n_regular - 1)
- memcpy(&t->regular[i],
- &t->regular[i+1],
- (n_regular - 1 - i) * sizeof(struct app_thread_pipeline_data));
+ return 0;
+}
- n_regular--;
- t->n_regular = n_regular;
+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);
+
+int
+pipeline_table_rule_add(const char *pipeline_name,
+ uint32_t table_id,
+ struct table_rule_match *match,
+ struct table_rule_action *action,
+ void **data)
+{
+ struct pipeline *p;
+ struct pipeline_msg_req *req;
+ struct pipeline_msg_rsp *rsp;
+ int status;
+
+ /* Check input params */
+ if ((pipeline_name == NULL) ||
+ (match == NULL) ||
+ (action == NULL) ||
+ (data == 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;
+
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+ 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)
+ 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);
+ return -1;
+ }
+
+ status = action_convert(a, action, data_in);
+ if (status) {
+ free(buffer);
+ 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);
+ return -1;
+ }
+
+ /* Write Response */
+ *data = data_out;
+
+ free(buffer);
return 0;
}
- /* search custom pipelines of current thread */
- for (i = 0; i < n_custom; i++) {
- if (t->custom[i].pipeline_id != req->pipeline_id)
- continue;
+ /* Allocate request */
+ req = pipeline_msg_alloc();
+ if (req == NULL)
+ 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);
+ if (rsp == NULL)
+ return -1;
- if (i < n_custom - 1)
- memcpy(&t->custom[i],
- &t->custom[i+1],
- (n_custom - 1 - i) * sizeof(struct app_thread_pipeline_data));
+ /* Read response */
+ status = rsp->status;
+ if (status == 0)
+ *data = rsp->table_rule_add.data;
- n_custom--;
- t->n_custom = n_custom;
+ /* 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,
+ void **data)
+{
+ struct pipeline *p;
+ struct pipeline_msg_req *req;
+ struct pipeline_msg_rsp *rsp;
+ int status;
+
+ /* Check input params */
+ if ((pipeline_name == NULL) ||
+ (action == NULL) ||
+ (data == 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;
+
+ 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)
+ 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);
+ return -1;
+ }
+
+ /* Write Response */
+ *data = data_out;
+
+ free(buffer);
return 0;
}
- /* return if pipeline not found */
- return -1;
+ /* Allocate request */
+ req = pipeline_msg_alloc();
+ if (req == NULL)
+ 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status == 0)
+ *data = rsp->table_rule_add_default.data;
+
+ /* Free response */
+ pipeline_msg_free(rsp);
+
+ return status;
}
-static int
-thread_msg_req_handle(struct app_thread_data *t)
+int
+pipeline_table_rule_add_bulk(const char *pipeline_name,
+ uint32_t table_id,
+ struct table_rule_match *match,
+ struct table_rule_action *action,
+ void **data,
+ uint32_t *n_rules)
{
- void *msg_ptr;
- struct thread_msg_req *req;
- struct thread_msg_rsp *rsp;
+ struct pipeline *p;
+ struct pipeline_msg_req *req;
+ struct pipeline_msg_rsp *rsp;
+ uint32_t i;
+ int status;
- msg_ptr = thread_msg_recv(t->msgq_in);
- req = msg_ptr;
- rsp = msg_ptr;
+ /* Check input params */
+ if ((pipeline_name == NULL) ||
+ (match == NULL) ||
+ (action == NULL) ||
+ (data == NULL) ||
+ (n_rules == NULL) ||
+ (*n_rules == 0))
+ return -1;
- if (req != NULL)
- switch (req->type) {
- case THREAD_MSG_REQ_PIPELINE_ENABLE: {
- rsp->status = thread_pipeline_enable(t,
- (struct thread_pipeline_enable_msg_req *) req);
- thread_msg_send(t->msgq_out, rsp);
- break;
+ p = pipeline_find(pipeline_name);
+ if ((p == NULL) ||
+ (table_id >= p->n_tables))
+ return -1;
+
+ for (i = 0; i < *n_rules; i++)
+ if (match_check(match, p, table_id) ||
+ action_check(action, p, table_id))
+ return -1;
+
+ if (!pipeline_is_running(p)) {
+ struct rte_table_action *a = p->table[table_id].a;
+ union table_rule_match_low_level *match_ll;
+ uint8_t *action_ll;
+ void **match_ll_ptr;
+ struct rte_pipeline_table_entry **action_ll_ptr;
+ struct rte_pipeline_table_entry **entries_ptr =
+ (struct rte_pipeline_table_entry **)data;
+ uint32_t bulk =
+ (p->table[table_id].params.match_type == TABLE_ACL) ? 1 : 0;
+ int *found;
+
+ /* Memory allocation */
+ match_ll = calloc(*n_rules, sizeof(union table_rule_match_low_level));
+ action_ll = calloc(*n_rules, TABLE_RULE_ACTION_SIZE_MAX);
+ match_ll_ptr = calloc(*n_rules, sizeof(void *));
+ action_ll_ptr =
+ calloc(*n_rules, sizeof(struct rte_pipeline_table_entry *));
+ found = calloc(*n_rules, sizeof(int));
+
+ if (match_ll == NULL ||
+ action_ll == NULL ||
+ match_ll_ptr == NULL ||
+ action_ll_ptr == NULL ||
+ found == NULL)
+ goto fail;
+
+ for (i = 0; i < *n_rules; 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];
}
- case THREAD_MSG_REQ_PIPELINE_DISABLE: {
- rsp->status = thread_pipeline_disable(t,
- (struct thread_pipeline_disable_msg_req *) req);
- thread_msg_send(t->msgq_out, rsp);
- break;
+ /* Rule match conversion */
+ for (i = 0; i < *n_rules; i++) {
+ status = match_convert(&match[i], match_ll_ptr[i], 1);
+ if (status)
+ goto fail;
}
- case THREAD_MSG_REQ_HEADROOM_READ: {
- struct thread_headroom_read_msg_rsp *rsp =
- (struct thread_headroom_read_msg_rsp *)
- req;
+ /* Rule action conversion */
+ for (i = 0; i < *n_rules; i++) {
+ status = action_convert(a, &action[i], action_ll_ptr[i]);
+ if (status)
+ goto fail;
+ }
- rsp->headroom_ratio = t->headroom_ratio;
- rsp->status = 0;
- thread_msg_send(t->msgq_out, rsp);
- break;
+ /* Add rule (match, action) to table */
+ if (bulk) {
+ status = rte_pipeline_table_entry_add_bulk(p->p,
+ table_id,
+ match_ll_ptr,
+ action_ll_ptr,
+ *n_rules,
+ found,
+ entries_ptr);
+ if (status)
+ *n_rules = 0;
+ } else {
+ for (i = 0; i < *n_rules; i++) {
+ status = rte_pipeline_table_entry_add(p->p,
+ table_id,
+ match_ll_ptr[i],
+ action_ll_ptr[i],
+ &found[i],
+ &entries_ptr[i]);
+ if (status) {
+ *n_rules = i;
+ break;
+ }
+ }
}
- default:
- break;
+
+ /* Free */
+ free(found);
+ free(action_ll_ptr);
+ free(match_ll_ptr);
+ free(action_ll);
+ free(match_ll);
+
+ return status;
+
+fail:
+ free(found);
+ free(action_ll_ptr);
+ free(match_ll_ptr);
+ free(action_ll);
+ free(match_ll);
+
+ *n_rules = 0;
+ return -1;
+ }
+
+ /* Allocate request */
+ req = pipeline_msg_alloc();
+ if (req == NULL)
+ return -1;
+
+ /* Write request */
+ req->type = PIPELINE_REQ_TABLE_RULE_ADD_BULK;
+ req->id = table_id;
+ req->table_rule_add_bulk.match = match;
+ req->table_rule_add_bulk.action = action;
+ req->table_rule_add_bulk.data = data;
+ req->table_rule_add_bulk.n_rules = *n_rules;
+ req->table_rule_add_bulk.bulk =
+ (p->table[table_id].params.match_type == TABLE_ACL) ? 1 : 0;
+
+ /* Send request and wait for response */
+ rsp = pipeline_msg_send_recv(p, req);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status == 0)
+ *n_rules = rsp->table_rule_add_bulk.n_rules;
+
+ /* 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 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;
+
+ 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);
+
+ 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+
+ /* 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 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)) {
+ status = rte_pipeline_table_default_entry_delete(p->p,
+ table_id,
+ NULL);
+
+ 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+
+ /* Free response */
+ pipeline_msg_free(rsp);
+
+ return status;
+}
+
+int
+pipeline_table_rule_stats_read(const char *pipeline_name,
+ uint32_t table_id,
+ void *data,
+ struct rte_table_action_stats_counters *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) ||
+ (data == 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)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_stats_read(a,
+ 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 = data;
+ req->table_rule_stats_read.clear = clear;
+
+ /* Send request and wait for response */
+ rsp = pipeline_msg_send_recv(p, req);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status)
+ 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* 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,
+ void *data,
+ uint32_t tc_mask,
+ struct rte_table_action_mtr_counters *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) ||
+ (data == 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)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_meter_read(a,
+ 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 = 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status)
+ 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);
+ if (rsp == NULL)
+ return -1;
+
+ /* 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,
+ void *data,
+ struct rte_table_action_ttl_counters *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) ||
+ (data == 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)) {
+ struct rte_table_action *a = p->table[table_id].a;
+
+ status = rte_table_action_ttl_read(a,
+ 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 = data;
+ req->table_rule_ttl_read.clear = clear;
+
+ /* Send request and wait for response */
+ rsp = pipeline_msg_send_recv(p, req);
+ if (rsp == NULL)
+ return -1;
+
+ /* Read response */
+ status = rsp->status;
+ if (status)
+ memcpy(stats, &rsp->table_rule_ttl_read.stats, sizeof(*stats));
+
+ /* 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 = sa32[0];
+ ml->acl_add.field_value[1].mask_range.u32 =
+ sa32_depth[0];
+ ml->acl_add.field_value[2].value.u32 = sa32[1];
+ ml->acl_add.field_value[2].mask_range.u32 =
+ sa32_depth[1];
+ ml->acl_add.field_value[3].value.u32 = sa32[2];
+ ml->acl_add.field_value[3].mask_range.u32 =
+ sa32_depth[2];
+ ml->acl_add.field_value[4].value.u32 = sa32[3];
+ ml->acl_add.field_value[4].mask_range.u32 =
+ sa32_depth[3];
+
+ ml->acl_add.field_value[5].value.u32 = da32[0];
+ ml->acl_add.field_value[5].mask_range.u32 =
+ da32_depth[0];
+ ml->acl_add.field_value[6].value.u32 = da32[1];
+ ml->acl_add.field_value[6].mask_range.u32 =
+ da32_depth[1];
+ ml->acl_add.field_value[7].value.u32 = da32[2];
+ ml->acl_add.field_value[7].mask_range.u32 =
+ da32_depth[2];
+ ml->acl_add.field_value[8].value.u32 = 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 =
+ sa32[0];
+ ml->acl_delete.field_value[1].mask_range.u32 =
+ sa32_depth[0];
+ ml->acl_delete.field_value[2].value.u32 =
+ sa32[1];
+ ml->acl_delete.field_value[2].mask_range.u32 =
+ sa32_depth[1];
+ ml->acl_delete.field_value[3].value.u32 =
+ sa32[2];
+ ml->acl_delete.field_value[3].mask_range.u32 =
+ sa32_depth[2];
+ ml->acl_delete.field_value[4].value.u32 =
+ sa32[3];
+ ml->acl_delete.field_value[4].mask_range.u32 =
+ sa32_depth[3];
+
+ ml->acl_delete.field_value[5].value.u32 =
+ da32[0];
+ ml->acl_delete.field_value[5].mask_range.u32 =
+ da32_depth[0];
+ ml->acl_delete.field_value[6].value.u32 =
+ da32[1];
+ ml->acl_delete.field_value[6].mask_range.u32 =
+ da32_depth[1];
+ ml->acl_delete.field_value[7].value.u32 =
+ da32[2];
+ ml->acl_delete.field_value[7].mask_range.u32 =
+ da32_depth[2];
+ ml->acl_delete.field_value[8].value.u32 =
+ 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 {
+ memcpy(ml->lpm_ipv6.ip,
+ mh->match.lpm.ipv6, sizeof(ml->lpm_ipv6.ip));
+ 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;
+ }
+
return 0;
}
-static void
-thread_headroom_update(struct app_thread_data *t, uint64_t time)
+static struct pipeline_msg_rsp *
+pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
+ struct pipeline_msg_req *req)
{
- uint64_t time_diff = time - t->headroom_time;
+ 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;
+ }
- t->headroom_ratio =
- ((double) t->headroom_cycles) / ((double) time_diff);
+ /* Write response */
+ rsp->status = 0;
+ rsp->table_rule_add.data = data_out;
- t->headroom_cycles = 0;
- t->headroom_time = rte_rdtsc_precise();
+ return rsp;
}
-int
-app_thread(void *arg)
+static struct pipeline_msg_rsp *
+pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,
+ struct pipeline_msg_req *req)
{
- struct app_params *app = (struct app_params *) arg;
- uint32_t core_id = rte_lcore_id(), i, j;
- struct app_thread_data *t = &app->thread_data[core_id];
+ 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;
- for (i = 0; ; i++) {
- uint32_t n_regular = RTE_MIN(t->n_regular, RTE_DIM(t->regular));
- uint32_t n_custom = RTE_MIN(t->n_custom, RTE_DIM(t->custom));
+ /* 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;
+ }
- /* Run regular pipelines */
- for (j = 0; j < n_regular; j++) {
- struct app_thread_pipeline_data *data = &t->regular[j];
- struct pipeline *p = data->be;
+ /* Write response */
+ rsp->status = 0;
+ rsp->table_rule_add_default.data = data_out;
- PIPELINE_RUN_REGULAR(t, p);
+ 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_match *match = req->table_rule_add_bulk.match;
+ struct table_rule_action *action = req->table_rule_add_bulk.action;
+ struct rte_pipeline_table_entry **data =
+ (struct rte_pipeline_table_entry **)req->table_rule_add_bulk.data;
+ uint32_t n_rules = req->table_rule_add_bulk.n_rules;
+ uint32_t bulk = req->table_rule_add_bulk.bulk;
+
+ struct rte_table_action *a = p->table_data[table_id].a;
+ union table_rule_match_low_level *match_ll;
+ uint8_t *action_ll;
+ void **match_ll_ptr;
+ struct rte_pipeline_table_entry **action_ll_ptr;
+ int *found, status;
+ uint32_t i;
+
+ /* Memory allocation */
+ match_ll = calloc(n_rules, sizeof(union table_rule_match_low_level));
+ action_ll = calloc(n_rules, TABLE_RULE_ACTION_SIZE_MAX);
+ match_ll_ptr = calloc(n_rules, sizeof(void *));
+ action_ll_ptr =
+ calloc(n_rules, sizeof(struct rte_pipeline_table_entry *));
+ found = calloc(n_rules, sizeof(int));
+
+ if ((match_ll == NULL) ||
+ (action_ll == NULL) ||
+ (match_ll_ptr == NULL) ||
+ (action_ll_ptr == NULL) ||
+ (found == NULL))
+ goto fail;
+
+ for (i = 0; i < n_rules; 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 conversion */
+ for (i = 0; i < n_rules; i++) {
+ status = match_convert(&match[i], match_ll_ptr[i], 1);
+ if (status)
+ goto fail;
+ }
+
+ /* Rule action conversion */
+ for (i = 0; i < n_rules; i++) {
+ status = action_convert(a, &action[i], action_ll_ptr[i]);
+ if (status)
+ goto fail;
+ }
+
+ /* Add rule (match, action) to table */
+ if (bulk) {
+ status = rte_pipeline_table_entry_add_bulk(p->p,
+ table_id,
+ match_ll_ptr,
+ action_ll_ptr,
+ n_rules,
+ found,
+ data);
+ if (status)
+ n_rules = 0;
+ } else
+ for (i = 0; i < n_rules; i++) {
+ status = rte_pipeline_table_entry_add(p->p,
+ table_id,
+ match_ll_ptr[i],
+ action_ll_ptr[i],
+ &found[i],
+ &data[i]);
+ if (status) {
+ n_rules = i;
+ break;
+ }
}
- /* Run custom pipelines */
- for (j = 0; j < n_custom; j++) {
- struct app_thread_pipeline_data *data = &t->custom[j];
+ /* Write response */
+ rsp->status = 0;
+ rsp->table_rule_add_bulk.n_rules = n_rules;
+
+ /* Free */
+ free(found);
+ free(action_ll_ptr);
+ free(match_ll_ptr);
+ free(action_ll);
+ free(match_ll);
+
+ return rsp;
+
+fail:
+ free(found);
+ free(action_ll_ptr);
+ free(match_ll_ptr);
+ free(action_ll);
+ free(match_ll);
+
+ rsp->status = -1;
+ rsp->table_rule_add_bulk.n_rules = 0;
+ 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 void
+pipeline_msg_handle(struct pipeline_data *p)
+{
+ for ( ; ; ) {
+ struct pipeline_msg_req *req;
+ struct pipeline_msg_rsp *rsp;
- PIPELINE_RUN_CUSTOM(t, data);
+ 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;
+
+ default:
+ rsp = (struct pipeline_msg_rsp *) req;
+ rsp->status = -1;
}
- /* Timer */
- if ((i & 0xF) == 0) {
- uint64_t time = rte_get_tsc_cycles();
- uint64_t t_deadline = UINT64_MAX;
+ pipeline_msg_send(p->msgq_rsp, rsp);
+ }
+}
- if (time < t->deadline)
- continue;
+/**
+ * Data plane threads: main
+ */
+int
+thread_main(void *arg __rte_unused)
+{
+ struct thread_data *t;
+ uint32_t thread_id, i;
- /* Timer for regular pipelines */
- for (j = 0; j < n_regular; j++) {
- struct app_thread_pipeline_data *data =
- &t->regular[j];
- uint64_t p_deadline = data->deadline;
+ thread_id = rte_lcore_id();
+ t = &thread_data[thread_id];
- if (p_deadline <= time) {
- data->f_timer(data->be);
- p_deadline = time + data->timer_period;
- data->deadline = p_deadline;
- }
+ /* Dispatch loop */
+ for (i = 0; ; i++) {
+ uint32_t j;
- if (p_deadline < t_deadline)
- t_deadline = p_deadline;
- }
+ /* Data Plane */
+ for (j = 0; j < t->n_pipelines; j++)
+ rte_pipeline_run(t->p[j]);
- /* Timer for custom pipelines */
- for (j = 0; j < n_custom; j++) {
- struct app_thread_pipeline_data *data =
- &t->custom[j];
- uint64_t p_deadline = data->deadline;
+ /* 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 (p_deadline <= time) {
- data->f_timer(data->be);
- p_deadline = time + data->timer_period;
- data->deadline = p_deadline;
+ 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 (p_deadline < t_deadline)
- t_deadline = p_deadline;
+ if (time_next < time_next_min)
+ time_next_min = time_next;
}
- /* Timer for thread message request */
+ /* Thread message queues */
{
- uint64_t deadline = t->thread_req_deadline;
+ uint64_t time_next = t->time_next;
- if (deadline <= time) {
- thread_msg_req_handle(t);
- thread_headroom_update(t, time);
- deadline = time + t->timer_period;
- t->thread_req_deadline = deadline;
+ if (time_next <= time) {
+ thread_msg_handle(t);
+ time_next = time + t->timer_period;
+ t->time_next = time_next;
}
- if (deadline < t_deadline)
- t_deadline = deadline;
+ if (time_next < time_next_min)
+ time_next_min = time_next;
}
-
- t->deadline = t_deadline;
+ t->time_next_min = time_next_min;
}
}
diff --git a/examples/ip_pipeline/thread.h b/examples/ip_pipeline/thread.h
index 2c4fb6ae..facdf004 100644
--- a/examples/ip_pipeline/thread.h
+++ b/examples/ip_pipeline/thread.h
@@ -1,69 +1,24 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
+ * Copyright(c) 2010-2018 Intel Corporation
*/
-#ifndef THREAD_H_
-#define THREAD_H_
+#ifndef _INCLUDE_THREAD_H_
+#define _INCLUDE_THREAD_H_
-#include "app.h"
-#include "pipeline_be.h"
+#include <stdint.h>
-enum thread_msg_req_type {
- THREAD_MSG_REQ_PIPELINE_ENABLE = 0,
- THREAD_MSG_REQ_PIPELINE_DISABLE,
- THREAD_MSG_REQ_HEADROOM_READ,
- THREAD_MSG_REQS
-};
+int
+thread_pipeline_enable(uint32_t thread_id,
+ const char *pipeline_name);
-struct thread_msg_req {
- enum thread_msg_req_type type;
-};
+int
+thread_pipeline_disable(uint32_t thread_id,
+ const char *pipeline_name);
-struct thread_msg_rsp {
- int status;
-};
+int
+thread_init(void);
-/*
- * PIPELINE ENABLE
- */
-struct thread_pipeline_enable_msg_req {
- enum thread_msg_req_type type;
-
- uint32_t pipeline_id;
- void *be;
- pipeline_be_op_run f_run;
- pipeline_be_op_timer f_timer;
- uint64_t timer_period;
-};
-
-struct thread_pipeline_enable_msg_rsp {
- int status;
-};
-
-/*
- * PIPELINE DISABLE
- */
-struct thread_pipeline_disable_msg_req {
- enum thread_msg_req_type type;
-
- uint32_t pipeline_id;
-};
-
-struct thread_pipeline_disable_msg_rsp {
- int status;
-};
-
-/*
- * THREAD HEADROOM
- */
-struct thread_headroom_read_msg_req {
- enum thread_msg_req_type type;
-};
-
-struct thread_headroom_read_msg_rsp {
- int status;
-
- double headroom_ratio;
-};
+int
+thread_main(void *arg);
-#endif /* THREAD_H_ */
+#endif /* _INCLUDE_THREAD_H_ */
diff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread_fe.c
deleted file mode 100644
index 4590c2b5..00000000
--- a/examples/ip_pipeline/thread_fe.c
+++ /dev/null
@@ -1,457 +0,0 @@
-#include <rte_common.h>
-#include <rte_ring.h>
-#include <rte_malloc.h>
-#include <cmdline_rdline.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_num.h>
-#include <cmdline_parse_string.h>
-
-#include "thread.h"
-#include "thread_fe.h"
-#include "pipeline.h"
-#include "pipeline_common_fe.h"
-#include "app.h"
-
-static inline void *
-thread_msg_send_recv(struct app_params *app,
- uint32_t socket_id, uint32_t core_id, uint32_t ht_id,
- void *msg,
- uint32_t timeout_ms)
-{
- struct rte_ring *r_req = app_thread_msgq_in_get(app,
- socket_id, core_id, ht_id);
- struct rte_ring *r_rsp = app_thread_msgq_out_get(app,
- socket_id, core_id, ht_id);
- uint64_t hz = rte_get_tsc_hz();
- void *msg_recv;
- uint64_t deadline;
- int status;
-
- /* send */
- do {
- status = rte_ring_sp_enqueue(r_req, (void *) msg);
- } while (status == -ENOBUFS);
-
- /* recv */
- deadline = (timeout_ms) ?
- (rte_rdtsc() + ((hz * timeout_ms) / 1000)) :
- UINT64_MAX;
-
- do {
- if (rte_rdtsc() > deadline)
- return NULL;
-
- status = rte_ring_sc_dequeue(r_rsp, &msg_recv);
- } while (status != 0);
-
- return msg_recv;
-}
-
-int
-app_pipeline_enable(struct app_params *app,
- uint32_t socket_id,
- uint32_t core_id,
- uint32_t hyper_th_id,
- uint32_t pipeline_id)
-{
- struct thread_pipeline_enable_msg_req *req;
- struct thread_pipeline_enable_msg_rsp *rsp;
- int thread_id;
- struct app_pipeline_data *p;
- struct app_pipeline_params *p_params;
- struct pipeline_type *p_type;
- int status;
-
- if (app == NULL)
- return -1;
-
- thread_id = cpu_core_map_get_lcore_id(app->core_map,
- socket_id,
- core_id,
- hyper_th_id);
-
- if ((thread_id < 0) || !app_core_is_enabled(app, thread_id))
- return -1;
-
- if (app_pipeline_data(app, pipeline_id) == NULL)
- return -1;
-
- p = &app->pipeline_data[pipeline_id];
- p_params = &app->pipeline_params[pipeline_id];
- p_type = app_pipeline_type_find(app, p_params->type);
-
- if (p_type == NULL)
- return -1;
-
- if (p->enabled == 1)
- return -1;
-
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = THREAD_MSG_REQ_PIPELINE_ENABLE;
- req->pipeline_id = pipeline_id;
- req->be = p->be;
- req->f_run = p_type->be_ops->f_run;
- req->f_timer = p_type->be_ops->f_timer;
- req->timer_period = p->timer_period;
-
- rsp = thread_msg_send_recv(app,
- socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT);
- if (rsp == NULL)
- return -1;
-
- status = rsp->status;
- app_msg_free(app, rsp);
-
- if (status != 0)
- return -1;
-
- p->enabled = 1;
- return 0;
-}
-
-int
-app_pipeline_disable(struct app_params *app,
- uint32_t socket_id,
- uint32_t core_id,
- uint32_t hyper_th_id,
- uint32_t pipeline_id)
-{
- struct thread_pipeline_disable_msg_req *req;
- struct thread_pipeline_disable_msg_rsp *rsp;
- int thread_id;
- struct app_pipeline_data *p;
- int status;
-
- if (app == NULL)
- return -1;
-
- thread_id = cpu_core_map_get_lcore_id(app->core_map,
- socket_id,
- core_id,
- hyper_th_id);
-
- if ((thread_id < 0) || !app_core_is_enabled(app, thread_id))
- return -1;
-
- if (app_pipeline_data(app, pipeline_id) == NULL)
- return -1;
-
- p = &app->pipeline_data[pipeline_id];
-
- if (p->enabled == 0)
- return -1;
-
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = THREAD_MSG_REQ_PIPELINE_DISABLE;
- req->pipeline_id = pipeline_id;
-
- rsp = thread_msg_send_recv(app,
- socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT);
-
- if (rsp == NULL)
- return -1;
-
- status = rsp->status;
- app_msg_free(app, rsp);
-
- if (status != 0)
- return -1;
-
- p->enabled = 0;
- return 0;
-}
-
-int
-app_thread_headroom(struct app_params *app,
- uint32_t socket_id,
- uint32_t core_id,
- uint32_t hyper_th_id)
-{
- struct thread_headroom_read_msg_req *req;
- struct thread_headroom_read_msg_rsp *rsp;
- int thread_id;
- int status;
-
- if (app == NULL)
- return -1;
-
- thread_id = cpu_core_map_get_lcore_id(app->core_map,
- socket_id,
- core_id,
- hyper_th_id);
-
- if ((thread_id < 0) || !app_core_is_enabled(app, thread_id))
- return -1;
-
- req = app_msg_alloc(app);
- if (req == NULL)
- return -1;
-
- req->type = THREAD_MSG_REQ_HEADROOM_READ;
-
- rsp = thread_msg_send_recv(app,
- socket_id, core_id, hyper_th_id, req, MSG_TIMEOUT_DEFAULT);
-
- if (rsp == NULL)
- return -1;
-
- status = rsp->status;
-
- if (status != 0)
- return -1;
-
- printf("%.3f%%\n", rsp->headroom_ratio * 100);
-
-
- app_msg_free(app, rsp);
-
- return 0;
-}
-
-/*
- * pipeline enable
- */
-
-struct cmd_pipeline_enable_result {
- cmdline_fixed_string_t t_string;
- cmdline_fixed_string_t t_id_string;
- cmdline_fixed_string_t pipeline_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t enable_string;
-};
-
-static void
-cmd_pipeline_enable_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_pipeline_enable_result *params = parsed_result;
- struct app_params *app = data;
- int status;
- uint32_t core_id, socket_id, hyper_th_id;
-
- if (parse_pipeline_core(&socket_id,
- &core_id,
- &hyper_th_id,
- params->t_id_string) != 0) {
- printf("Command failed\n");
- return;
- }
-
- status = app_pipeline_enable(app,
- socket_id,
- core_id,
- hyper_th_id,
- params->pipeline_id);
-
- if (status != 0)
- printf("Command failed\n");
-}
-
-static cmdline_parse_token_string_t cmd_pipeline_enable_t_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, t_string, "t");
-
-static cmdline_parse_token_string_t cmd_pipeline_enable_t_id_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, t_id_string,
- NULL);
-
-static cmdline_parse_token_string_t cmd_pipeline_enable_pipeline_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, pipeline_string,
- "pipeline");
-
-static cmdline_parse_token_num_t cmd_pipeline_enable_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_pipeline_enable_result, pipeline_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_pipeline_enable_enable_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_enable_result, enable_string,
- "enable");
-
-static cmdline_parse_inst_t cmd_pipeline_enable = {
- .f = cmd_pipeline_enable_parsed,
- .data = NULL,
- .help_str = "Enable pipeline on specified core",
- .tokens = {
- (void *)&cmd_pipeline_enable_t_string,
- (void *)&cmd_pipeline_enable_t_id_string,
- (void *)&cmd_pipeline_enable_pipeline_string,
- (void *)&cmd_pipeline_enable_pipeline_id,
- (void *)&cmd_pipeline_enable_enable_string,
- NULL,
- },
-};
-
-/*
- * pipeline disable
- */
-
-struct cmd_pipeline_disable_result {
- cmdline_fixed_string_t t_string;
- cmdline_fixed_string_t t_id_string;
- cmdline_fixed_string_t pipeline_string;
- uint32_t pipeline_id;
- cmdline_fixed_string_t disable_string;
-};
-
-static void
-cmd_pipeline_disable_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_pipeline_disable_result *params = parsed_result;
- struct app_params *app = data;
- int status;
- uint32_t core_id, socket_id, hyper_th_id;
-
- if (parse_pipeline_core(&socket_id,
- &core_id,
- &hyper_th_id,
- params->t_id_string) != 0) {
- printf("Command failed\n");
- return;
- }
-
- status = app_pipeline_disable(app,
- socket_id,
- core_id,
- hyper_th_id,
- params->pipeline_id);
-
- if (status != 0)
- printf("Command failed\n");
-}
-
-static cmdline_parse_token_string_t cmd_pipeline_disable_t_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, t_string, "t");
-
-static cmdline_parse_token_string_t cmd_pipeline_disable_t_id_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, t_id_string,
- NULL);
-
-static cmdline_parse_token_string_t cmd_pipeline_disable_pipeline_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result,
- pipeline_string, "pipeline");
-
-static cmdline_parse_token_num_t cmd_pipeline_disable_pipeline_id =
- TOKEN_NUM_INITIALIZER(struct cmd_pipeline_disable_result, pipeline_id,
- UINT32);
-
-static cmdline_parse_token_string_t cmd_pipeline_disable_disable_string =
- TOKEN_STRING_INITIALIZER(struct cmd_pipeline_disable_result, disable_string,
- "disable");
-
-static cmdline_parse_inst_t cmd_pipeline_disable = {
- .f = cmd_pipeline_disable_parsed,
- .data = NULL,
- .help_str = "Disable pipeline on specified core",
- .tokens = {
- (void *)&cmd_pipeline_disable_t_string,
- (void *)&cmd_pipeline_disable_t_id_string,
- (void *)&cmd_pipeline_disable_pipeline_string,
- (void *)&cmd_pipeline_disable_pipeline_id,
- (void *)&cmd_pipeline_disable_disable_string,
- NULL,
- },
-};
-
-
-/*
- * thread headroom
- */
-
-struct cmd_thread_headroom_result {
- cmdline_fixed_string_t t_string;
- cmdline_fixed_string_t t_id_string;
- cmdline_fixed_string_t headroom_string;
-};
-
-static void
-cmd_thread_headroom_parsed(
- void *parsed_result,
- __rte_unused struct cmdline *cl,
- void *data)
-{
- struct cmd_thread_headroom_result *params = parsed_result;
- struct app_params *app = data;
- int status;
- uint32_t core_id, socket_id, hyper_th_id;
-
- if (parse_pipeline_core(&socket_id,
- &core_id,
- &hyper_th_id,
- params->t_id_string) != 0) {
- printf("Command failed\n");
- return;
- }
-
- status = app_thread_headroom(app,
- socket_id,
- core_id,
- hyper_th_id);
-
- if (status != 0)
- printf("Command failed\n");
-}
-
-static cmdline_parse_token_string_t cmd_thread_headroom_t_string =
- TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
- t_string, "t");
-
-static cmdline_parse_token_string_t cmd_thread_headroom_t_id_string =
- TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
- t_id_string, NULL);
-
-static cmdline_parse_token_string_t cmd_thread_headroom_headroom_string =
- TOKEN_STRING_INITIALIZER(struct cmd_thread_headroom_result,
- headroom_string, "headroom");
-
-static cmdline_parse_inst_t cmd_thread_headroom = {
- .f = cmd_thread_headroom_parsed,
- .data = NULL,
- .help_str = "Display thread headroom",
- .tokens = {
- (void *)&cmd_thread_headroom_t_string,
- (void *)&cmd_thread_headroom_t_id_string,
- (void *)&cmd_thread_headroom_headroom_string,
- NULL,
- },
-};
-
-
-static cmdline_parse_ctx_t thread_cmds[] = {
- (cmdline_parse_inst_t *) &cmd_pipeline_enable,
- (cmdline_parse_inst_t *) &cmd_pipeline_disable,
- (cmdline_parse_inst_t *) &cmd_thread_headroom,
- NULL,
-};
-
-int
-app_pipeline_thread_cmd_push(struct app_params *app)
-{
- uint32_t n_cmds, i;
-
- /* Check for available slots in the application commands array */
- n_cmds = RTE_DIM(thread_cmds) - 1;
- if (n_cmds > APP_MAX_CMDS - app->n_cmds)
- return -ENOMEM;
-
- /* Push thread commands into the application */
- memcpy(&app->cmds[app->n_cmds], thread_cmds,
- n_cmds * sizeof(cmdline_parse_ctx_t));
-
- for (i = 0; i < n_cmds; i++)
- app->cmds[app->n_cmds + i]->data = app;
-
- app->n_cmds += n_cmds;
- app->cmds[app->n_cmds] = NULL;
-
- return 0;
-}
diff --git a/examples/ip_pipeline/thread_fe.h b/examples/ip_pipeline/thread_fe.h
deleted file mode 100644
index 056a5e8a..00000000
--- a/examples/ip_pipeline/thread_fe.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2015 Intel Corporation
- */
-
-#ifndef THREAD_FE_H_
-#define THREAD_FE_H_
-
-static inline struct rte_ring *
-app_thread_msgq_in_get(struct app_params *app,
- uint32_t socket_id, uint32_t core_id, uint32_t ht_id)
-{
- char msgq_name[32];
- ssize_t param_idx;
-
- snprintf(msgq_name, sizeof(msgq_name),
- "MSGQ-REQ-CORE-s%" PRIu32 "c%" PRIu32 "%s",
- socket_id,
- core_id,
- (ht_id) ? "h" : "");
- param_idx = APP_PARAM_FIND(app->msgq_params, msgq_name);
-
- if (param_idx < 0)
- return NULL;
-
- return app->msgq[param_idx];
-}
-
-static inline struct rte_ring *
-app_thread_msgq_out_get(struct app_params *app,
- uint32_t socket_id, uint32_t core_id, uint32_t ht_id)
-{
- char msgq_name[32];
- ssize_t param_idx;
-
- snprintf(msgq_name, sizeof(msgq_name),
- "MSGQ-RSP-CORE-s%" PRIu32 "c%" PRIu32 "%s",
- socket_id,
- core_id,
- (ht_id) ? "h" : "");
- param_idx = APP_PARAM_FIND(app->msgq_params, msgq_name);
-
- if (param_idx < 0)
- return NULL;
-
- return app->msgq[param_idx];
-
-}
-
-int
-app_pipeline_thread_cmd_push(struct app_params *app);
-
-int
-app_pipeline_enable(struct app_params *app,
- uint32_t core_id,
- uint32_t socket_id,
- uint32_t hyper_th_id,
- uint32_t pipeline_id);
-
-int
-app_pipeline_disable(struct app_params *app,
- uint32_t core_id,
- uint32_t socket_id,
- uint32_t hyper_th_id,
- uint32_t pipeline_id);
-
-int
-app_thread_headroom(struct app_params *app,
- uint32_t core_id,
- uint32_t socket_id,
- uint32_t hyper_th_id);
-
-#endif /* THREAD_FE_H_ */
diff --git a/examples/ip_pipeline/tmgr.c b/examples/ip_pipeline/tmgr.c
new file mode 100644
index 00000000..40cbf1d0
--- /dev/null
+++ b/examples/ip_pipeline/tmgr.c
@@ -0,0 +1,229 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <stdlib.h>
+
+#include <rte_string_fns.h>
+
+#include "tmgr.h"
+
+static struct rte_sched_subport_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 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_params *p)
+{
+ /* Check input params */
+ if (p == NULL)
+ return -1;
+
+ /* Save profile */
+ memcpy(&subport_profile[n_subport_profiles],
+ p,
+ sizeof(*p));
+
+ 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_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_pipes_per_subport = params->n_pipes_per_subport;
+
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
+ p.qsize[i] = params->qsize[i];
+
+ p.pipe_profiles = pipe_profile;
+ p.n_pipe_profiles = n_pipe_profiles;
+
+ s = rte_sched_port_config(&p);
+ if (s == NULL)
+ return NULL;
+
+ for (i = 0; i < params->n_subports_per_port; i++) {
+ int status;
+
+ status = rte_sched_subport_config(
+ s,
+ i,
+ &subport_profile[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,
+ &subport_profile[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
new file mode 100644
index 00000000..0b497e79
--- /dev/null
+++ b/examples/ip_pipeline/tmgr.h
@@ -0,0 +1,70 @@
+/* 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 "common.h"
+
+#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 {
+ uint32_t rate;
+ uint32_t n_subports_per_port;
+ uint32_t n_pipes_per_subport;
+ uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ uint32_t frame_overhead;
+ uint32_t mtu;
+ uint32_t cpu_id;
+};
+
+int
+tmgr_subport_profile_add(struct rte_sched_subport_params *p);
+
+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_ */