@@ -10,7 +10,6 @@ sources = files(
'conn.c',
'parser.c',
'rte_eth_softnic.c',
- 'rte_eth_softnic_action.c',
'rte_eth_softnic_cli.c',
'rte_eth_softnic_link.c',
'rte_eth_softnic_mempool.c',
@@ -160,8 +160,6 @@ pmd_dev_stop(struct rte_eth_dev *dev)
/* Firmware */
softnic_pipeline_disable_all(p);
softnic_pipeline_free(p);
- softnic_table_action_profile_free(p);
- softnic_port_in_action_profile_free(p);
softnic_link_free(p);
softnic_softnic_swq_free_keep_rxq_txq(p);
softnic_mempool_free(p);
@@ -180,8 +178,6 @@ pmd_free(struct pmd_internals *p)
softnic_thread_free(p);
softnic_pipeline_free(p);
- softnic_table_action_profile_free(p);
- softnic_port_in_action_profile_free(p);
softnic_link_free(p);
softnic_swq_free(p);
softnic_mempool_free(p);
@@ -261,8 +257,6 @@ pmd_init(struct pmd_params *params)
softnic_mempool_init(p);
softnic_swq_init(p);
softnic_link_init(p);
- softnic_port_in_action_profile_init(p);
- softnic_table_action_profile_init(p);
softnic_pipeline_init(p);
status = softnic_thread_init(p);
deleted file mode 100644
@@ -1,423 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2018 Intel Corporation
- */
-
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <rte_string_fns.h>
-#include <rte_table_hash_func.h>
-
-#include "rte_eth_softnic_internals.h"
-
-/**
- * Input port
- */
-int
-softnic_port_in_action_profile_init(struct pmd_internals *p)
-{
- TAILQ_INIT(&p->port_in_action_profile_list);
-
- return 0;
-}
-
-void
-softnic_port_in_action_profile_free(struct pmd_internals *p)
-{
- for ( ; ; ) {
- struct softnic_port_in_action_profile *profile;
-
- profile = TAILQ_FIRST(&p->port_in_action_profile_list);
- if (profile == NULL)
- break;
-
- TAILQ_REMOVE(&p->port_in_action_profile_list, profile, node);
- free(profile);
- }
-}
-
-struct softnic_port_in_action_profile *
-softnic_port_in_action_profile_find(struct pmd_internals *p,
- const char *name)
-{
- struct softnic_port_in_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &p->port_in_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct softnic_port_in_action_profile *
-softnic_port_in_action_profile_create(struct pmd_internals *p,
- const char *name,
- struct softnic_port_in_action_profile_params *params)
-{
- struct softnic_port_in_action_profile *profile;
- struct rte_port_in_action_profile *ap;
- int status;
-
- /* Check input params */
- if (name == NULL ||
- softnic_port_in_action_profile_find(p, name) ||
- params == NULL)
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) &&
- params->lb.f_hash == NULL) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
-
- /* Resource */
- ap = rte_port_in_action_profile_create(0);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_FLTR)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_FLTR,
- ¶ms->fltr);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_PORT_IN_ACTION_LB)) {
- status = rte_port_in_action_profile_action_register(ap,
- RTE_PORT_IN_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_port_in_action_profile_freeze(ap);
- if (status) {
- rte_port_in_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct softnic_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(&p->port_in_action_profile_list, profile, node);
-
- return profile;
-}
-
-/**
- * Table
- */
-int
-softnic_table_action_profile_init(struct pmd_internals *p)
-{
- TAILQ_INIT(&p->table_action_profile_list);
-
- return 0;
-}
-
-void
-softnic_table_action_profile_free(struct pmd_internals *p)
-{
- for ( ; ; ) {
- struct softnic_table_action_profile *profile;
-
- profile = TAILQ_FIRST(&p->table_action_profile_list);
- if (profile == NULL)
- break;
-
- TAILQ_REMOVE(&p->table_action_profile_list, profile, node);
- rte_table_action_profile_free(profile->ap);
- free(profile);
- }
-}
-
-struct softnic_table_action_profile *
-softnic_table_action_profile_find(struct pmd_internals *p,
- const char *name)
-{
- struct softnic_table_action_profile *profile;
-
- if (name == NULL)
- return NULL;
-
- TAILQ_FOREACH(profile, &p->table_action_profile_list, node)
- if (strcmp(profile->name, name) == 0)
- return profile;
-
- return NULL;
-}
-
-struct softnic_table_action_profile *
-softnic_table_action_profile_create(struct pmd_internals *p,
- const char *name,
- struct softnic_table_action_profile_params *params)
-{
- struct softnic_table_action_profile *profile;
- struct rte_table_action_profile *ap;
- int status;
-
- /* Check input params */
- if (name == NULL ||
- softnic_table_action_profile_find(p, name) ||
- params == NULL ||
- ((params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) == 0))
- return NULL;
-
- if ((params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) &&
- params->lb.f_hash == NULL) {
- switch (params->lb.key_size) {
- case 8:
- params->lb.f_hash = rte_table_hash_crc_key8;
- break;
-
- case 16:
- params->lb.f_hash = rte_table_hash_crc_key16;
- break;
-
- case 24:
- params->lb.f_hash = rte_table_hash_crc_key24;
- break;
-
- case 32:
- params->lb.f_hash = rte_table_hash_crc_key32;
- break;
-
- case 40:
- params->lb.f_hash = rte_table_hash_crc_key40;
- break;
-
- case 48:
- params->lb.f_hash = rte_table_hash_crc_key48;
- break;
-
- case 56:
- params->lb.f_hash = rte_table_hash_crc_key56;
- break;
-
- case 64:
- params->lb.f_hash = rte_table_hash_crc_key64;
- break;
-
- default:
- return NULL;
- }
-
- params->lb.seed = 0;
- }
-
- /* Resource */
- ap = rte_table_action_profile_create(¶ms->common);
- if (ap == NULL)
- return NULL;
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_FWD,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_LB,
- ¶ms->lb);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_MTR,
- ¶ms->mtr);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TM,
- ¶ms->tm);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_ENCAP,
- ¶ms->encap);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_NAT,
- ¶ms->nat);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TTL,
- ¶ms->ttl);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_STATS,
- ¶ms->stats);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TIME,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_TAG,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_DECAP,
- NULL);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- if (params->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_profile_action_register(ap,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- ¶ms->sym_crypto);
-
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
- }
-
- status = rte_table_action_profile_freeze(ap);
- if (status) {
- rte_table_action_profile_free(ap);
- return NULL;
- }
-
- /* Node allocation */
- profile = calloc(1, sizeof(struct softnic_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(&p->table_action_profile_list, profile, node);
-
- return profile;
-}
@@ -196,6 +196,7 @@ cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
size_t out_size)
{
char *pipeline_name;
+ struct pipeline *p;
uint32_t thread_id;
int status;
@@ -215,13 +216,18 @@ cmd_softnic_thread_pipeline_enable(struct pmd_internals *softnic,
}
pipeline_name = tokens[3];
+ p = softnic_pipeline_find(softnic, pipeline_name);
+ if (!p) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
+ return;
+ }
if (strcmp(tokens[4], "enable") != 0) {
snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable");
return;
}
- status = softnic_thread_pipeline_enable(softnic, thread_id, pipeline_name);
+ status = softnic_thread_pipeline_enable(softnic, thread_id, p);
if (status) {
snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable");
return;
@@ -239,6 +245,7 @@ cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
size_t out_size)
{
char *pipeline_name;
+ struct pipeline *p;
uint32_t thread_id;
int status;
@@ -258,13 +265,18 @@ cmd_softnic_thread_pipeline_disable(struct pmd_internals *softnic,
}
pipeline_name = tokens[3];
+ p = softnic_pipeline_find(softnic, pipeline_name);
+ if (!p) {
+ snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name");
+ return;
+ }
if (strcmp(tokens[4], "disable") != 0) {
snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable");
return;
}
- status = softnic_thread_pipeline_disable(softnic, thread_id, pipeline_name);
+ status = softnic_thread_pipeline_disable(softnic, thread_id, p);
if (status) {
snprintf(out, out_size, MSG_CMD_FAIL,
"thread pipeline disable");
@@ -13,9 +13,8 @@
#include <rte_mbuf.h>
#include <rte_ring.h>
#include <rte_ethdev.h>
-#include <rte_port_in_action.h>
-#include <rte_table_action.h>
-#include <rte_pipeline.h>
+#include <rte_swx_pipeline.h>
+#include <rte_swx_ctl.h>
#include <rte_ethdev_core.h>
#include <ethdev_driver.h>
@@ -89,207 +88,18 @@ struct softnic_link {
TAILQ_HEAD(softnic_link_list, softnic_link);
-/**
- * Input port action
- */
-struct softnic_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 softnic_port_in_action_profile {
- TAILQ_ENTRY(softnic_port_in_action_profile) node;
- char name[NAME_SIZE];
- struct softnic_port_in_action_profile_params params;
- struct rte_port_in_action_profile *ap;
-};
-
-TAILQ_HEAD(softnic_port_in_action_profile_list, softnic_port_in_action_profile);
-
-/**
- * Table action
- */
-struct softnic_table_action_profile_params {
- uint64_t action_mask;
- struct rte_table_action_common_config common;
- struct rte_table_action_lb_config lb;
- struct rte_table_action_mtr_config mtr;
- struct rte_table_action_tm_config tm;
- struct rte_table_action_encap_config encap;
- struct rte_table_action_nat_config nat;
- struct rte_table_action_ttl_config ttl;
- struct rte_table_action_stats_config stats;
- struct rte_table_action_sym_crypto_config sym_crypto;
-};
-
-struct softnic_table_action_profile {
- TAILQ_ENTRY(softnic_table_action_profile) node;
- char name[NAME_SIZE];
- struct softnic_table_action_profile_params params;
- struct rte_table_action_profile *ap;
-};
-
-TAILQ_HEAD(softnic_table_action_profile_list, softnic_table_action_profile);
-
-struct softnic_table_meter_profile {
- TAILQ_ENTRY(softnic_table_meter_profile) node;
- uint32_t meter_profile_id;
- struct rte_table_action_meter_profile profile;
-};
-
-TAILQ_HEAD(softnic_table_meter_profile_list,
- softnic_table_meter_profile);
-
/**
* Pipeline
*/
-struct pipeline_params {
- uint32_t timer_period_ms;
- uint32_t offset_port_id;
-};
-
-enum softnic_port_in_type {
- PORT_IN_RXQ,
- PORT_IN_SWQ,
- PORT_IN_SOURCE,
-};
-
-struct softnic_port_in_params {
- /* Read */
- enum softnic_port_in_type type;
- char dev_name[NAME_SIZE];
- union {
- struct {
- uint16_t queue_id;
- } rxq;
-
- struct {
- const char *mempool_name;
- const char *file_name;
- uint32_t n_bytes_per_pkt;
- } source;
- };
- uint32_t burst_size;
-
- /* Action */
- char action_profile_name[NAME_SIZE];
-};
-
-enum softnic_port_out_type {
- PORT_OUT_TXQ,
- PORT_OUT_SWQ,
- PORT_OUT_SINK,
-};
-
-struct softnic_port_out_params {
- enum softnic_port_out_type type;
- char dev_name[NAME_SIZE];
- 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 softnic_table_type {
- TABLE_ACL,
- TABLE_ARRAY,
- TABLE_HASH,
- TABLE_LPM,
- TABLE_STUB,
-};
-
-struct softnic_table_acl_params {
- uint32_t n_rules;
- uint32_t ip_header_offset;
- int ip_version;
-};
-
-struct softnic_table_array_params {
- uint32_t n_keys;
- uint32_t key_offset;
-};
-
-#ifndef TABLE_RULE_MATCH_SIZE_MAX
-#define TABLE_RULE_MATCH_SIZE_MAX 256
-#endif
-
-struct softnic_table_hash_params {
- uint32_t n_keys;
- uint32_t key_offset;
- uint32_t key_size;
- uint8_t key_mask[TABLE_RULE_MATCH_SIZE_MAX];
- uint32_t n_buckets;
- int extendable_bucket;
-};
-
-struct softnic_table_lpm_params {
- uint32_t n_rules;
- uint32_t key_offset;
- uint32_t key_size;
-};
-
-struct softnic_table_params {
- /* Match */
- enum softnic_table_type match_type;
- union {
- struct softnic_table_acl_params acl;
- struct softnic_table_array_params array;
- struct softnic_table_hash_params hash;
- struct softnic_table_lpm_params lpm;
- } match;
-
- /* Action */
- char action_profile_name[NAME_SIZE];
-};
-
-struct softnic_port_in {
- struct softnic_port_in_params params;
- struct softnic_port_in_action_profile *ap;
- struct rte_port_in_action *a;
-};
-
-struct softnic_port_out {
- struct softnic_port_out_params params;
-};
-
-struct softnic_table {
- struct softnic_table_params params;
- struct softnic_table_action_profile *ap;
- struct rte_table_action *a;
- struct rte_table_action_dscp_table dscp_table;
- struct softnic_table_meter_profile_list meter_profiles;
-};
-
struct pipeline {
TAILQ_ENTRY(pipeline) node;
char name[NAME_SIZE];
- struct rte_pipeline *p;
- struct pipeline_params params;
- struct softnic_port_in port_in[RTE_PIPELINE_PORT_IN_MAX];
- struct softnic_port_out port_out[RTE_PIPELINE_PORT_OUT_MAX];
- struct softnic_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;
+ struct rte_swx_pipeline *p;
+ struct rte_swx_ctl_pipeline *ctl;
int enabled;
uint32_t thread_id;
- uint32_t cpu_id;
};
TAILQ_HEAD(pipeline_list, pipeline);
@@ -309,6 +119,15 @@ TAILQ_HEAD(pipeline_list, pipeline);
#define THREAD_TIMER_PERIOD_MS 100
#endif
+/* Pipeline instruction quanta: Needs to be big enough to do some meaningful
+ * work, but not too big to avoid starving any other pipelines mapped to the
+ * same thread. For a pipeline that executes 10 instructions per packet, a
+ * quanta of 1000 instructions equates to processing 100 packets.
+ */
+#ifndef PIPELINE_INSTR_QUANTA
+#define PIPELINE_INSTR_QUANTA 1000
+#endif
+
/**
* Main thread: data plane thread context
*/
@@ -322,37 +141,14 @@ struct softnic_thread {
/**
* Data plane threads: context
*/
-#ifndef TABLE_RULE_ACTION_SIZE_MAX
-#define TABLE_RULE_ACTION_SIZE_MAX 2048
-#endif
-
-struct softnic_table_data {
- struct rte_table_action *a;
-};
-
-struct pipeline_data {
- struct rte_pipeline *p;
- struct softnic_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 softnic_thread_data {
- struct rte_pipeline *p[THREAD_PIPELINES_MAX];
+ struct rte_swx_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;
uint64_t iter;
} __rte_cache_aligned;
@@ -367,8 +163,6 @@ struct pmd_internals {
struct softnic_mempool_list mempool_list;
struct softnic_swq_list swq_list;
struct softnic_link_list link_list;
- struct softnic_port_in_action_profile_list port_in_action_profile_list;
- struct softnic_table_action_profile_list table_action_profile_list;
struct pipeline_list pipeline_list;
struct softnic_thread thread[RTE_MAX_LCORE];
struct softnic_thread_data thread_data[RTE_MAX_LCORE];
@@ -447,42 +241,6 @@ softnic_link_create(struct pmd_internals *p,
const char *name,
struct softnic_link_params *params);
-/**
- * Input port action
- */
-int
-softnic_port_in_action_profile_init(struct pmd_internals *p);
-
-void
-softnic_port_in_action_profile_free(struct pmd_internals *p);
-
-struct softnic_port_in_action_profile *
-softnic_port_in_action_profile_find(struct pmd_internals *p,
- const char *name);
-
-struct softnic_port_in_action_profile *
-softnic_port_in_action_profile_create(struct pmd_internals *p,
- const char *name,
- struct softnic_port_in_action_profile_params *params);
-
-/**
- * Table action
- */
-int
-softnic_table_action_profile_init(struct pmd_internals *p);
-
-void
-softnic_table_action_profile_free(struct pmd_internals *p);
-
-struct softnic_table_action_profile *
-softnic_table_action_profile_find(struct pmd_internals *p,
- const char *name);
-
-struct softnic_table_action_profile *
-softnic_table_action_profile_create(struct pmd_internals *p,
- const char *name,
- struct softnic_table_action_profile_params *params);
-
/**
* Pipeline
*/
@@ -504,228 +262,9 @@ softnic_pipeline_find(struct pmd_internals *p, const char *name);
struct pipeline *
softnic_pipeline_create(struct pmd_internals *p,
const char *name,
- struct pipeline_params *params);
-
-int
-softnic_pipeline_port_in_create(struct pmd_internals *p,
- const char *pipeline_name,
- struct softnic_port_in_params *params,
- int enabled);
-
-int
-softnic_pipeline_port_in_connect_to_table(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t port_id,
- uint32_t table_id);
-
-int
-softnic_pipeline_port_out_create(struct pmd_internals *p,
- const char *pipeline_name,
- struct softnic_port_out_params *params);
-
-int
-softnic_pipeline_port_out_find(struct pmd_internals *softnic,
- const char *pipeline_name,
- const char *name,
- uint32_t *port_id);
-
-int
-softnic_pipeline_table_create(struct pmd_internals *p,
- const char *pipeline_name,
- struct softnic_table_params *params);
-
-struct softnic_table_meter_profile *
-softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
- uint32_t meter_profile_id);
-
-struct softnic_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 softnic_table_rule_match_array {
- uint32_t pos;
-};
-
-struct softnic_table_rule_match_hash {
- uint8_t key[TABLE_RULE_MATCH_SIZE_MAX];
-};
-
-struct softnic_table_rule_match_lpm {
- int ip_version;
-
- RTE_STD_C11
- union {
- uint32_t ipv4;
- uint8_t ipv6[16];
- };
-
- uint8_t depth;
-};
-
-struct softnic_table_rule_match {
- enum softnic_table_type match_type;
-
- union {
- struct softnic_table_rule_match_acl acl;
- struct softnic_table_rule_match_array array;
- struct softnic_table_rule_match_hash hash;
- struct softnic_table_rule_match_lpm lpm;
- } match;
-};
-
-#ifndef SYM_CRYPTO_MAX_KEY_SIZE
-#define SYM_CRYPTO_MAX_KEY_SIZE (256)
-#endif
-struct softnic_table_rule_action {
- uint64_t action_mask;
- struct rte_table_action_fwd_params fwd;
- struct rte_table_action_lb_params lb;
- struct rte_table_action_mtr_params mtr;
- struct rte_table_action_tm_params tm;
- struct rte_table_action_encap_params encap;
- struct rte_table_action_nat_params nat;
- struct rte_table_action_ttl_params ttl;
- struct rte_table_action_stats_params stats;
- struct rte_table_action_time_params time;
- struct rte_table_action_tag_params tag;
- struct rte_table_action_decap_params decap;
- struct rte_table_action_sym_crypto_params sym_crypto;
- uint8_t sym_crypto_key[SYM_CRYPTO_MAX_KEY_SIZE];
-};
-
-int
-softnic_pipeline_port_in_stats_read(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_in_stats *stats,
- int clear);
-
-int
-softnic_pipeline_port_in_enable(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t port_id);
-
-int
-softnic_pipeline_port_in_disable(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t port_id);
-
-int
-softnic_pipeline_port_out_stats_read(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t port_id,
- struct rte_pipeline_port_out_stats *stats,
- int clear);
-
-int
-softnic_pipeline_table_stats_read(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear);
-
-int
-softnic_pipeline_table_rule_add(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_table_rule_match *match,
- struct softnic_table_rule_action *action,
- void **data);
-
-int
-softnic_pipeline_table_rule_add_bulk(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_table_rule_match *match,
- struct softnic_table_rule_action *action,
- void **data,
- uint32_t *n_rules);
-
-int
-softnic_pipeline_table_rule_add_default(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_table_rule_action *action,
- void **data);
-
-int
-softnic_pipeline_table_rule_delete(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_table_rule_match *match);
-
-int
-softnic_pipeline_table_rule_delete_default(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id);
-
-int
-softnic_pipeline_table_rule_stats_read(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- void *data,
- struct rte_table_action_stats_counters *stats,
- int clear);
-
-int
-softnic_pipeline_table_mtr_profile_add(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id,
- struct rte_table_action_meter_profile *profile);
-
-int
-softnic_pipeline_table_mtr_profile_delete(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- uint32_t meter_profile_id);
-
-int
-softnic_pipeline_table_rule_mtr_read(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- void *data,
- uint32_t tc_mask,
- struct rte_table_action_mtr_counters *stats,
- int clear);
-
-int
-softnic_pipeline_table_dscp_table_update(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- uint64_t dscp_mask,
- struct rte_table_action_dscp_table *dscp_table);
-
-int
-softnic_pipeline_table_rule_ttl_read(struct pmd_internals *p,
- const char *pipeline_name,
- uint32_t table_id,
- void *data,
- struct rte_table_action_ttl_counters *stats,
- int clear);
+ const char *lib_file_name,
+ const char *iospec_file_name,
+ int numa_node);
/**
* Thread
@@ -739,12 +278,15 @@ softnic_thread_free(struct pmd_internals *p);
int
softnic_thread_pipeline_enable(struct pmd_internals *p,
uint32_t thread_id,
- const char *pipeline_name);
+ struct pipeline *pipeline);
int
softnic_thread_pipeline_disable(struct pmd_internals *p,
uint32_t thread_id,
- const char *pipeline_name);
+ struct pipeline *pipeline);
+
+void
+softnic_thread_pipeline_disable_all(struct pmd_internals *p);
/**
* CLI
@@ -6,35 +6,10 @@
#include <string.h>
#include <rte_common.h>
-#include <rte_ip.h>
-#include <rte_tcp.h>
-
#include <rte_string_fns.h>
-#include <rte_port_ethdev.h>
-#include <rte_port_ring.h>
-#include <rte_port_source_sink.h>
-#include <rte_port_fd.h>
-#include <rte_port_sched.h>
-#include <rte_port_sym_crypto.h>
-
-#include <rte_table_acl.h>
-#include <rte_table_array.h>
-#include <rte_table_hash.h>
-#include <rte_table_hash_func.h>
-#include <rte_table_lpm.h>
-#include <rte_table_lpm_ipv6.h>
-#include <rte_table_stub.h>
#include "rte_eth_softnic_internals.h"
-#ifndef PIPELINE_MSGQ_SIZE
-#define PIPELINE_MSGQ_SIZE 64
-#endif
-
-#ifndef TABLE_LPM_NUMBER_TBL8
-#define TABLE_LPM_NUMBER_TBL8 256
-#endif
-
int
softnic_pipeline_init(struct pmd_internals *p)
{
@@ -43,44 +18,19 @@ softnic_pipeline_init(struct pmd_internals *p)
return 0;
}
-static void
-softnic_pipeline_table_free(struct softnic_table *table)
-{
- for ( ; ; ) {
- struct softnic_table_meter_profile *mp;
-
- mp = TAILQ_FIRST(&table->meter_profiles);
- if (mp == NULL)
- break;
-
- TAILQ_REMOVE(&table->meter_profiles, mp, node);
- free(mp);
- }
-}
-
void
softnic_pipeline_free(struct pmd_internals *p)
{
for ( ; ; ) {
struct pipeline *pipeline;
- uint32_t table_id;
pipeline = TAILQ_FIRST(&p->pipeline_list);
if (pipeline == NULL)
break;
TAILQ_REMOVE(&p->pipeline_list, pipeline, node);
-
- for (table_id = 0; table_id < pipeline->n_tables; table_id++) {
- struct softnic_table *table =
- &pipeline->table[table_id];
-
- softnic_pipeline_table_free(table);
- }
-
- rte_ring_free(pipeline->msgq_req);
- rte_ring_free(pipeline->msgq_rsp);
- rte_pipeline_free(pipeline->p);
+ rte_swx_ctl_pipeline_free(pipeline->ctl);
+ rte_swx_pipeline_free(pipeline->p);
free(pipeline);
}
}
@@ -94,7 +44,7 @@ softnic_pipeline_disable_all(struct pmd_internals *p)
if (pipeline->enabled)
softnic_thread_pipeline_disable(p,
pipeline->thread_id,
- pipeline->name);
+ pipeline);
}
uint32_t
@@ -126,850 +76,170 @@ softnic_pipeline_find(struct pmd_internals *p,
return NULL;
}
-struct pipeline *
-softnic_pipeline_create(struct pmd_internals *softnic,
- const char *name,
- struct pipeline_params *params)
-{
- char resource_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 ||
- softnic_pipeline_find(softnic, name) ||
- params == NULL ||
- params->timer_period_ms == 0)
- return NULL;
-
- /* Resource create */
- snprintf(resource_name, sizeof(resource_name), "%s-%s-REQ",
- softnic->params.name,
- name);
-
- msgq_req = rte_ring_create(resource_name,
- PIPELINE_MSGQ_SIZE,
- softnic->params.cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_req == NULL)
- return NULL;
-
- snprintf(resource_name, sizeof(resource_name), "%s-%s-RSP",
- softnic->params.name,
- name);
-
- msgq_rsp = rte_ring_create(resource_name,
- PIPELINE_MSGQ_SIZE,
- softnic->params.cpu_id,
- RING_F_SP_ENQ | RING_F_SC_DEQ);
- if (msgq_rsp == NULL) {
- rte_ring_free(msgq_req);
- return NULL;
- }
-
- snprintf(resource_name, sizeof(resource_name), "%s_%s",
- softnic->params.name,
- name);
-
- pp.name = resource_name;
- pp.socket_id = (int)softnic->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;
- memcpy(&pipeline->params, params, sizeof(*params));
- 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 = softnic->params.cpu_id;
-
- /* Node add to list */
- TAILQ_INSERT_TAIL(&softnic->pipeline_list, pipeline, node);
-
- return pipeline;
-}
+#ifndef MAX_LINE_LENGTH
+#define MAX_LINE_LENGTH 2048
+#endif
-int
-softnic_pipeline_port_in_create(struct pmd_internals *softnic,
- const char *pipeline_name,
- struct softnic_port_in_params *params,
- int enabled)
+/* The Soft NIC device internal resources such as mempools, rings or pipelines are globally visible,
+ * hence they need to have globally unique names. In order to apply the same configuration scripts
+ * unmodified to all the Soft NIC devices that instantiate the same program, the pipeline I/O
+ * configuration files are silently translated internally to prefix the name of the above resources
+ * with the Soft NIC device name, thus making the resource names globally unique.
+ */
+static int
+iospec_translate(struct pmd_internals *softnic __rte_unused,
+ const char *file_in_name,
+ const char *file_out_name)
{
- struct rte_pipeline_port_in_params p;
-
- union {
- struct rte_port_ethdev_reader_params ethdev;
- struct rte_port_ring_reader_params ring;
- struct rte_port_sched_reader_params sched;
- struct rte_port_fd_reader_params fd;
- struct rte_port_source_params source;
- } pp;
+ FILE *fi = NULL, *fo = NULL;
+ char *line = NULL;
+ int status = 0;
- struct pipeline *pipeline;
- struct softnic_port_in *port_in;
- struct softnic_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 = softnic_pipeline_find(softnic, pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- ap = NULL;
- if (strlen(params->action_profile_name)) {
- ap = softnic_port_in_action_profile_find(softnic,
- params->action_profile_name);
- if (ap == NULL)
- return -1;
+ /* File open. */
+ fi = fopen(file_in_name, "r");
+ fo = fopen(file_out_name, "w");
+ if (!fi || !fo) {
+ status = -EIO;
+ goto free;
}
- switch (params->type) {
- case PORT_IN_RXQ:
- {
- struct softnic_link *link;
-
- link = softnic_link_find(softnic, 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;
+ /* Memory allocation. */
+ line = malloc(MAX_LINE_LENGTH);
+ if (!line) {
+ status = -ENOMEM;
+ goto free;
}
- case PORT_IN_SWQ:
- {
- struct softnic_swq *swq;
-
- swq = softnic_swq_find(softnic, 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;
- }
+ /* Read from the input file and write to the output file. */
+ for ( ; ; ) {
+ char *ptr = line;
+ uint32_t n_tokens;
+ int flag = 0;
- case PORT_IN_SOURCE:
- {
- struct softnic_mempool *mempool;
+ /* Read next line. */
+ if (!fgets(line, MAX_LINE_LENGTH, fi))
+ break;
- mempool = softnic_mempool_find(softnic, params->source.mempool_name);
- if (mempool == NULL)
- return -1;
+ /* Parse the line into tokens. */
+ for (n_tokens = 0; ; n_tokens++) {
+ char *token;
- 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;
+ /* Read token. */
+ token = strtok_r(ptr, " \f\n\r\t\v", &ptr);
+ if (!token)
+ break;
- p.ops = &rte_port_source_ops;
- p.arg_create = &pp.source;
- break;
- }
+ /* Handle comments. */
+ if (!n_tokens &&
+ ((token[0] == '#') ||
+ (token[0] == ';') ||
+ ((token[0] == '/') && (token[1] == '/'))))
+ break;
- default:
- return -1;
- }
+ /* Process token. */
+ if (flag) {
+ fprintf(fo, "%s_%s ", softnic->params.name, token);
+ flag = 0;
+ continue;
+ }
- p.burst_size = params->burst_size;
+ if (!strcmp(token, "mempool") ||
+ !strcmp(token, "ring")) {
+ flag = 1;
+ fprintf(fo, "%s ", token);
+ continue;
+ }
- /* Resource create */
- action = NULL;
- p.f_action = NULL;
- p.arg_ah = NULL;
-
- if (ap) {
- action = rte_port_in_action_create(ap->ap,
- softnic->params.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;
+ /* Default action: write token. */
+ fprintf(fo, "%s ", token);
}
- }
-
- 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
-softnic_pipeline_port_in_connect_to_table(struct pmd_internals *softnic,
- 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;
+ /* Handle empty or comment lines. */
+ if (!n_tokens)
+ continue;
- pipeline = softnic_pipeline_find(softnic, pipeline_name);
- if (pipeline == NULL ||
- port_id >= pipeline->n_ports_in ||
- table_id >= pipeline->n_tables)
- return -1;
+ /* Write newline. */
+ fprintf(fo, "\n");
+ }
- /* Resource */
- status = rte_pipeline_port_in_connect_to_table(pipeline->p,
- port_id,
- table_id);
+free:
+ /* Memory free. */
+ free(line);
+ /* File close. */
+ if (fi)
+ fclose(fi);
+ if (fo)
+ fclose(fo);
return status;
}
-int
-softnic_pipeline_port_out_create(struct pmd_internals *softnic,
- const char *pipeline_name,
- struct softnic_port_out_params *params)
+struct pipeline *
+softnic_pipeline_create(struct pmd_internals *softnic,
+ const char *name,
+ const char *lib_file_name,
+ const char *iospec_file_name,
+ int numa_node)
{
- struct rte_pipeline_port_out_params p;
-
- union {
- struct rte_port_ethdev_writer_params ethdev;
- struct rte_port_ring_writer_params ring;
- struct rte_port_sched_writer_params sched;
- struct rte_port_fd_writer_params fd;
- struct rte_port_sink_params sink;
- } 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;
- } pp_nodrop;
-
- struct pipeline *pipeline;
- struct softnic_port_out *port_out;
- uint32_t port_id;
- int status;
-
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
- memset(&pp_nodrop, 0, sizeof(pp_nodrop));
+ char global_name[NAME_MAX];
+ FILE *iospec_file = NULL;
+ struct pipeline *pipeline = NULL;
+ struct rte_swx_pipeline *p = NULL;
+ struct rte_swx_ctl_pipeline *ctl = NULL;
+ int status = 0;
/* 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 = softnic_pipeline_find(softnic, pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- switch (params->type) {
- case PORT_OUT_TXQ:
- {
- struct softnic_link *link;
-
- link = softnic_link_find(softnic, 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 softnic_swq *swq;
-
- swq = softnic_swq_find(softnic, 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_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;
+ if (!name || !name[0] || softnic_pipeline_find(softnic, name))
+ goto error;
/* Resource create */
- status = rte_pipeline_port_out_create(pipeline->p,
- &p,
- &port_id);
+ snprintf(global_name, sizeof(global_name), "/tmp/%s_%s.io", softnic->params.name, name);
+ status = iospec_translate(softnic, iospec_file_name, global_name);
if (status)
- return -1;
-
- /* Pipeline */
- port_out = &pipeline->port_out[pipeline->n_ports_out];
- memcpy(&port_out->params, params, sizeof(*params));
- pipeline->n_ports_out++;
-
- return 0;
-}
+ goto error;
-static const struct rte_acl_field_def table_acl_field_format_ipv4[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv4_hdr, next_proto_id),
- },
-
- /* Source IP address (IPv4) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv4_hdr, src_addr),
- },
-
- /* Destination IP address (IPv4) */
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv4_hdr, dst_addr),
- },
-
- /* Source Port */
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 3,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 4,
- .input_index = 3,
- .offset = sizeof(struct rte_ipv4_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-static const struct rte_acl_field_def table_acl_field_format_ipv6[] = {
- /* Protocol */
- [0] = {
- .type = RTE_ACL_FIELD_TYPE_BITMASK,
- .size = sizeof(uint8_t),
- .field_index = 0,
- .input_index = 0,
- .offset = offsetof(struct rte_ipv6_hdr, proto),
- },
-
- /* Source IP address (IPv6) */
- [1] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 1,
- .input_index = 1,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr[0]),
- },
-
- [2] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 2,
- .input_index = 2,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr[4]),
- },
-
- [3] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 3,
- .input_index = 3,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr[8]),
- },
-
- [4] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 4,
- .input_index = 4,
- .offset = offsetof(struct rte_ipv6_hdr, src_addr[12]),
- },
-
- /* Destination IP address (IPv6) */
- [5] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 5,
- .input_index = 5,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr[0]),
- },
-
- [6] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 6,
- .input_index = 6,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr[4]),
- },
-
- [7] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 7,
- .input_index = 7,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr[8]),
- },
-
- [8] = {
- .type = RTE_ACL_FIELD_TYPE_MASK,
- .size = sizeof(uint32_t),
- .field_index = 8,
- .input_index = 8,
- .offset = offsetof(struct rte_ipv6_hdr, dst_addr[12]),
- },
-
- /* Source Port */
- [9] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 9,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, src_port),
- },
-
- /* Destination Port */
- [10] = {
- .type = RTE_ACL_FIELD_TYPE_RANGE,
- .size = sizeof(uint16_t),
- .field_index = 10,
- .input_index = 9,
- .offset = sizeof(struct rte_ipv6_hdr) +
- offsetof(struct rte_tcp_hdr, dst_port),
- },
-};
-
-int
-softnic_pipeline_table_create(struct pmd_internals *softnic,
- const char *pipeline_name,
- struct softnic_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 softnic_table *table;
- struct softnic_table_action_profile *ap;
- struct rte_table_action *action;
- uint32_t table_id;
- int status;
+ iospec_file = fopen(global_name, "r");
+ if (!iospec_file)
+ goto error;
- memset(&p, 0, sizeof(p));
- memset(&pp, 0, sizeof(pp));
-
- /* Check input params */
- if (pipeline_name == NULL ||
- params == NULL)
- return -1;
-
- pipeline = softnic_pipeline_find(softnic, pipeline_name);
- if (pipeline == NULL ||
- pipeline->n_tables >= RTE_PIPELINE_TABLE_MAX)
- return -1;
-
- ap = NULL;
- if (strlen(params->action_profile_name)) {
- ap = softnic_table_action_profile_find(softnic,
- params->action_profile_name);
- if (ap == NULL)
- return -1;
- }
-
- snprintf(name, NAME_MAX, "%s_%s_table%u",
- softnic->params.name, pipeline_name, pipeline->n_tables);
-
- switch (params->match_type) {
- case TABLE_ACL:
- {
- uint32_t ip_header_offset = params->match.acl.ip_header_offset -
- (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM);
- uint32_t i;
-
- if (params->match.acl.n_rules == 0)
- return -1;
-
- pp.acl.name = name;
- pp.acl.n_rules = params->match.acl.n_rules;
- if (params->match.acl.ip_version) {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv4,
- sizeof(table_acl_field_format_ipv4));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv4);
- } else {
- memcpy(&pp.acl.field_format,
- &table_acl_field_format_ipv6,
- sizeof(table_acl_field_format_ipv6));
- pp.acl.n_rule_fields =
- RTE_DIM(table_acl_field_format_ipv6);
- }
-
- for (i = 0; i < pp.acl.n_rule_fields; i++)
- pp.acl.field_format[i].offset += ip_header_offset;
-
- p.ops = &rte_table_acl_ops;
- p.arg_create = &pp.acl;
- break;
- }
-
- case TABLE_ARRAY:
- {
- if (params->match.array.n_keys == 0)
- return -1;
-
- pp.array.n_entries = params->match.array.n_keys;
- pp.array.offset = params->match.array.key_offset;
-
- p.ops = &rte_table_array_ops;
- p.arg_create = &pp.array;
- break;
- }
-
- case TABLE_HASH:
- {
- struct rte_table_ops *ops;
- rte_table_hash_op_hash f_hash;
-
- if (params->match.hash.n_keys == 0)
- return -1;
-
- switch (params->match.hash.key_size) {
- case 8:
- f_hash = rte_table_hash_crc_key8;
- break;
- case 16:
- f_hash = rte_table_hash_crc_key16;
- break;
- case 24:
- f_hash = rte_table_hash_crc_key24;
- break;
- case 32:
- f_hash = rte_table_hash_crc_key32;
- break;
- case 40:
- f_hash = rte_table_hash_crc_key40;
- break;
- case 48:
- f_hash = rte_table_hash_crc_key48;
- break;
- case 56:
- f_hash = rte_table_hash_crc_key56;
- break;
- case 64:
- f_hash = rte_table_hash_crc_key64;
- break;
- default:
- return -1;
- }
+ snprintf(global_name, sizeof(global_name), "%s_%s", softnic->params.name, name);
- 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,
- softnic->params.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;
- }
+ status = rte_swx_pipeline_build_from_lib(&p,
+ global_name,
+ lib_file_name,
+ iospec_file,
+ numa_node);
+ if (status)
+ goto error;
- /* Pipeline */
- table = &pipeline->table[pipeline->n_tables];
- memcpy(&table->params, params, sizeof(*params));
- table->ap = ap;
- table->a = action;
- TAILQ_INIT(&table->meter_profiles);
- memset(&table->dscp_table, 0, sizeof(table->dscp_table));
- pipeline->n_tables++;
+ fclose(iospec_file);
+ iospec_file = NULL;
- return 0;
-}
+ ctl = rte_swx_ctl_pipeline_create(p);
+ if (!ctl)
+ goto error;
-int
-softnic_pipeline_port_out_find(struct pmd_internals *softnic,
- const char *pipeline_name,
- const char *name,
- uint32_t *port_id)
-{
- struct pipeline *pipeline;
- uint32_t i;
-
- if (softnic == NULL ||
- pipeline_name == NULL ||
- name == NULL ||
- port_id == NULL)
- return -1;
-
- pipeline = softnic_pipeline_find(softnic, pipeline_name);
- if (pipeline == NULL)
- return -1;
-
- for (i = 0; i < pipeline->n_ports_out; i++)
- if (strcmp(pipeline->port_out[i].params.dev_name, name) == 0) {
- *port_id = i;
- return 0;
- }
+ /* Node allocation */
+ pipeline = calloc(1, sizeof(struct pipeline));
+ if (!pipeline)
+ goto error;
- return -1;
-}
+ /* Node fill in */
+ strlcpy(pipeline->name, name, sizeof(pipeline->name));
+ pipeline->p = p;
+ pipeline->ctl = ctl;
-struct softnic_table_meter_profile *
-softnic_pipeline_table_meter_profile_find(struct softnic_table *table,
- uint32_t meter_profile_id)
-{
- struct softnic_table_meter_profile *mp;
+ /* Node add to list */
+ TAILQ_INSERT_TAIL(&softnic->pipeline_list, pipeline, node);
- TAILQ_FOREACH(mp, &table->meter_profiles, node)
- if (mp->meter_profile_id == meter_profile_id)
- return mp;
+ return pipeline;
+error:
+ free(pipeline);
+ rte_swx_ctl_pipeline_free(ctl);
+ rte_swx_pipeline_free(p);
+ if (iospec_file)
+ fclose(iospec_file);
return NULL;
}
@@ -10,11 +10,6 @@
#include <rte_service_component.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 "rte_eth_softnic_internals.h"
/**
@@ -88,7 +83,6 @@ softnic_thread_init(struct pmd_internals *softnic)
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;
@@ -97,6 +91,9 @@ softnic_thread_init(struct pmd_internals *softnic)
static inline int
thread_is_valid(struct pmd_internals *softnic, uint32_t thread_id)
{
+ if (thread_id >= RTE_MAX_LCORE)
+ return 0; /* FALSE */
+
if (thread_id == rte_get_main_lcore())
return 0; /* FALSE */
@@ -190,18 +187,22 @@ thread_sc_service_down(struct pmd_internals *softnic, uint32_t thread_id)
t->service_id = UINT32_MAX;
}
-/**
- * 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)
+void
+softnic_thread_pipeline_disable_all(struct pmd_internals *softnic)
{
- if (p->enabled == 0)
- return 0;
+ uint32_t thread_id;
- return thread_is_running(p->thread_id);
+ for (thread_id = 0; thread_id < RTE_MAX_LCORE; thread_id++) {
+ struct softnic_thread_data *td = &softnic->thread_data[thread_id];
+
+ if (!thread_is_valid(softnic, thread_id))
+ continue;
+
+ if (softnic->params.sc && td->n_pipelines)
+ thread_sc_service_down(softnic, thread_id);
+
+ td->n_pipelines = 0;
+ }
}
/**
@@ -218,18 +219,11 @@ struct thread_msg_req {
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;
+ struct rte_swx_pipeline *p;
} pipeline_enable;
struct {
- struct rte_pipeline *p;
+ struct rte_swx_pipeline *p;
} pipeline_disable;
};
};
@@ -283,20 +277,16 @@ thread_msg_send_recv(struct pmd_internals *softnic,
int
softnic_thread_pipeline_enable(struct pmd_internals *softnic,
uint32_t thread_id,
- const char *pipeline_name)
+ struct pipeline *p)
{
- struct pipeline *p = softnic_pipeline_find(softnic, pipeline_name);
struct thread_msg_req *req;
struct thread_msg_rsp *rsp;
- uint32_t n_pipelines, i;
+ uint32_t n_pipelines;
int status;
/* Check input params */
if (!thread_is_valid(softnic, thread_id) ||
(p == NULL) ||
- (p->n_ports_in == 0) ||
- (p->n_ports_out == 0) ||
- (p->n_tables == 0) ||
p->enabled)
return -1;
@@ -312,22 +302,9 @@ softnic_thread_pipeline_enable(struct pmd_internals *softnic,
if (!thread_is_running(thread_id)) {
struct softnic_thread_data *td = &softnic->thread_data[thread_id];
- struct pipeline_data *tdp = &td->pipeline_data[td->n_pipelines];
/* 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 */
@@ -345,13 +322,6 @@ softnic_thread_pipeline_enable(struct pmd_internals *softnic,
/* 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(softnic, thread_id, req);
@@ -375,9 +345,8 @@ softnic_thread_pipeline_enable(struct pmd_internals *softnic,
int
softnic_thread_pipeline_disable(struct pmd_internals *softnic,
uint32_t thread_id,
- const char *pipeline_name)
+ struct pipeline *p)
{
- struct pipeline *p = softnic_pipeline_find(softnic, pipeline_name);
struct thread_msg_req *req;
struct thread_msg_rsp *rsp;
uint32_t n_pipelines;
@@ -397,21 +366,12 @@ softnic_thread_pipeline_disable(struct pmd_internals *softnic,
uint32_t i;
for (i = 0; i < td->n_pipelines; i++) {
- struct pipeline_data *tdp = &td->pipeline_data[i];
-
- if (tdp->p != p->p)
+ if (td->p[i] != 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));
- }
+ if (i < td->n_pipelines - 1)
+ td->p[i] = td->p[td->n_pipelines - 1];
td->n_pipelines--;
@@ -490,25 +450,9 @@ thread_msg_handle_pipeline_enable(struct softnic_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 */
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 */
@@ -522,25 +466,16 @@ thread_msg_handle_pipeline_disable(struct softnic_thread_data *t,
{
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;
+ struct rte_swx_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)
+ if (t->p[i] != 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));
- }
+ if (i < n_pipelines - 1)
+ t->p[i] = t->p[n_pipelines - 1];
t->n_pipelines--;
@@ -583,2464 +518,37 @@ thread_msg_handle(struct softnic_thread_data *t)
}
/**
- * Main thread & data plane threads: message passing
- */
-enum pipeline_req_type {
- /* Port IN */
- PIPELINE_REQ_PORT_IN_STATS_READ,
- PIPELINE_REQ_PORT_IN_ENABLE,
- PIPELINE_REQ_PORT_IN_DISABLE,
-
- /* Port OUT */
- PIPELINE_REQ_PORT_OUT_STATS_READ,
-
- /* Table */
- PIPELINE_REQ_TABLE_STATS_READ,
- PIPELINE_REQ_TABLE_RULE_ADD,
- PIPELINE_REQ_TABLE_RULE_ADD_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_ADD_BULK,
- PIPELINE_REQ_TABLE_RULE_DELETE,
- PIPELINE_REQ_TABLE_RULE_DELETE_DEFAULT,
- PIPELINE_REQ_TABLE_RULE_STATS_READ,
- PIPELINE_REQ_TABLE_MTR_PROFILE_ADD,
- PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE,
- PIPELINE_REQ_TABLE_RULE_MTR_READ,
- PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE,
- PIPELINE_REQ_TABLE_RULE_TTL_READ,
- PIPELINE_REQ_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 softnic_table_rule_match match;
- struct softnic_table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_default {
- struct softnic_table_rule_action action;
-};
-
-struct pipeline_msg_req_table_rule_add_bulk {
- struct softnic_table_rule_match *match;
- struct softnic_table_rule_action *action;
- void **data;
- uint32_t n_rules;
- int bulk;
-};
-
-struct pipeline_msg_req_table_rule_delete {
- struct softnic_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;
- };
-};
-
-/**
- * Main thread
+ * Data plane threads: main
*/
-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
-softnic_pipeline_port_in_stats_read(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, pipeline_name);
- if (p == NULL ||
- port_id >= p->n_ports_in)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_STATS_READ;
- req->id = port_id;
- req->port_in_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status)
- memcpy(stats, &rsp->port_in_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_port_in_enable(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, pipeline_name);
- if (p == NULL ||
- port_id >= p->n_ports_in)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_enable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_ENABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_port_in_disable(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, pipeline_name);
- if (p == NULL ||
- port_id >= p->n_ports_in)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_in_disable(p->p, port_id);
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_IN_DISABLE;
- req->id = port_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_port_out_stats_read(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, pipeline_name);
- if (p == NULL ||
- port_id >= p->n_ports_out)
- return -1;
-
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_port_out_stats_read(p->p,
- port_id,
- stats,
- clear);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_PORT_OUT_STATS_READ;
- req->id = port_id;
- req->port_out_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status)
- memcpy(stats, &rsp->port_out_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_stats_read(struct pmd_internals *softnic,
- const char *pipeline_name,
- uint32_t table_id,
- struct rte_pipeline_table_stats *stats,
- int clear)
+static int32_t
+rte_pmd_softnic_run_internal(void *arg)
{
- 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;
+ struct rte_eth_dev *dev = arg;
+ struct pmd_internals *softnic;
+ struct softnic_thread_data *t;
+ uint32_t thread_id, j;
- p = softnic_pipeline_find(softnic, pipeline_name);
- if (p == NULL ||
- table_id >= p->n_tables)
- return -1;
+ softnic = dev->data->dev_private;
+ thread_id = rte_lcore_id();
+ t = &softnic->thread_data[thread_id];
+ t->iter++;
- if (!pipeline_is_running(p)) {
- status = rte_pipeline_table_stats_read(p->p,
- table_id,
- stats,
- clear);
+ /* Data Plane */
+ for (j = 0; j < t->n_pipelines; j++)
+ rte_swx_pipeline_run(t->p[j], PIPELINE_INSTR_QUANTA);
- return status;
- }
+ /* Control Plane */
+ if ((t->iter & 0xFLLU) == 0) {
+ uint64_t time = rte_get_tsc_cycles();
+ uint64_t time_next = t->time_next;
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_STATS_READ;
- req->id = table_id;
- req->table_stats_read.clear = clear;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status)
- memcpy(stats, &rsp->table_stats_read.stats, sizeof(*stats));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-static int
-match_check(struct softnic_table_rule_match *match,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct softnic_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 softnic_table_acl_params *t = &table->params.match.acl;
- struct softnic_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 softnic_table_lpm_params *t = &table->params.match.lpm;
- struct softnic_table_rule_match_lpm *r = &match->match.lpm;
-
- if ((r->ip_version && (t->key_size != 4)) ||
- ((r->ip_version == 0) && (t->key_size != 16)))
- return -1;
-
- if (r->ip_version) {
- if (r->depth > 32)
- return -1;
- } else {
- if (r->depth > 128)
- return -1;
- }
- return 0;
- }
-
- case TABLE_STUB:
- return -1;
-
- default:
- return -1;
- }
-}
-
-static int
-action_check(struct softnic_table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- struct softnic_table_action_profile *ap;
-
- if (action == NULL ||
- p == NULL ||
- table_id >= p->n_tables)
- return -1;
-
- ap = p->table[table_id].ap;
- if (action->action_mask != ap->params.action_mask)
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT &&
- action->fwd.id >= p->n_ports_out)
- return -1;
-
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE &&
- action->fwd.id >= p->n_tables)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- uint32_t tc_mask0 = (1 << ap->params.mtr.n_tc) - 1;
- uint32_t tc_mask1 = action->mtr.tc_mask;
-
- if (tc_mask1 != tc_mask0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- uint32_t n_subports_per_port =
- ap->params.tm.n_subports_per_port;
- uint32_t n_pipes_per_subport =
- ap->params.tm.n_pipes_per_subport;
- uint32_t subport_id = action->tm.subport_id;
- uint32_t pipe_id = action->tm.pipe_id;
-
- if (subport_id >= n_subports_per_port ||
- pipe_id >= n_pipes_per_subport)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- uint64_t encap_mask = ap->params.encap.encap_mask;
- enum rte_table_action_encap_type type = action->encap.type;
-
- if ((encap_mask & (1LLU << type)) == 0)
- return -1;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- int ip_version0 = ap->params.common.ip_version;
- int ip_version1 = action->nat.ip_version;
-
- if ((ip_version1 && (ip_version0 == 0)) ||
- ((ip_version1 == 0) && ip_version0))
- return -1;
- }
-
- return 0;
-}
-
-static int
-action_default_check(struct softnic_table_rule_action *action,
- struct pipeline *p,
- uint32_t table_id)
-{
- if (action == NULL ||
- action->action_mask != (1LLU << RTE_TABLE_ACTION_FWD) ||
- p == NULL ||
- table_id >= p->n_tables)
- return -1;
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT &&
- action->fwd.id >= p->n_ports_out)
- return -1;
-
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE &&
- action->fwd.id >= p->n_tables)
- return -1;
- }
-
- return 0;
-}
-
-union table_rule_match_low_level {
- struct rte_table_acl_rule_add_params acl_add;
- struct rte_table_acl_rule_delete_params acl_delete;
- struct rte_table_array_key array;
- uint8_t hash[TABLE_RULE_MATCH_SIZE_MAX];
- struct rte_table_lpm_key lpm_ipv4;
- struct rte_table_lpm_ipv6_key lpm_ipv6;
-};
-
-static int
-match_convert(struct softnic_table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add);
-
-static int
-action_convert(struct rte_table_action *a,
- struct softnic_table_rule_action *action,
- struct rte_pipeline_table_entry *data);
-
-int
-softnic_pipeline_table_rule_add(struct pmd_internals *softnic,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_table_rule_match *match,
- struct softnic_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 = softnic_pipeline_find(softnic, 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;
- }
-
- /* 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);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- *data = rsp->table_rule_add.data;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_rule_add_default(struct pmd_internals *softnic,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_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 = softnic_pipeline_find(softnic, 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;
- }
-
- /* 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);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- *data = rsp->table_rule_add_default.data;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_rule_add_bulk(struct pmd_internals *softnic,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_table_rule_match *match,
- struct softnic_table_rule_action *action,
- void **data,
- uint32_t *n_rules)
-{
- struct pipeline *p;
- struct pipeline_msg_req *req;
- struct pipeline_msg_rsp *rsp;
- uint32_t i;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL ||
- match == NULL ||
- action == NULL ||
- data == NULL ||
- n_rules == NULL ||
- (*n_rules == 0))
- return -1;
-
- p = softnic_pipeline_find(softnic, 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];
- }
-
- /* 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,
- 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;
- }
- }
- }
-
- /* 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);
-
- /* 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
-softnic_pipeline_table_rule_delete(struct pmd_internals *softnic,
- const char *pipeline_name,
- uint32_t table_id,
- struct softnic_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 = softnic_pipeline_find(softnic, 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);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_rule_delete_default(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, 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);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_rule_stats_read(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, 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);
-
- /* 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
-softnic_pipeline_table_mtr_profile_add(struct pmd_internals *softnic,
- 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;
- struct softnic_table *table;
- struct softnic_table_meter_profile *mp;
- int status;
-
- /* Check input params */
- if (pipeline_name == NULL ||
- profile == NULL)
- return -1;
-
- p = softnic_pipeline_find(softnic, pipeline_name);
- if (p == NULL ||
- table_id >= p->n_tables)
- return -1;
-
- table = &p->table[table_id];
- mp = softnic_pipeline_table_meter_profile_find(table, meter_profile_id);
- if (mp)
- return -1;
-
- /* Resource Allocation */
- mp = calloc(1, sizeof(struct softnic_table_meter_profile));
- if (mp == NULL)
- return -1;
-
- mp->meter_profile_id = meter_profile_id;
- memcpy(&mp->profile, profile, sizeof(mp->profile));
-
- if (!pipeline_is_running(p)) {
- status = rte_table_action_meter_profile_add(table->a,
- meter_profile_id,
- profile);
- if (status) {
- free(mp);
- return status;
- }
-
- /* Add profile to the table. */
- TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL) {
- free(mp);
- return -1;
- }
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_ADD;
- req->id = table_id;
- req->table_mtr_profile_add.meter_profile_id = meter_profile_id;
- memcpy(&req->table_mtr_profile_add.profile, profile, sizeof(*profile));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
- if (status == 0)
- TAILQ_INSERT_TAIL(&table->meter_profiles, mp, node);
- else
- free(mp);
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_mtr_profile_delete(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, pipeline_name);
- if (p == NULL ||
- table_id >= p->n_tables)
- return -1;
-
- if (!pipeline_is_running(p)) {
- struct rte_table_action *a = p->table[table_id].a;
-
- status = rte_table_action_meter_profile_delete(a,
- meter_profile_id);
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_MTR_PROFILE_DELETE;
- req->id = table_id;
- req->table_mtr_profile_delete.meter_profile_id = meter_profile_id;
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_rule_mtr_read(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, 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);
-
- /* 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
-softnic_pipeline_table_dscp_table_update(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, 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);
-
- /* Update table dscp table */
- if (!status)
- memcpy(&p->table[table_id].dscp_table, dscp_table,
- sizeof(p->table[table_id].dscp_table));
-
- return status;
- }
-
- /* Allocate request */
- req = pipeline_msg_alloc();
- if (req == NULL)
- return -1;
-
- /* Write request */
- req->type = PIPELINE_REQ_TABLE_DSCP_TABLE_UPDATE;
- req->id = table_id;
- req->table_dscp_table_update.dscp_mask = dscp_mask;
- memcpy(&req->table_dscp_table_update.dscp_table,
- dscp_table, sizeof(*dscp_table));
-
- /* Send request and wait for response */
- rsp = pipeline_msg_send_recv(p, req);
-
- /* Read response */
- status = rsp->status;
-
- /* Update table dscp table */
- if (!status)
- memcpy(&p->table[table_id].dscp_table, dscp_table,
- sizeof(p->table[table_id].dscp_table));
-
- /* Free response */
- pipeline_msg_free(rsp);
-
- return status;
-}
-
-int
-softnic_pipeline_table_rule_ttl_read(struct pmd_internals *softnic,
- 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 = softnic_pipeline_find(softnic, 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);
-
- /* 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 softnic_table_rule_match *mh,
- union table_rule_match_low_level *ml,
- int add)
-{
- memset(ml, 0, sizeof(*ml));
-
- switch (mh->match_type) {
- case TABLE_ACL:
- if (mh->match.acl.ip_version)
- if (add) {
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_add.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_add.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_add.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_add.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t)mh->match.acl.priority;
- } else {
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- mh->match.acl.ipv4.sa;
- ml->acl_delete.field_value[1].mask_range.u32 =
- mh->match.acl.sa_depth;
-
- ml->acl_delete.field_value[2].value.u32 =
- mh->match.acl.ipv4.da;
- ml->acl_delete.field_value[2].mask_range.u32 =
- mh->match.acl.da_depth;
-
- ml->acl_delete.field_value[3].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[3].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[4].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[4].mask_range.u16 =
- mh->match.acl.dp1;
- }
- else
- if (add) {
- uint32_t *sa32 =
- (uint32_t *)mh->match.acl.ipv6.sa;
- uint32_t *da32 =
- (uint32_t *)mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(
- mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_add.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_add.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_add.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_add.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_add.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_add.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_add.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_add.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_add.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_add.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_add.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_add.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_add.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_add.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_add.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_add.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_add.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_add.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_add.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_add.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_add.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_add.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
-
- ml->acl_add.priority =
- (int32_t)mh->match.acl.priority;
- } else {
- uint32_t *sa32 =
- (uint32_t *)mh->match.acl.ipv6.sa;
- uint32_t *da32 =
- (uint32_t *)mh->match.acl.ipv6.da;
- uint32_t sa32_depth[4], da32_depth[4];
- int status;
-
- status = match_convert_ipv6_depth(mh->match.acl.sa_depth,
- sa32_depth);
- if (status)
- return status;
-
- status = match_convert_ipv6_depth(mh->match.acl.da_depth,
- da32_depth);
- if (status)
- return status;
-
- ml->acl_delete.field_value[0].value.u8 =
- mh->match.acl.proto;
- ml->acl_delete.field_value[0].mask_range.u8 =
- mh->match.acl.proto_mask;
-
- ml->acl_delete.field_value[1].value.u32 =
- rte_be_to_cpu_32(sa32[0]);
- ml->acl_delete.field_value[1].mask_range.u32 =
- sa32_depth[0];
- ml->acl_delete.field_value[2].value.u32 =
- rte_be_to_cpu_32(sa32[1]);
- ml->acl_delete.field_value[2].mask_range.u32 =
- sa32_depth[1];
- ml->acl_delete.field_value[3].value.u32 =
- rte_be_to_cpu_32(sa32[2]);
- ml->acl_delete.field_value[3].mask_range.u32 =
- sa32_depth[2];
- ml->acl_delete.field_value[4].value.u32 =
- rte_be_to_cpu_32(sa32[3]);
- ml->acl_delete.field_value[4].mask_range.u32 =
- sa32_depth[3];
-
- ml->acl_delete.field_value[5].value.u32 =
- rte_be_to_cpu_32(da32[0]);
- ml->acl_delete.field_value[5].mask_range.u32 =
- da32_depth[0];
- ml->acl_delete.field_value[6].value.u32 =
- rte_be_to_cpu_32(da32[1]);
- ml->acl_delete.field_value[6].mask_range.u32 =
- da32_depth[1];
- ml->acl_delete.field_value[7].value.u32 =
- rte_be_to_cpu_32(da32[2]);
- ml->acl_delete.field_value[7].mask_range.u32 =
- da32_depth[2];
- ml->acl_delete.field_value[8].value.u32 =
- rte_be_to_cpu_32(da32[3]);
- ml->acl_delete.field_value[8].mask_range.u32 =
- da32_depth[3];
-
- ml->acl_delete.field_value[9].value.u16 =
- mh->match.acl.sp0;
- ml->acl_delete.field_value[9].mask_range.u16 =
- mh->match.acl.sp1;
-
- ml->acl_delete.field_value[10].value.u16 =
- mh->match.acl.dp0;
- ml->acl_delete.field_value[10].mask_range.u16 =
- mh->match.acl.dp1;
- }
- return 0;
-
- case TABLE_ARRAY:
- ml->array.pos = mh->match.array.pos;
- return 0;
-
- case TABLE_HASH:
- memcpy(ml->hash, mh->match.hash.key, sizeof(ml->hash));
- return 0;
-
- case TABLE_LPM:
- if (mh->match.lpm.ip_version) {
- ml->lpm_ipv4.ip = mh->match.lpm.ipv4;
- ml->lpm_ipv4.depth = mh->match.lpm.depth;
- } else {
- 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 softnic_table_rule_action *action,
- struct rte_pipeline_table_entry *data)
-{
- int status;
-
- /* Apply actions */
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_FWD)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_FWD,
- &action->fwd);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_LB)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_LB,
- &action->lb);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_MTR)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_MTR,
- &action->mtr);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TM)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TM,
- &action->tm);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_ENCAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_ENCAP,
- &action->encap);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_NAT)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_NAT,
- &action->nat);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TTL)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TTL,
- &action->ttl);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_STATS)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_STATS,
- &action->stats);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TIME)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TIME,
- &action->time);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_TAG)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_TAG,
- &action->tag);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_DECAP)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_DECAP,
- &action->decap);
-
- if (status)
- return status;
- }
-
- if (action->action_mask & (1LLU << RTE_TABLE_ACTION_SYM_CRYPTO)) {
- status = rte_table_action_apply(a,
- data,
- RTE_TABLE_ACTION_SYM_CRYPTO,
- &action->sym_crypto);
-
- if (status)
- return status;
- }
-
- return 0;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- union table_rule_match_low_level match_ll;
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;
- struct softnic_table_rule_match *match = &req->table_rule_add.match;
- struct softnic_table_rule_action *action = &req->table_rule_add.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int key_found, status;
- struct rte_table_action *a = p->table_data[table_id].a;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *)p->buffer;
-
- status = match_convert(match, &match_ll, 1);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = action_convert(a, action, data_in);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- status = rte_pipeline_table_entry_add(p->p,
- table_id,
- &match_ll,
- data_in,
- &key_found,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_default(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;
- struct softnic_table_rule_action *action = &req->table_rule_add_default.action;
- struct rte_pipeline_table_entry *data_in, *data_out;
- uint32_t table_id = req->id;
- int status;
-
- /* Apply actions */
- memset(p->buffer, 0, sizeof(p->buffer));
- data_in = (struct rte_pipeline_table_entry *)p->buffer;
-
- data_in->action = action->fwd.action;
- if (action->fwd.action == RTE_PIPELINE_ACTION_PORT)
- data_in->port_id = action->fwd.id;
- if (action->fwd.action == RTE_PIPELINE_ACTION_TABLE)
- data_in->table_id = action->fwd.id;
-
- /* Add default rule to table */
- status = rte_pipeline_table_default_entry_add(p->p,
- table_id,
- data_in,
- &data_out);
- if (status) {
- rsp->status = -1;
- return rsp;
- }
-
- /* Write response */
- rsp->status = 0;
- rsp->table_rule_add_default.data = data_out;
-
- return rsp;
-}
-
-static struct pipeline_msg_rsp *
-pipeline_msg_handle_table_rule_add_bulk(struct pipeline_data *p,
- struct pipeline_msg_req *req)
-{
- struct pipeline_msg_rsp *rsp = (struct pipeline_msg_rsp *)req;
-
- uint32_t table_id = req->id;
- struct softnic_table_rule_match *match = req->table_rule_add_bulk.match;
- struct softnic_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;
- }
- }
- }
-
- /* 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 softnic_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;
-
- 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;
- }
-
- pipeline_msg_send(p->msgq_rsp, rsp);
- }
-}
-
-/**
- * Data plane threads: main
- */
-static int32_t
-rte_pmd_softnic_run_internal(void *arg)
-{
- struct rte_eth_dev *dev = arg;
- struct pmd_internals *softnic;
- struct softnic_thread_data *t;
- uint32_t thread_id, j;
-
- softnic = dev->data->dev_private;
- thread_id = rte_lcore_id();
- t = &softnic->thread_data[thread_id];
- t->iter++;
-
- /* Data Plane */
- for (j = 0; j < t->n_pipelines; j++)
- rte_pipeline_run(t->p[j]);
-
- /* Control Plane */
- if ((t->iter & 0xFLLU) == 0) {
- uint64_t time = rte_get_tsc_cycles();
- uint64_t time_next_min = UINT64_MAX;
-
- if (time < t->time_next_min)
- return 0;
-
- /* Pipeline message queues */
- for (j = 0; j < t->n_pipelines; j++) {
- struct pipeline_data *p =
- &t->pipeline_data[j];
- uint64_t time_next = p->time_next;
-
- if (time_next <= time) {
- pipeline_msg_handle(p);
- rte_pipeline_flush(p->p);
- time_next = time + p->timer_period;
- p->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
+ if (time < time_next)
+ return 0;
/* Thread message queues */
- {
- uint64_t time_next = t->time_next;
-
- if (time_next <= time) {
- thread_msg_handle(t);
- time_next = time + t->timer_period;
- t->time_next = time_next;
- }
-
- if (time_next < time_next_min)
- time_next_min = time_next;
- }
+ thread_msg_handle(t);
- t->time_next_min = time_next_min;
+ t->time_next = time_next + t->timer_period;
}
return 0;