From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
To: dev@dpdk.org
Cc: thomas@monjalon.net, david.marchand@redhat.com
Subject: [dpdk-dev] [PATCH v5 31/41] pipeline: add SWX table update high level API
Date: Wed, 23 Sep 2020 19:06:35 +0100 [thread overview]
Message-ID: <20200923180645.55852-32-cristian.dumitrescu@intel.com> (raw)
In-Reply-To: <20200923180645.55852-1-cristian.dumitrescu@intel.com>
High-level transaction-oriented API for SWX pipeline table updates. It
supports multi-table atomic updates, i.e. multiple tables can be
updated in a single step with only the before and after table set
visible to the packets. Uses the lower-level table update mechanisms.
Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
lib/librte_pipeline/meson.build | 3 +-
lib/librte_pipeline/rte_pipeline_version.map | 15 +-
lib/librte_pipeline/rte_swx_ctl.c | 1552 ++++++++++++++++++
lib/librte_pipeline/rte_swx_ctl.h | 170 ++
4 files changed, 1736 insertions(+), 4 deletions(-)
create mode 100644 lib/librte_pipeline/rte_swx_ctl.c
diff --git a/lib/librte_pipeline/meson.build b/lib/librte_pipeline/meson.build
index d5f4d16e5..be1d9c3a4 100644
--- a/lib/librte_pipeline/meson.build
+++ b/lib/librte_pipeline/meson.build
@@ -4,7 +4,8 @@
sources = files('rte_pipeline.c',
'rte_port_in_action.c',
'rte_table_action.c',
- 'rte_swx_pipeline.c',)
+ 'rte_swx_pipeline.c',
+ 'rte_swx_ctl.c',)
headers = files('rte_pipeline.h',
'rte_port_in_action.h',
'rte_table_action.h',
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 730e11a0c..ec38f0eef 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -1,4 +1,4 @@
-DPDK_21 {
+DPDK_20.0 {
global:
rte_pipeline_ah_packet_drop;
@@ -75,8 +75,6 @@ EXPERIMENTAL {
rte_swx_pipeline_free;
rte_swx_pipeline_run;
rte_swx_pipeline_flush;
- rte_swx_pipeline_table_state_get;
- rte_swx_pipeline_table_state_set;
rte_swx_ctl_pipeline_info_get;
rte_swx_ctl_pipeline_numa_node_get;
rte_swx_ctl_pipeline_port_in_stats_read;
@@ -87,4 +85,15 @@ EXPERIMENTAL {
rte_swx_ctl_table_match_field_info_get;
rte_swx_ctl_table_action_info_get;
rte_swx_ctl_table_ops_get;
+ rte_swx_pipeline_table_state_get;
+ rte_swx_pipeline_table_state_set;
+ rte_swx_ctl_pipeline_create;
+ rte_swx_ctl_pipeline_free;
+ rte_swx_ctl_pipeline_table_entry_add;
+ rte_swx_ctl_pipeline_table_default_entry_add;
+ rte_swx_ctl_pipeline_table_entry_delete;
+ rte_swx_ctl_pipeline_commit;
+ rte_swx_ctl_pipeline_abort;
+ rte_swx_ctl_pipeline_table_entry_read;
+ rte_swx_ctl_pipeline_table_fprintf;
};
diff --git a/lib/librte_pipeline/rte_swx_ctl.c b/lib/librte_pipeline/rte_swx_ctl.c
new file mode 100644
index 000000000..576fb2bf3
--- /dev/null
+++ b/lib/librte_pipeline/rte_swx_ctl.c
@@ -0,0 +1,1552 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/queue.h>
+#include <unistd.h>
+
+#include <rte_common.h>
+#include <rte_byteorder.h>
+
+#include "rte_swx_ctl.h"
+
+#define CHECK(condition, err_code) \
+do { \
+ if (!(condition)) \
+ return -(err_code); \
+} while (0)
+
+#define ntoh64(x) rte_be_to_cpu_64(x)
+#define hton64(x) rte_cpu_to_be_64(x)
+
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+#define field_ntoh(val, n_bits) (ntoh64((val) << (64 - n_bits)))
+#define field_hton(val, n_bits) (hton64((val) << (64 - n_bits)))
+#else
+#define field_ntoh(val, n_bits) (val)
+#define field_hton(val, n_bits) (val)
+#endif
+
+struct action {
+ struct rte_swx_ctl_action_info info;
+ struct rte_swx_ctl_action_arg_info *args;
+ uint32_t data_size;
+};
+
+struct table {
+ struct rte_swx_ctl_table_info info;
+ struct rte_swx_ctl_table_match_field_info *mf;
+ struct rte_swx_ctl_table_action_info *actions;
+ struct rte_swx_table_ops ops;
+ struct rte_swx_table_params params;
+
+ struct rte_swx_table_entry_list entries;
+ struct rte_swx_table_entry_list pending_add;
+ struct rte_swx_table_entry_list pending_modify0;
+ struct rte_swx_table_entry_list pending_modify1;
+ struct rte_swx_table_entry_list pending_delete;
+ struct rte_swx_table_entry *pending_default;
+
+ int is_stub;
+ uint32_t n_add;
+ uint32_t n_modify;
+ uint32_t n_delete;
+};
+
+struct rte_swx_ctl_pipeline {
+ struct rte_swx_ctl_pipeline_info info;
+ struct rte_swx_pipeline *p;
+ struct action *actions;
+ struct table *tables;
+ struct rte_swx_table_state *ts;
+ struct rte_swx_table_state *ts_next;
+ int numa_node;
+};
+
+static struct action *
+action_find(struct rte_swx_ctl_pipeline *ctl, const char *action_name)
+{
+ uint32_t i;
+
+ for (i = 0; i < ctl->info.n_actions; i++) {
+ struct action *a = &ctl->actions[i];
+
+ if (!strcmp(action_name, a->info.name))
+ return a;
+ }
+
+ return NULL;
+}
+
+static void
+action_free(struct rte_swx_ctl_pipeline *ctl)
+{
+ uint32_t i;
+
+ if (!ctl->actions)
+ return;
+
+ for (i = 0; i < ctl->info.n_actions; i++) {
+ struct action *action = &ctl->actions[i];
+
+ free(action->args);
+ }
+
+ free(ctl->actions);
+ ctl->actions = NULL;
+}
+
+static struct table *
+table_find(struct rte_swx_ctl_pipeline *ctl, const char *table_name)
+{
+ uint32_t i;
+
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ struct table *table = &ctl->tables[i];
+
+ if (!strcmp(table_name, table->info.name))
+ return table;
+ }
+
+ return NULL;
+}
+
+static int
+table_params_get(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id)
+{
+ struct table *table = &ctl->tables[table_id];
+ uint8_t *key_mask = NULL;
+ enum rte_swx_table_match_type match_type = RTE_SWX_TABLE_MATCH_WILDCARD;
+ uint32_t key_size = 0, key_offset = 0, action_data_size = 0, i;
+
+ if (table->info.n_match_fields) {
+ struct rte_swx_ctl_table_match_field_info *first, *last;
+ uint32_t i;
+
+ first = &table->mf[0];
+ last = &table->mf[table->info.n_match_fields - 1];
+
+ /* match_type. */
+ for (i = 0; i < table->info.n_match_fields; i++) {
+ struct rte_swx_ctl_table_match_field_info *f;
+
+ f = &table->mf[i];
+ if (f->match_type != RTE_SWX_TABLE_MATCH_EXACT)
+ break;
+ }
+
+ if (i == table->info.n_match_fields)
+ match_type = RTE_SWX_TABLE_MATCH_EXACT;
+ else if ((i == table->info.n_match_fields - 1) &&
+ (last->match_type == RTE_SWX_TABLE_MATCH_LPM))
+ match_type = RTE_SWX_TABLE_MATCH_LPM;
+
+ /* key_offset. */
+ key_offset = first->offset / 8;
+
+ /* key_size. */
+ key_size = (last->offset + last->n_bits - first->offset) / 8;
+
+ /* key_mask. */
+ key_mask = calloc(1, key_size);
+ CHECK(key_mask, ENOMEM);
+
+ for (i = 0; i < table->info.n_match_fields; i++) {
+ struct rte_swx_ctl_table_match_field_info *f;
+ uint32_t start;
+ size_t size;
+
+ f = &table->mf[i];
+ start = (f->offset - first->offset) / 8;
+ size = f->n_bits / 8;
+
+ memset(&key_mask[start], 0xFF, size);
+ }
+ }
+
+ /* action_data_size. */
+ for (i = 0; i < table->info.n_actions; i++) {
+ uint32_t action_id = table->actions[i].action_id;
+ struct action *a = &ctl->actions[action_id];
+
+ if (a->data_size > action_data_size)
+ action_data_size = a->data_size;
+ }
+
+ /* Fill in. */
+ table->params.match_type = match_type;
+ table->params.key_size = key_size;
+ table->params.key_offset = key_offset;
+ table->params.key_mask0 = key_mask;
+ table->params.action_data_size = action_data_size;
+ table->params.n_keys_max = table->info.size;
+
+ return 0;
+}
+
+static void
+table_entry_free(struct rte_swx_table_entry *entry)
+{
+ if (!entry)
+ return;
+
+ free(entry->key);
+ free(entry->key_mask);
+ free(entry->action_data);
+ free(entry);
+}
+
+static struct rte_swx_table_entry *
+table_entry_alloc(struct table *table)
+{
+ struct rte_swx_table_entry *entry;
+
+ entry = calloc(1, sizeof(struct rte_swx_table_entry));
+ if (!entry)
+ goto error;
+
+ /* key, key_mask. */
+ if (!table->is_stub) {
+ entry->key = calloc(1, table->params.key_size);
+ if (!entry->key)
+ goto error;
+
+ if (table->params.match_type != RTE_SWX_TABLE_MATCH_EXACT) {
+ entry->key_mask = calloc(1, table->params.key_size);
+ if (!entry->key_mask)
+ goto error;
+ }
+ }
+
+ /* action_data. */
+ if (table->params.action_data_size) {
+ entry->action_data = calloc(1, table->params.action_data_size);
+ if (!entry->action_data)
+ goto error;
+ }
+
+ return entry;
+
+error:
+ table_entry_free(entry);
+ return NULL;
+}
+
+static int
+table_entry_check(struct rte_swx_ctl_pipeline *ctl,
+ uint32_t table_id,
+ struct rte_swx_table_entry *entry,
+ int key_check,
+ int data_check)
+{
+ struct table *table = &ctl->tables[table_id];
+
+ CHECK(entry, EINVAL);
+
+ if (key_check) {
+ if (table->is_stub) {
+ /* key. */
+ CHECK(!entry->key, EINVAL);
+
+ /* key_mask. */
+ CHECK(!entry->key_mask, EINVAL);
+ } else {
+ /* key. */
+ CHECK(entry->key, EINVAL);
+
+ /* key_mask. */
+ switch (table->params.match_type) {
+ case RTE_SWX_TABLE_MATCH_WILDCARD:
+ break;
+
+ case RTE_SWX_TABLE_MATCH_LPM:
+ /* TBD Check that key mask is prefix. */
+ break;
+
+ case RTE_SWX_TABLE_MATCH_EXACT:
+ CHECK(!entry->key_mask, EINVAL);
+ break;
+
+ default:
+ CHECK(0, EINVAL);
+ }
+ }
+ }
+
+ if (data_check) {
+ struct action *a;
+ uint32_t i;
+
+ /* action_id. */
+ for (i = 0; i < table->info.n_actions; i++)
+ if (entry->action_id == table->actions[i].action_id)
+ break;
+
+ CHECK(i < table->info.n_actions, EINVAL);
+
+ /* action_data. */
+ a = &ctl->actions[entry->action_id];
+ CHECK((a->data_size && entry->action_data) ||
+ (!a->data_size && !entry->action_data), EINVAL);
+ }
+
+ return 0;
+}
+
+static struct rte_swx_table_entry *
+table_entry_duplicate(struct rte_swx_ctl_pipeline *ctl,
+ uint32_t table_id,
+ struct rte_swx_table_entry *entry,
+ int key_duplicate,
+ int data_duplicate)
+{
+ struct table *table = &ctl->tables[table_id];
+ struct rte_swx_table_entry *new_entry = NULL;
+
+ if (!entry)
+ goto error;
+
+ new_entry = calloc(1, sizeof(struct rte_swx_table_entry));
+ if (!new_entry)
+ goto error;
+
+ if (key_duplicate && !table->is_stub) {
+ /* key. */
+ if (!entry->key)
+ goto error;
+
+ new_entry->key = malloc(table->params.key_size);
+ if (!new_entry->key)
+ goto error;
+
+ memcpy(new_entry->key, entry->key, table->params.key_size);
+
+ /* key_signature. */
+ new_entry->key_signature = entry->key_signature;
+
+ /* key_mask. */
+ if (table->params.match_type != RTE_SWX_TABLE_MATCH_EXACT) {
+ if (!entry->key_mask)
+ goto error;
+
+ new_entry->key_mask = malloc(table->params.key_size);
+ if (!new_entry->key_mask)
+ goto error;
+
+ memcpy(new_entry->key_mask,
+ entry->key_mask,
+ table->params.key_size);
+ }
+ }
+
+ if (data_duplicate) {
+ struct action *a;
+ uint32_t i;
+
+ /* action_id. */
+ for (i = 0; i < table->info.n_actions; i++)
+ if (entry->action_id == table->actions[i].action_id)
+ break;
+
+ if (i >= table->info.n_actions)
+ goto error;
+
+ new_entry->action_id = entry->action_id;
+
+ /* action_data. */
+ a = &ctl->actions[entry->action_id];
+ if (a->data_size) {
+ if (!entry->action_data)
+ goto error;
+
+ new_entry->action_data = malloc(a->data_size);
+ if (!new_entry->action_data)
+ goto error;
+
+ memcpy(new_entry->action_data,
+ entry->action_data,
+ a->data_size);
+ }
+ }
+
+ return entry;
+
+error:
+ table_entry_free(new_entry);
+ return NULL;
+}
+
+static int
+entry_keycmp_em(struct rte_swx_table_entry *e0,
+ struct rte_swx_table_entry *e1,
+ uint32_t key_size)
+{
+ if (e0->key_signature != e1->key_signature)
+ return 1; /* Not equal. */
+
+ if (memcmp(e0->key, e1->key, key_size))
+ return 1; /* Not equal. */
+
+ return 0; /* Equal */
+}
+
+static int
+entry_keycmp_wm(struct rte_swx_table_entry *e0 __rte_unused,
+ struct rte_swx_table_entry *e1 __rte_unused,
+ uint32_t key_size __rte_unused)
+{
+ /* TBD */
+
+ return 1; /* Not equal */
+}
+
+static int
+entry_keycmp_lpm(struct rte_swx_table_entry *e0 __rte_unused,
+ struct rte_swx_table_entry *e1 __rte_unused,
+ uint32_t key_size __rte_unused)
+{
+ /* TBD */
+
+ return 1; /* Not equal */
+}
+
+static int
+table_entry_keycmp(struct table *table,
+ struct rte_swx_table_entry *e0,
+ struct rte_swx_table_entry *e1)
+{
+ switch (table->params.match_type) {
+ case RTE_SWX_TABLE_MATCH_EXACT:
+ return entry_keycmp_em(e0, e1, table->params.key_size);
+
+ case RTE_SWX_TABLE_MATCH_WILDCARD:
+ return entry_keycmp_wm(e0, e1, table->params.key_size);
+
+ case RTE_SWX_TABLE_MATCH_LPM:
+ return entry_keycmp_lpm(e0, e1, table->params.key_size);
+
+ default:
+ return 1; /* Not equal. */
+ }
+}
+
+static struct rte_swx_table_entry *
+table_entries_find(struct table *table, struct rte_swx_table_entry *entry)
+{
+ struct rte_swx_table_entry *e;
+
+ TAILQ_FOREACH(e, &table->entries, node)
+ if (!table_entry_keycmp(table, entry, e))
+ return e; /* Found. */
+
+ return NULL; /* Not found. */
+}
+
+static void
+table_entries_free(struct table *table)
+{
+ for ( ; ; ) {
+ struct rte_swx_table_entry *entry;
+
+ entry = TAILQ_FIRST(&table->entries);
+ if (!entry)
+ break;
+
+ TAILQ_REMOVE(&table->entries, entry, node);
+ table_entry_free(entry);
+ }
+}
+
+static struct rte_swx_table_entry *
+table_pending_add_find(struct table *table, struct rte_swx_table_entry *entry)
+{
+ struct rte_swx_table_entry *e;
+
+ TAILQ_FOREACH(e, &table->pending_add, node)
+ if (!table_entry_keycmp(table, entry, e))
+ return e; /* Found. */
+
+ return NULL; /* Not found. */
+}
+
+static void
+table_pending_add_admit(struct table *table)
+{
+ TAILQ_CONCAT(&table->entries, &table->pending_add, node);
+}
+
+static void
+table_pending_add_free(struct table *table)
+{
+ for ( ; ; ) {
+ struct rte_swx_table_entry *entry;
+
+ entry = TAILQ_FIRST(&table->pending_add);
+ if (!entry)
+ break;
+
+ TAILQ_REMOVE(&table->pending_add, entry, node);
+ table_entry_free(entry);
+ }
+}
+
+static struct rte_swx_table_entry *
+table_pending_modify0_find(struct table *table,
+ struct rte_swx_table_entry *entry)
+{
+ struct rte_swx_table_entry *e;
+
+ TAILQ_FOREACH(e, &table->pending_modify0, node)
+ if (!table_entry_keycmp(table, entry, e))
+ return e; /* Found. */
+
+ return NULL; /* Not found. */
+}
+
+static void
+table_pending_modify0_admit(struct table *table)
+{
+ TAILQ_CONCAT(&table->entries, &table->pending_modify0, node);
+}
+
+static void
+table_pending_modify0_free(struct table *table)
+{
+ for ( ; ; ) {
+ struct rte_swx_table_entry *entry;
+
+ entry = TAILQ_FIRST(&table->pending_modify0);
+ if (!entry)
+ break;
+
+ TAILQ_REMOVE(&table->pending_modify0, entry, node);
+ table_entry_free(entry);
+ }
+}
+
+static struct rte_swx_table_entry *
+table_pending_modify1_find(struct table *table,
+ struct rte_swx_table_entry *entry)
+{
+ struct rte_swx_table_entry *e;
+
+ TAILQ_FOREACH(e, &table->pending_modify1, node)
+ if (!table_entry_keycmp(table, entry, e))
+ return e; /* Found. */
+
+ return NULL; /* Not found. */
+}
+
+static void
+table_pending_modify1_admit(struct table *table)
+{
+ TAILQ_CONCAT(&table->entries, &table->pending_modify1, node);
+}
+
+static void
+table_pending_modify1_free(struct table *table)
+{
+ for ( ; ; ) {
+ struct rte_swx_table_entry *entry;
+
+ entry = TAILQ_FIRST(&table->pending_modify1);
+ if (!entry)
+ break;
+
+ TAILQ_REMOVE(&table->pending_modify1, entry, node);
+ table_entry_free(entry);
+ }
+}
+
+static struct rte_swx_table_entry *
+table_pending_delete_find(struct table *table,
+ struct rte_swx_table_entry *entry)
+{
+ struct rte_swx_table_entry *e;
+
+ TAILQ_FOREACH(e, &table->pending_delete, node)
+ if (!table_entry_keycmp(table, entry, e))
+ return e; /* Found. */
+
+ return NULL; /* Not found. */
+}
+
+static void
+table_pending_delete_admit(struct table *table)
+{
+ TAILQ_CONCAT(&table->entries, &table->pending_delete, node);
+}
+
+static void
+table_pending_delete_free(struct table *table)
+{
+ for ( ; ; ) {
+ struct rte_swx_table_entry *entry;
+
+ entry = TAILQ_FIRST(&table->pending_delete);
+ if (!entry)
+ break;
+
+ TAILQ_REMOVE(&table->pending_delete, entry, node);
+ table_entry_free(entry);
+ }
+}
+
+static void
+table_pending_default_free(struct table *table)
+{
+ if (!table->pending_default)
+ return;
+
+ free(table->pending_default->action_data);
+ free(table->pending_default);
+ table->pending_default = NULL;
+}
+
+static void
+table_free(struct rte_swx_ctl_pipeline *ctl)
+{
+ uint32_t i;
+
+ if (!ctl->tables)
+ return;
+
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ struct table *table = &ctl->tables[i];
+
+ free(table->mf);
+ free(table->actions);
+ free(table->params.key_mask0);
+
+ table_entries_free(table);
+ table_pending_add_free(table);
+ table_pending_modify0_free(table);
+ table_pending_modify1_free(table);
+ table_pending_delete_free(table);
+ table_pending_default_free(table);
+ }
+
+ free(ctl->tables);
+ ctl->tables = NULL;
+}
+
+static void
+table_state_free(struct rte_swx_ctl_pipeline *ctl)
+{
+ uint32_t i;
+
+ if (!ctl->ts_next)
+ return;
+
+ /* For each table, free its table state. */
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ struct table *table = &ctl->tables[i];
+ struct rte_swx_table_state *ts = &ctl->ts_next[i];
+
+ /* Default action data. */
+ free(ts->default_action_data);
+
+ /* Table object. */
+ if (!table->is_stub && table->ops.free && ts->obj)
+ table->ops.free(ts->obj);
+ }
+
+ free(ctl->ts_next);
+ ctl->ts_next = NULL;
+}
+
+static int
+table_state_create(struct rte_swx_ctl_pipeline *ctl)
+{
+ int status = 0;
+ uint32_t i;
+
+ ctl->ts_next = calloc(ctl->info.n_tables,
+ sizeof(struct rte_swx_table_state));
+ if (!ctl->ts_next) {
+ status = -ENOMEM;
+ goto error;
+ }
+
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ struct table *table = &ctl->tables[i];
+ struct rte_swx_table_state *ts = &ctl->ts[i];
+ struct rte_swx_table_state *ts_next = &ctl->ts_next[i];
+
+ /* Table object. */
+ if (!table->is_stub) {
+ ts_next->obj = table->ops.create(&table->params,
+ &table->entries,
+ table->info.args,
+ ctl->numa_node);
+ if (!ts_next->obj) {
+ status = -ENODEV;
+ goto error;
+ }
+ }
+
+ /* Default action data: duplicate from current table state. */
+ ts_next->default_action_data =
+ malloc(table->params.action_data_size);
+ if (!ts_next->default_action_data) {
+ status = -ENOMEM;
+ goto error;
+ }
+
+ memcpy(ts_next->default_action_data,
+ ts->default_action_data,
+ table->params.action_data_size);
+
+ ts_next->default_action_id = ts->default_action_id;
+ }
+
+ return 0;
+
+error:
+ table_state_free(ctl);
+ return status;
+}
+
+void
+rte_swx_ctl_pipeline_free(struct rte_swx_ctl_pipeline *ctl)
+{
+ if (!ctl)
+ return;
+
+ action_free(ctl);
+
+ table_state_free(ctl);
+
+ table_free(ctl);
+
+ free(ctl);
+}
+
+struct rte_swx_ctl_pipeline *
+rte_swx_ctl_pipeline_create(struct rte_swx_pipeline *p)
+{
+ struct rte_swx_ctl_pipeline *ctl = NULL;
+ uint32_t i;
+ int status;
+
+ if (!p)
+ goto error;
+
+ ctl = calloc(1, sizeof(struct rte_swx_ctl_pipeline));
+ if (!ctl)
+ goto error;
+
+ /* info. */
+ status = rte_swx_ctl_pipeline_info_get(p, &ctl->info);
+ if (status)
+ goto error;
+
+ /* numa_node. */
+ status = rte_swx_ctl_pipeline_numa_node_get(p, &ctl->numa_node);
+ if (status)
+ goto error;
+
+ /* p. */
+ ctl->p = p;
+
+ /* actions. */
+ ctl->actions = calloc(ctl->info.n_actions, sizeof(struct action));
+ if (!ctl->actions)
+ goto error;
+
+ for (i = 0; i < ctl->info.n_actions; i++) {
+ struct action *a = &ctl->actions[i];
+ uint32_t j;
+
+ /* info. */
+ status = rte_swx_ctl_action_info_get(p, i, &a->info);
+ if (status)
+ goto error;
+
+ /* args. */
+ a->args = calloc(a->info.n_args,
+ sizeof(struct rte_swx_ctl_action_arg_info));
+ if (!a->args)
+ goto error;
+
+ for (j = 0; j < a->info.n_args; j++) {
+ status = rte_swx_ctl_action_arg_info_get(p,
+ i,
+ j,
+ &a->args[j]);
+ if (status)
+ goto error;
+ }
+
+ /* data_size. */
+ for (j = 0; j < a->info.n_args; j++) {
+ struct rte_swx_ctl_action_arg_info *info = &a->args[j];
+
+ a->data_size += info->n_bits;
+ }
+
+ a->data_size = (a->data_size + 7) / 8;
+ }
+
+ /* tables. */
+ ctl->tables = calloc(ctl->info.n_tables, sizeof(struct table));
+ if (!ctl->tables)
+ goto error;
+
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ struct table *t = &ctl->tables[i];
+
+ TAILQ_INIT(&t->entries);
+ TAILQ_INIT(&t->pending_add);
+ TAILQ_INIT(&t->pending_modify0);
+ TAILQ_INIT(&t->pending_modify1);
+ TAILQ_INIT(&t->pending_delete);
+ }
+
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ struct table *t = &ctl->tables[i];
+ uint32_t j;
+
+ /* info. */
+ status = rte_swx_ctl_table_info_get(p, i, &t->info);
+ if (status)
+ goto error;
+
+ /* mf. */
+ t->mf = calloc(t->info.n_match_fields,
+ sizeof(struct rte_swx_ctl_table_match_field_info));
+ if (!t->mf)
+ goto error;
+
+ for (j = 0; j < t->info.n_match_fields; j++) {
+ status = rte_swx_ctl_table_match_field_info_get(p,
+ i,
+ j,
+ &t->mf[j]);
+ if (status)
+ goto error;
+ }
+
+ /* actions. */
+ t->actions = calloc(t->info.n_actions,
+ sizeof(struct rte_swx_ctl_table_action_info));
+ if (!t->actions)
+ goto error;
+
+ for (j = 0; j < t->info.n_actions; j++) {
+ status = rte_swx_ctl_table_action_info_get(p,
+ i,
+ j,
+ &t->actions[j]);
+ if (status ||
+ t->actions[j].action_id >= ctl->info.n_actions)
+ goto error;
+ }
+
+ /* ops, is_stub. */
+ status = rte_swx_ctl_table_ops_get(p, i, &t->ops, &t->is_stub);
+ if (status)
+ goto error;
+
+ if ((t->is_stub && t->info.n_match_fields) ||
+ (!t->is_stub && !t->info.n_match_fields))
+ goto error;
+
+ /* params. */
+ status = table_params_get(ctl, i);
+ if (status)
+ goto error;
+ }
+
+ /* ts. */
+ status = rte_swx_pipeline_table_state_get(p, &ctl->ts);
+ if (status)
+ goto error;
+
+ /* ts_next. */
+ status = table_state_create(ctl);
+ if (status)
+ goto error;
+
+ return ctl;
+
+error:
+ rte_swx_ctl_pipeline_free(ctl);
+ return NULL;
+}
+
+int
+rte_swx_ctl_pipeline_table_entry_add(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ struct rte_swx_table_entry *entry)
+{
+ struct table *table;
+ struct rte_swx_table_entry *new_entry, *existing_entry;
+ uint32_t table_id;
+
+ CHECK(ctl, EINVAL);
+ CHECK(table_name && table_name[0], EINVAL);
+
+ table = table_find(ctl, table_name);
+ CHECK(table, EINVAL);
+ table_id = table - ctl->tables;
+
+ new_entry = table_entry_duplicate(ctl, table_id, entry, 1, 1);
+ CHECK(new_entry, ENOMEM);
+
+ /* The new entry is found in the table->entries list:
+ * - Add the new entry to the table->pending_modify1 list;
+ * - Move the existing entry from the table->entries list to the
+ * table->pending_modify0 list.
+ */
+ existing_entry = table_entries_find(table, entry);
+ if (existing_entry) {
+ TAILQ_INSERT_TAIL(&table->pending_modify1,
+ new_entry,
+ node);
+
+ TAILQ_REMOVE(&table->entries,
+ existing_entry,
+ node);
+
+ TAILQ_INSERT_TAIL(&table->pending_modify0,
+ existing_entry,
+ node);
+
+ return 0;
+ }
+
+ /* The new entry is found in the table->pending_add list:
+ * - Replace the entry in the table->pending_add list with the new entry
+ * (and free the replaced entry).
+ */
+ existing_entry = table_pending_add_find(table, entry);
+ if (existing_entry) {
+ TAILQ_INSERT_AFTER(&table->pending_add,
+ existing_entry,
+ new_entry,
+ node);
+
+ TAILQ_REMOVE(&table->pending_add,
+ existing_entry,
+ node);
+
+ table_entry_free(existing_entry);
+
+ return 0;
+ }
+
+ /* The new entry is found in the table->pending_modify1 list:
+ * - Replace the entry in the table->pending_modify1 list with the new
+ * entry (and free the replaced entry).
+ */
+ existing_entry = table_pending_modify1_find(table, entry);
+ if (existing_entry) {
+ TAILQ_INSERT_AFTER(&table->pending_modify1,
+ existing_entry,
+ new_entry,
+ node);
+
+ TAILQ_REMOVE(&table->pending_modify1,
+ existing_entry,
+ node);
+
+ table_entry_free(existing_entry);
+
+ return 0;
+ }
+
+ /* The new entry is found in the table->pending_delete list:
+ * - Add the new entry to the table->pending_modify1 list;
+ * - Move the existing entry from the table->pending_delete list to the
+ * table->pending_modify0 list.
+ */
+ existing_entry = table_pending_delete_find(table, entry);
+ if (existing_entry) {
+ TAILQ_INSERT_TAIL(&table->pending_modify1,
+ new_entry,
+ node);
+
+ TAILQ_REMOVE(&table->pending_delete,
+ existing_entry,
+ node);
+
+ TAILQ_INSERT_TAIL(&table->pending_modify0,
+ existing_entry,
+ node);
+
+ return 0;
+ }
+
+ /* The new entry is not found in any of the above lists:
+ * - Add the new entry to the table->pending_add list.
+ */
+ TAILQ_INSERT_TAIL(&table->pending_add, new_entry, node);
+
+ return 0;
+}
+
+int
+rte_swx_ctl_pipeline_table_entry_delete(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ struct rte_swx_table_entry *entry)
+{
+ struct table *table;
+ struct rte_swx_table_entry *existing_entry;
+ uint32_t table_id;
+
+ CHECK(ctl, EINVAL);
+
+ CHECK(table_name && table_name[0], EINVAL);
+ table = table_find(ctl, table_name);
+ CHECK(table, EINVAL);
+ table_id = table - ctl->tables;
+
+ CHECK(entry, EINVAL);
+ CHECK(!table_entry_check(ctl, table_id, entry, 1, 0), EINVAL);
+
+ /* The entry is found in the table->entries list:
+ * - Move the existing entry from the table->entries list to to the
+ * table->pending_delete list.
+ */
+ existing_entry = table_entries_find(table, entry);
+ if (existing_entry) {
+ TAILQ_REMOVE(&table->entries,
+ existing_entry,
+ node);
+
+ TAILQ_INSERT_TAIL(&table->pending_delete,
+ existing_entry,
+ node);
+
+ return 0;
+ }
+
+ /* The entry is found in the table->pending_add list:
+ * - Remove the entry from the table->pending_add list and free it.
+ */
+ existing_entry = table_pending_add_find(table, entry);
+ if (existing_entry) {
+ TAILQ_REMOVE(&table->pending_add,
+ existing_entry,
+ node);
+
+ table_entry_free(existing_entry);
+ }
+
+ /* The entry is found in the table->pending_modify1 list:
+ * - Free the entry in the table->pending_modify1 list;
+ * - Move the existing entry from the table->pending_modify0 list to the
+ * table->pending_delete list.
+ */
+ existing_entry = table_pending_modify1_find(table, entry);
+ if (existing_entry) {
+ struct rte_swx_table_entry *real_existing_entry;
+
+ TAILQ_REMOVE(&table->pending_modify1,
+ existing_entry,
+ node);
+
+ table_entry_free(existing_entry);
+
+ real_existing_entry = table_pending_modify0_find(table, entry);
+ CHECK(real_existing_entry, EINVAL); /* Coverity. */
+
+ TAILQ_REMOVE(&table->pending_modify0,
+ real_existing_entry,
+ node);
+
+ TAILQ_INSERT_TAIL(&table->pending_delete,
+ real_existing_entry,
+ node);
+
+ return 0;
+ }
+
+ /* The entry is found in the table->pending_delete list:
+ * - Do nothing: the existing entry is already in the
+ * table->pending_delete list, i.e. already marked for delete, so
+ * simply keep it there as it is.
+ */
+
+ /* The entry is not found in any of the above lists:
+ * - Do nothing: no existing entry to delete.
+ */
+
+ return 0;
+}
+
+int
+rte_swx_ctl_pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ struct rte_swx_table_entry *entry)
+{
+ struct table *table;
+ struct rte_swx_table_entry *new_entry;
+ uint32_t table_id;
+
+ CHECK(ctl, EINVAL);
+
+ CHECK(table_name && table_name[0], EINVAL);
+ table = table_find(ctl, table_name);
+ CHECK(table, EINVAL);
+ table_id = table - ctl->tables;
+ CHECK(!table->info.default_action_is_const, EINVAL);
+
+ new_entry = table_entry_duplicate(ctl, table_id, entry, 0, 1);
+ CHECK(new_entry, ENOMEM);
+
+ table_pending_default_free(table);
+
+ table->pending_default = new_entry;
+ return 0;
+}
+
+static int
+table_rollfwd0(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id)
+{
+ struct table *table = &ctl->tables[table_id];
+ struct rte_swx_table_state *ts_next = &ctl->ts_next[table_id];
+ struct rte_swx_table_entry *entry;
+
+ /* Reset counters. */
+ table->n_add = 0;
+ table->n_modify = 0;
+ table->n_delete = 0;
+
+ /* Add pending rules. */
+ TAILQ_FOREACH(entry, &table->pending_add, node) {
+ int status;
+
+ status = table->ops.add(ts_next->obj, entry);
+ if (status)
+ return status;
+
+ table->n_add++;
+ }
+
+ /* Modify pending rules. */
+ TAILQ_FOREACH(entry, &table->pending_modify1, node) {
+ int status;
+
+ status = table->ops.add(ts_next->obj, entry);
+ if (status)
+ return status;
+
+ table->n_modify++;
+ }
+
+ /* Delete pending rules. */
+ TAILQ_FOREACH(entry, &table->pending_delete, node) {
+ int status;
+
+ status = table->ops.del(ts_next->obj, entry);
+ if (status)
+ return status;
+
+ table->n_delete++;
+ }
+
+ return 0;
+}
+
+static void
+table_rollfwd1(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id)
+{
+ struct table *table = &ctl->tables[table_id];
+ struct rte_swx_table_state *ts_next = &ctl->ts_next[table_id];
+ struct action *a;
+ uint8_t *action_data;
+ uint64_t action_id;
+
+ /* Copy the pending default entry. */
+ if (!table->pending_default)
+ return;
+
+ action_id = table->pending_default->action_id;
+ action_data = table->pending_default->action_data;
+ a = &ctl->actions[action_id];
+
+ memcpy(ts_next->default_action_data,
+ action_data,
+ a->data_size);
+
+ ts_next->default_action_id = action_id;
+}
+
+static void
+table_rollfwd2(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id)
+{
+ struct table *table = &ctl->tables[table_id];
+
+ /* Move all the pending add entries to the table, as they are now part
+ * of the table.
+ */
+ table_pending_add_admit(table);
+
+ /* Move all the pending modify1 entries to table, are they are now part
+ * of the table. Free up all the pending modify0 entries, as they are no
+ * longer part of the table.
+ */
+ table_pending_modify1_admit(table);
+ table_pending_modify0_free(table);
+
+ /* Free up all the pending delete entries, as they are no longer part of
+ * the table.
+ */
+ table_pending_delete_free(table);
+
+ /* Free up the pending default entry, as it is now part of the table. */
+ table_pending_default_free(table);
+}
+
+static void
+table_rollback(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id)
+{
+ struct table *table = &ctl->tables[table_id];
+ struct rte_swx_table_state *ts_next = &ctl->ts_next[table_id];
+ struct rte_swx_table_entry *entry;
+
+ /* Add back all the entries that were just deleted. */
+ TAILQ_FOREACH(entry, &table->pending_delete, node) {
+ if (!table->n_delete)
+ break;
+
+ table->ops.add(ts_next->obj, entry);
+ table->n_delete--;
+ }
+
+ /* Add back the old copy for all the entries that were just
+ * modified.
+ */
+ TAILQ_FOREACH(entry, &table->pending_modify0, node) {
+ if (!table->n_modify)
+ break;
+
+ table->ops.add(ts_next->obj, entry);
+ table->n_modify--;
+ }
+
+ /* Delete all the entries that were just added. */
+ TAILQ_FOREACH(entry, &table->pending_add, node) {
+ if (!table->n_add)
+ break;
+
+ table->ops.del(ts_next->obj, entry);
+ table->n_add--;
+ }
+}
+
+static void
+table_abort(struct rte_swx_ctl_pipeline *ctl, uint32_t table_id)
+{
+ struct table *table = &ctl->tables[table_id];
+
+ /* Free up all the pending add entries, as none of them is part of the
+ * table.
+ */
+ table_pending_add_free(table);
+
+ /* Free up all the pending modify1 entries, as none of them made it to
+ * the table. Add back all the pending modify0 entries, as none of them
+ * was deleted from the table.
+ */
+ table_pending_modify1_free(table);
+ table_pending_modify0_admit(table);
+
+ /* Add back all the pending delete entries, as none of them was deleted
+ * from the table.
+ */
+ table_pending_delete_admit(table);
+
+ /* Free up the pending default entry, as it is no longer going to be
+ * added to the table.
+ */
+ table_pending_default_free(table);
+}
+
+int
+rte_swx_ctl_pipeline_commit(struct rte_swx_ctl_pipeline *ctl, int abort_on_fail)
+{
+ struct rte_swx_table_state *ts;
+ int status = 0;
+ uint32_t i;
+
+ CHECK(ctl, EINVAL);
+
+ /* Operate the changes on the current ts_next before it becomes the new
+ * ts.
+ */
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ status = table_rollfwd0(ctl, i);
+ if (status)
+ goto rollback;
+ }
+
+ for (i = 0; i < ctl->info.n_tables; i++)
+ table_rollfwd1(ctl, i);
+
+ /* Swap the table state for the data plane. The current ts and ts_next
+ * become the new ts_next and ts, respectively.
+ */
+ rte_swx_pipeline_table_state_set(ctl->p, ctl->ts_next);
+ usleep(100);
+ ts = ctl->ts;
+ ctl->ts = ctl->ts_next;
+ ctl->ts_next = ts;
+
+ /* Operate the changes on the current ts_next, which is the previous ts.
+ */
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ table_rollfwd0(ctl, i);
+ table_rollfwd1(ctl, i);
+ table_rollfwd2(ctl, i);
+ }
+
+ return 0;
+
+rollback:
+ for (i = 0; i < ctl->info.n_tables; i++) {
+ table_rollback(ctl, i);
+ if (abort_on_fail)
+ table_abort(ctl, i);
+ }
+
+ return status;
+}
+
+void
+rte_swx_ctl_pipeline_abort(struct rte_swx_ctl_pipeline *ctl)
+{
+ uint32_t i;
+
+ if (!ctl)
+ return;
+
+ for (i = 0; i < ctl->info.n_tables; i++)
+ table_abort(ctl, i);
+}
+
+#define RTE_SWX_CTL_ENTRY_TOKENS_MAX 256
+
+struct rte_swx_table_entry *
+rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ const char *string)
+{
+ char *tokens[RTE_SWX_CTL_ENTRY_TOKENS_MAX];
+ struct table *table;
+ struct action *action;
+ struct rte_swx_table_entry *entry = NULL;
+ char *s0 = NULL, *s;
+ uint32_t n_tokens = 0, arg_offset = 0, i;
+
+ /* Check input arguments. */
+ if (!ctl)
+ goto error;
+
+ if (!table_name || !table_name[0])
+ goto error;
+
+ table = table_find(ctl, table_name);
+ if (!table)
+ goto error;
+
+ if (!string || !string[0])
+ goto error;
+
+ /* Memory allocation. */
+ s0 = strdup(string);
+ if (!s0)
+ goto error;
+
+ entry = table_entry_alloc(table);
+ if (!entry)
+ goto error;
+
+ /* Parse the string into tokens. */
+ for (s = s0; ; ) {
+ char *token;
+
+ token = strtok_r(s, " \f\n\r\t\v", &s);
+ if (!token)
+ break;
+
+ if (n_tokens >= RTE_SWX_CTL_ENTRY_TOKENS_MAX)
+ goto error;
+
+ tokens[n_tokens] = token;
+ n_tokens++;
+ }
+
+ if ((n_tokens < 3 + table->info.n_match_fields) ||
+ strcmp(tokens[0], "match") ||
+ strcmp(tokens[1 + table->info.n_match_fields], "action"))
+ goto error;
+
+ action = action_find(ctl, tokens[2 + table->info.n_match_fields]);
+ if (!action)
+ goto error;
+
+ if (n_tokens != 3 + table->info.n_match_fields +
+ action->info.n_args * 2)
+ goto error;
+
+ /*
+ * Match.
+ */
+ for (i = 0; i < table->info.n_match_fields; i++) {
+ struct rte_swx_ctl_table_match_field_info *mf = &table->mf[i];
+ char *mf_val = tokens[1 + i];
+ uint64_t val;
+
+ val = strtoull(mf_val, &mf_val, 0);
+ if (mf_val[0])
+ goto error;
+
+ /* Endianness conversion. */
+ if (mf->is_header)
+ val = field_hton(val, mf->n_bits);
+
+ /* Copy key and key_mask to entry. */
+ memcpy(&entry->key[(mf->offset - table->mf[0].offset) / 8],
+ (uint8_t *)&val,
+ mf->n_bits / 8);
+
+ /* TBD Set entry->key_mask for wildcard and LPM tables. */
+ }
+
+ /*
+ * Action.
+ */
+ /* action_id. */
+ entry->action_id = action - ctl->actions;
+
+ /* action_data. */
+ for (i = 0; i < action->info.n_args; i++) {
+ struct rte_swx_ctl_action_arg_info *arg = &action->args[i];
+ char *arg_name, *arg_val;
+ uint64_t val;
+ int is_nbo = 0;
+
+ arg_name = tokens[3 + table->info.n_match_fields + i * 2];
+ arg_val = tokens[3 + table->info.n_match_fields + i * 2 + 1];
+
+ if (strcmp(arg_name, arg->name) ||
+ (strlen(arg_val) < 4) ||
+ ((arg_val[0] != 'H') && (arg_val[0] != 'N')) ||
+ (arg_val[1] != '(') ||
+ (arg_val[strlen(arg_val) - 1] != ')'))
+ goto error;
+
+ if (arg_val[0] == 'N')
+ is_nbo = 1;
+
+ arg_val[strlen(arg_val) - 1] = 0; /* Remove the ')'. */
+ arg_val += 2; /* Remove the "H(" or "N(". */
+
+ val = strtoull(arg_val, &arg_val, 0);
+ if (arg_val[0])
+ goto error;
+
+ /* Endianness conversion. */
+ if (is_nbo)
+ val = field_hton(val, arg->n_bits);
+
+ /* Copy to entry. */
+ memcpy(&entry->action_data[arg_offset],
+ (uint8_t *)&val,
+ arg->n_bits / 8);
+
+ arg_offset += arg->n_bits / 8;
+ }
+
+ return entry;
+
+error:
+ table_entry_free(entry);
+ free(s0);
+ return NULL;
+}
+
+int
+rte_swx_ctl_pipeline_table_fprintf(FILE *f,
+ struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name)
+{
+ struct table *table;
+ struct rte_swx_table_entry *entry;
+ uint32_t n_entries = 0, i;
+
+ if (!f || !ctl || !table_name || !table_name[0])
+ return -EINVAL;
+
+ table = table_find(ctl, table_name);
+ if (!table)
+ return -EINVAL;
+
+ /* Table. */
+ fprintf(f, "# Table %s: key size %u bytes, key offset %u, key mask [",
+ table->info.name,
+ table->params.key_size,
+ table->params.key_offset);
+
+ for (i = 0; i < table->params.key_size; i++)
+ fprintf(f, "%02x", table->params.key_mask0[i]);
+
+ fprintf(f, "], action data size %u bytes\n",
+ table->params.action_data_size);
+
+ /* Table entries. */
+ TAILQ_FOREACH(entry, &table->entries, node) {
+ struct action *action = &ctl->actions[entry->action_id];
+
+ fprintf(f, "match ");
+ for (i = 0; i < table->params.key_size; i++)
+ fprintf(f, "%02x", entry->key[i]);
+
+ fprintf(f, " action %s ", action->info.name);
+ for (i = 0; i < action->data_size; i++)
+ fprintf(f, "%02x", entry->action_data[i]);
+
+ fprintf(f, "\n");
+ n_entries++;
+ }
+
+ TAILQ_FOREACH(entry, &table->pending_modify0, node) {
+ struct action *action = &ctl->actions[entry->action_id];
+
+ fprintf(f, "match ");
+ for (i = 0; i < table->params.key_size; i++)
+ fprintf(f, "%02x", entry->key[i]);
+
+ fprintf(f, " action %s ", action->info.name);
+ for (i = 0; i < action->data_size; i++)
+ fprintf(f, "%02x", entry->action_data[i]);
+
+ fprintf(f, "\n");
+ n_entries++;
+ }
+
+ TAILQ_FOREACH(entry, &table->pending_delete, node) {
+ struct action *action = &ctl->actions[entry->action_id];
+
+ fprintf(f, "match ");
+ for (i = 0; i < table->params.key_size; i++)
+ fprintf(f, "%02x", entry->key[i]);
+
+ fprintf(f, " action %s ", action->info.name);
+ for (i = 0; i < action->data_size; i++)
+ fprintf(f, "%02x", entry->action_data[i]);
+
+ fprintf(f, "\n");
+ n_entries++;
+ }
+
+ fprintf(f, "# Table %s currently has %u entries.\n",
+ table_name,
+ n_entries);
+ return 0;
+}
diff --git a/lib/librte_pipeline/rte_swx_ctl.h b/lib/librte_pipeline/rte_swx_ctl.h
index 344c7c833..18b065834 100644
--- a/lib/librte_pipeline/rte_swx_ctl.h
+++ b/lib/librte_pipeline/rte_swx_ctl.h
@@ -391,6 +391,176 @@ int
rte_swx_pipeline_table_state_set(struct rte_swx_pipeline *p,
struct rte_swx_table_state *table_state);
+/*
+ * High Level Reference Table Update API.
+ */
+
+/** Pipeline control opaque data structure. */
+struct rte_swx_ctl_pipeline;
+
+/**
+ * Pipeline control create
+ *
+ * @param[in] p
+ * Pipeline handle.
+ * @return
+ * Pipeline control handle, on success, or NULL, on error.
+ */
+__rte_experimental
+struct rte_swx_ctl_pipeline *
+rte_swx_ctl_pipeline_create(struct rte_swx_pipeline *p);
+
+/**
+ * Pipeline table entry add
+ *
+ * Schedule entry for addition to table or update as part of the next commit
+ * operation.
+ *
+ * @param[in] ctl
+ * Pipeline control handle.
+ * @param[in] table_name
+ * Table name.
+ * @param[in] entry
+ * Entry to be added to the table.
+ * @return
+ * 0 on success or the following error codes otherwise:
+ * -EINVAL: Invalid argument.
+ */
+__rte_experimental
+int
+rte_swx_ctl_pipeline_table_entry_add(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ struct rte_swx_table_entry *entry);
+
+/**
+ * Pipeline table default entry add
+ *
+ * Schedule table default entry update as part of the next commit operation.
+ *
+ * @param[in] ctl
+ * Pipeline control handle.
+ * @param[in] table_name
+ * Table name.
+ * @param[in] entry
+ * The new table default entry. The *key* and *key_mask* entry fields are
+ * ignored.
+ * @return
+ * 0 on success or the following error codes otherwise:
+ * -EINVAL: Invalid argument.
+ */
+__rte_experimental
+int
+rte_swx_ctl_pipeline_table_default_entry_add(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ struct rte_swx_table_entry *entry);
+
+/**
+ * Pipeline table entry delete
+ *
+ * Schedule entry for deletion from table as part of the next commit operation.
+ * Request is silently discarded if no such entry exists.
+ *
+ * @param[in] ctl
+ * Pipeline control handle.
+ * @param[in] table_name
+ * Table name.
+ * @param[in] entry
+ * Entry to be deleted from the table. The *action_id* and *action_data* entry
+ * fields are ignored.
+ * @return
+ * 0 on success or the following error codes otherwise:
+ * -EINVAL: Invalid argument.
+ */
+__rte_experimental
+int
+rte_swx_ctl_pipeline_table_entry_delete(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ struct rte_swx_table_entry *entry);
+
+/**
+ * Pipeline commit
+ *
+ * Perform all the scheduled table work.
+ *
+ * @param[in] ctl
+ * Pipeline control handle.
+ * @param[in] abort_on_fail
+ * When non-zero (false), all the scheduled work is discarded after a failed
+ * commit. Otherwise, the scheduled work is still kept pending for the next
+ * commit.
+ * @return
+ * 0 on success or the following error codes otherwise:
+ * -EINVAL: Invalid argument.
+ */
+__rte_experimental
+int
+rte_swx_ctl_pipeline_commit(struct rte_swx_ctl_pipeline *ctl,
+ int abort_on_fail);
+
+/**
+ * Pipeline abort
+ *
+ * Discard all the scheduled table work.
+ *
+ * @param[in] ctl
+ * Pipeline control handle.
+ */
+__rte_experimental
+void
+rte_swx_ctl_pipeline_abort(struct rte_swx_ctl_pipeline *ctl);
+
+/**
+ * Pipeline table entry read
+ *
+ * Read table entry from string.
+ *
+ * @param[in] ctl
+ * Pipeline control handle.
+ * @param[in] table_name
+ * Table name.
+ * @param[in] string
+ * String containing the table entry.
+ * @return
+ * 0 on success or the following error codes otherwise:
+ * -EINVAL: Invalid argument.
+ */
+__rte_experimental
+struct rte_swx_table_entry *
+rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name,
+ const char *string);
+
+/**
+ * Pipeline table print to file
+ *
+ * Print all the table entries to file.
+ *
+ * @param[in] f
+ * Output file.
+ * @param[in] ctl
+ * Pipeline control handle.
+ * @param[in] table_name
+ * Table name.
+ * @return
+ * 0 on success or the following error codes otherwise:
+ * -EINVAL: Invalid argument.
+ */
+__rte_experimental
+int
+rte_swx_ctl_pipeline_table_fprintf(FILE *f,
+ struct rte_swx_ctl_pipeline *ctl,
+ const char *table_name);
+
+/**
+ * Pipeline control free
+ *
+ * @param[in] ctl
+ * Pipeline control handle.
+ */
+__rte_experimental
+void
+rte_swx_ctl_pipeline_free(struct rte_swx_ctl_pipeline *ctl);
+
#ifdef __cplusplus
}
#endif
--
2.17.1
next prev parent reply other threads:[~2020-09-23 18:12 UTC|newest]
Thread overview: 329+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-08-26 15:14 [dpdk-dev] [PATCH 00/40] Pipeline alignment with the P4 language Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 01/40] pipeline: add pipeline Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 00/41] Pipeline alignment with the P4 language Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 01/41] pipeline: add new SWX pipeline type Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 00/41] Pipeline alignment with the P4 language Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 01/41] pipeline: add new SWX pipeline type Cristian Dumitrescu
2020-09-09 19:05 ` Stephen Hemminger
2020-09-09 19:52 ` Dumitrescu, Cristian
2020-09-10 8:42 ` Bruce Richardson
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 00/41] Pipeline alignment with the P4 language Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 01/41] pipeline: add new SWX pipeline type Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 00/41] Pipeline alignment with the P4 language Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 01/41] pipeline: add new SWX pipeline type Cristian Dumitrescu
2020-09-23 18:24 ` Stephen Hemminger
2020-09-23 18:37 ` Dumitrescu, Cristian
2020-09-23 20:23 ` Stephen Hemminger
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 00/42] Pipeline alignment with the P4 language Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 01/42] pipeline: add new SWX pipeline type Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 00/42] Pipeline alignment with the P4 language Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 01/42] pipeline: add new SWX pipeline type Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 02/42] pipeline: add SWX pipeline input port Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 03/42] pipeline: add SWX pipeline output port Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 04/42] pipeline: add SWX headers and meta-data Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 05/42] pipeline: add SWX extern objects and funcs Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 06/42] pipeline: add SWX pipeline action Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 07/42] pipeline: add SWX pipeline tables Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 08/42] pipeline: add SWX pipeline instructions Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 09/42] pipeline: add SWX Rx and extract instructions Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 10/42] pipeline: add SWX Tx and emit instructions Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 11/42] pipeline: add header validate and invalidate SWX instructions Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 12/42] pipeline: add SWX move instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 13/42] pipeline: add SWX DMA instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 14/42] pipeline: introduce SWX add instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 15/42] pipeline: introduce SWX subtract instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 16/42] pipeline: introduce SWX ckadd instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 17/42] pipeline: introduce SWX cksub instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 18/42] pipeline: introduce SWX and instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 19/42] pipeline: introduce SWX or instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 20/42] pipeline: introduce SWX XOR instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 21/42] pipeline: introduce SWX SHL instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 22/42] pipeline: introduce SWX SHR instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 23/42] pipeline: introduce SWX table instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 24/42] pipeline: introduce SWX extern instruction Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 25/42] pipeline: introduce SWX jump and return instructions Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 26/42] pipeline: add SWX instruction description Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 27/42] pipeline: add SWX instruction verifier Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 28/42] pipeline: add SWX instruction optimizer Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 29/42] pipeline: add SWX pipeline query API Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 30/42] pipeline: add SWX pipeline flush Cristian Dumitrescu
2020-10-01 10:19 ` [dpdk-dev] [PATCH v7 31/42] pipeline: add SWX table update high level API Cristian Dumitrescu
2020-10-01 12:03 ` David Marchand
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 32/42] pipeline: add SWX pipeline specification file Cristian Dumitrescu
2020-10-04 7:50 ` Raslan Darawsheh
2020-10-04 9:01 ` David Marchand
2020-10-04 10:47 ` Raslan Darawsheh
2020-10-04 18:28 ` Dumitrescu, Cristian
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 33/42] port: add ethernet device SWX port Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 34/42] port: add source and sink SWX ports Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 35/42] table: add exact match SWX table Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 36/42] examples/pipeline: add new example application Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 37/42] examples/pipeline: add message passing mechanism Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 38/42] examples/pipeline: add configuration commands Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 39/42] examples/pipeline: add l2fwd example Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 40/42] examples/pipeline: add l2fwd with MAC swap example Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 41/42] examples/pipeline: add VXLAN encapsulation example Cristian Dumitrescu
2020-10-01 10:20 ` [dpdk-dev] [PATCH v7 42/42] doc: add new SWX pipeline type to release notes Cristian Dumitrescu
2020-10-01 17:15 ` [dpdk-dev] [PATCH v7 00/42] Pipeline alignment with the P4 language David Marchand
2020-10-01 17:22 ` Dumitrescu, Cristian
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 02/42] pipeline: add SWX pipeline input port Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 03/42] pipeline: add SWX pipeline output port Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 04/42] pipeline: add SWX headers and meta-data Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 05/42] pipeline: add SWX extern objects and funcs Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 06/42] pipeline: add SWX pipeline action Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 07/42] pipeline: add SWX pipeline tables Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 08/42] pipeline: add SWX pipeline instructions Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 09/42] pipeline: add SWX Rx and extract instructions Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 10/42] pipeline: add SWX Tx and emit instructions Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 11/42] pipeline: add header validate and invalidate SWX instructions Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 12/42] pipeline: add SWX move instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 13/42] pipeline: add SWX DMA instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 14/42] pipeline: introduce SWX add instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 15/42] pipeline: introduce SWX subtract instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 16/42] pipeline: introduce SWX ckadd instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 17/42] pipeline: introduce SWX cksub instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 18/42] pipeline: introduce SWX and instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 19/42] pipeline: introduce SWX or instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 20/42] pipeline: introduce SWX XOR instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 21/42] pipeline: introduce SWX SHL instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 22/42] pipeline: introduce SWX SHR instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 23/42] pipeline: introduce SWX table instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 24/42] pipeline: introduce SWX extern instruction Cristian Dumitrescu
2020-09-30 6:33 ` [dpdk-dev] [PATCH v6 25/42] pipeline: introduce SWX jump and return instructions Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 26/42] pipeline: add SWX instruction description Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 27/42] pipeline: add SWX instruction verifier Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 28/42] pipeline: add SWX instruction optimizer Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 29/42] pipeline: add SWX pipeline query API Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 30/42] pipeline: add SWX pipeline flush Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 31/42] pipeline: add SWX table update high level API Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 32/42] pipeline: add SWX pipeline specification file Cristian Dumitrescu
2020-10-04 7:48 ` Raslan Darawsheh
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 33/42] port: add ethernet device SWX port Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 34/42] port: add source and sink SWX ports Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 35/42] table: add exact match SWX table Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 36/42] examples/pipeline: add new example application Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 37/42] examples/pipeline: add message passing mechanism Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 38/42] examples/pipeline: add configuration commands Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 39/42] examples/pipeline: add l2fwd example Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 40/42] examples/pipeline: add l2fwd with MAC swap example Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 41/42] examples/pipeline: add VXLAN encapsulation example Cristian Dumitrescu
2020-09-30 6:34 ` [dpdk-dev] [PATCH v6 42/42] doc: add new SWX pipeline type to release notes Cristian Dumitrescu
2020-09-30 19:34 ` [dpdk-dev] [PATCH v6 00/42] Pipeline alignment with the P4 language David Marchand
2020-10-01 10:45 ` Dumitrescu, Cristian
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 02/41] pipeline: add SWX pipeline input port Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 03/41] pipeline: add SWX pipeline output port Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 04/41] pipeline: add SWX headers and meta-data Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 05/41] pipeline: add SWX extern objects and funcs Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 06/41] pipeline: add SWX pipeline action Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 07/41] pipeline: add SWX pipeline tables Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 08/41] pipeline: add SWX pipeline instructions Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 09/41] pipeline: add SWX Rx and extract instructions Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 10/41] pipeline: add SWX Tx and emit instructions Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 11/41] pipeline: add header validate and invalidate SWX instructions Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 12/41] pipeline: add SWX move instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 13/41] pipeline: add SWX DMA instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 14/41] pipeline: introduce SWX add instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 15/41] pipeline: introduce SWX subtract instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 16/41] pipeline: introduce SWX ckadd instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 17/41] pipeline: introduce SWX cksub instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 18/41] pipeline: introduce SWX and instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 19/41] pipeline: introduce SWX or instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 20/41] pipeline: introduce SWX XOR instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 21/41] pipeline: introduce SWX SHL instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 22/41] pipeline: introduce SWX SHR instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 23/41] pipeline: introduce SWX table instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 24/41] pipeline: introduce SWX extern instruction Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 25/41] pipeline: introduce SWX jump and return instructions Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 26/41] pipeline: add SWX instruction description Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 27/41] pipeline: add SWX instruction verifier Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 28/41] pipeline: add SWX instruction optimizer Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 29/41] pipeline: add SWX pipeline query API Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 30/41] pipeline: add SWX pipeline flush Cristian Dumitrescu
2020-09-23 18:06 ` Cristian Dumitrescu [this message]
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 32/41] pipeline: add SWX pipeline specification file Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 33/41] port: add ethernet device SWX port Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 34/41] port: add source and sink SWX ports Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 35/41] table: add exact match SWX table Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 36/41] examples/pipeline: add new example application Cristian Dumitrescu
2020-09-23 18:26 ` Stephen Hemminger
2020-09-23 18:30 ` Dumitrescu, Cristian
2020-09-29 13:51 ` David Marchand
2020-09-30 6:50 ` Dumitrescu, Cristian
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 37/41] examples/pipeline: add message passing mechanism Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 38/41] examples/pipeline: add configuration commands Cristian Dumitrescu
2020-09-29 13:51 ` David Marchand
2020-09-30 6:50 ` Dumitrescu, Cristian
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 39/41] examples/pipeline: add l2fwd example Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 40/41] examples/pipeline: add l2fwd with MAC swap example Cristian Dumitrescu
2020-09-23 18:06 ` [dpdk-dev] [PATCH v5 41/41] examples/pipeline: add VXLAN encapsulation example Cristian Dumitrescu
2020-09-29 14:08 ` [dpdk-dev] [PATCH v5 00/41] Pipeline alignment with the P4 language David Marchand
2020-09-30 6:50 ` Dumitrescu, Cristian
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 02/41] pipeline: add SWX pipeline input port Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 03/41] pipeline: add SWX pipeline output port Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 04/41] pipeline: add SWX headers and meta-data Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 05/41] pipeline: add SWX extern objects and funcs Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 06/41] pipeline: add SWX pipeline action Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 07/41] pipeline: add SWX pipeline tables Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 08/41] pipeline: add SWX pipeline instructions Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 09/41] pipeline: add SWX rx and extract instructions Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 10/41] pipeline: add SWX tx and emit instructions Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 11/41] pipeline: add header validate and invalidate SWX instructions Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 12/41] pipeline: add SWX mov instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 13/41] pipeline: add SWX dma instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 14/41] pipeline: introduce SWX add instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 15/41] pipeline: introduce SWX sub instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 16/41] pipeline: introduce SWX ckadd instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 17/41] pipeline: introduce SWX cksub instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 18/41] pipeline: introduce SWX and instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 19/41] pipeline: introduce SWX or instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 20/41] pipeline: introduce SWX xor instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 21/41] pipeline: introduce SWX shl instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 22/41] pipeline: introduce SWX shr instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 23/41] pipeline: introduce SWX table instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 24/41] pipeline: introduce SWX extern instruction Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 25/41] pipeline: introduce SWX jmp and return instructions Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 26/41] pipeline: add SWX instruction description Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 27/41] pipeline: add SWX instruction verifier Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 28/41] pipeline: add SWX instruction optimizer Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 29/41] pipeline: add SWX pipeline query API Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 30/41] pipeline: add SWX pipeline flush Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 31/41] pipeline: add SWX table update high level API Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 32/41] pipeline: add SWX pipeline specification file Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 33/41] port: add ethernet device SWX port Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 34/41] port: add source and sink SWX ports Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 35/41] table: add exact match SWX table Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 36/41] examples/pipeline: add new example application Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 37/41] examples/pipeline: add message passing mechanism Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 38/41] examples/pipeline: add configuration commands Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 39/41] examples/pipeline: add l2fwd example Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 40/41] examples/pipeline: add l2fwd with MAC swap example Cristian Dumitrescu
2020-09-10 15:26 ` [dpdk-dev] [PATCH v4 41/41] examples/pipeline: add VXLAN encapsulation example Cristian Dumitrescu
2020-09-22 20:05 ` [dpdk-dev] [PATCH v4 00/41] Pipeline alignment with the P4 language Wang, Han2
2020-09-22 20:08 ` Dumitrescu, Cristian
2020-09-23 11:45 ` David Marchand
2020-09-23 16:07 ` Dumitrescu, Cristian
2020-09-23 16:28 ` David Marchand
2020-09-23 16:40 ` Thomas Monjalon
2020-09-23 16:49 ` Dumitrescu, Cristian
2020-09-23 19:02 ` Dumitrescu, Cristian
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 02/41] pipeline: add SWX pipeline input port Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 03/41] pipeline: add SWX pipeline output port Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 04/41] pipeline: add SWX headers and meta-data Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 05/41] pipeline: add SWX extern objects and funcs Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 06/41] pipeline: add SWX pipeline action Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 07/41] pipeline: add SWX pipeline tables Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 08/41] pipeline: add SWX pipeline instructions Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 09/41] pipeline: add SWX rx and extract instructions Cristian Dumitrescu
2020-09-08 20:17 ` [dpdk-dev] [PATCH v3 10/41] pipeline: add SWX tx and emit instructions Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 11/41] pipeline: add header validate and invalidate SWX instructions Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 12/41] pipeline: add SWX mov instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 13/41] pipeline: add SWX dma instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 14/41] pipeline: introduce SWX add instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 15/41] pipeline: introduce SWX sub instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 16/41] pipeline: introduce SWX ckadd instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 17/41] pipeline: introduce SWX cksub instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 18/41] pipeline: introduce SWX and instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 19/41] pipeline: introduce SWX or instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 20/41] pipeline: introduce SWX xor instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 21/41] pipeline: introduce SWX shl instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 22/41] pipeline: introduce SWX shr instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 23/41] pipeline: introduce SWX table instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 24/41] pipeline: introduce SWX extern instruction Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 25/41] pipeline: introduce SWX jmp and return instructions Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 26/41] pipeline: add SWX instruction description Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 27/41] pipeline: add SWX instruction verifier Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 28/41] pipeline: add SWX instruction optimizer Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 29/41] pipeline: add SWX pipeline query API Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 30/41] pipeline: add SWX pipeline flush Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 31/41] pipeline: add SWX table update high level API Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 32/41] pipeline: add SWX pipeline specification file Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 33/41] port: add ethernet device SWX port Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 34/41] port: add source and sink SWX ports Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 35/41] table: add exact match SWX table Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 36/41] examples/pipeline: add new example application Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 37/41] examples/pipeline: add message passing mechanism Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 38/41] examples/pipeline: add configuration commands Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 39/41] examples/pipeline: add l2fwd example Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 40/41] examples/pipeline: add l2fwd with MAC swap example Cristian Dumitrescu
2020-09-08 20:18 ` [dpdk-dev] [PATCH v3 41/41] examples/pipeline: add VXLAN encapsulation example Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 02/41] pipeline: add SWX pipeline input port Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 03/41] pipeline: add SWX pipeline output port Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 04/41] pipeline: add SWX headers and meta-data Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 05/41] pipeline: add SWX extern objects and funcs Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 06/41] pipeline: add SWX pipeline action Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 07/41] pipeline: add SWX pipeline tables Cristian Dumitrescu
2020-09-07 21:39 ` [dpdk-dev] [PATCH v2 08/41] pipeline: add SWX pipeline instructions Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 09/41] pipeline: add SWX rx and extract instructions Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 10/41] pipeline: add SWX tx and emit instructions Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 11/41] pipeline: add header validate and invalidate SWX instructions Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 12/41] pipeline: add SWX mov instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 13/41] pipeline: add SWX dma instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 14/41] pipeline: introduce SWX add instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 15/41] pipeline: introduce SWX sub instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 16/41] pipeline: introduce SWX ckadd instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 17/41] pipeline: introduce SWX cksub instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 18/41] pipeline: introduce SWX and instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 19/41] pipeline: introduce SWX or instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 20/41] pipeline: introduce SWX xor instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 21/41] pipeline: introduce SWX shl instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 22/41] pipeline: introduce SWX shr instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 23/41] pipeline: introduce SWX table instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 24/41] pipeline: introduce SWX extern instruction Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 25/41] pipeline: introduce SWX jmp and return instructions Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 26/41] pipeline: add SWX instruction description Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 27/41] pipeline: add SWX instruction verifier Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 28/41] pipeline: add SWX instruction optimizer Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 29/41] pipeline: add SWX pipeline query API Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 30/41] pipeline: add SWX pipeline flush Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 31/41] pipeline: add SWX table update high level API Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 32/41] pipeline: add SWX pipeline specification file Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 33/41] port: add ethernet device SWX port Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 34/41] port: add source and sink SWX ports Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 35/41] table: add exact match SWX table Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 36/41] examples/pipeline: add new example application Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 37/41] examples/pipeline: add message passing mechanism Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 38/41] examples/pipeline: add configuration commands Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 39/41] examples/pipeline: add l2fwd example Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 40/41] examples/pipeline: add l2fwd with MAC swap example Cristian Dumitrescu
2020-09-07 21:40 ` [dpdk-dev] [PATCH v2 41/41] examples/pipeline: add VXLAN encapsulation example Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 02/40] pipeline: add input port Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 03/40] pipeline: add output port Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 04/40] pipeline: add headers and meta-data Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 05/40] pipeline: add extern objects and functions Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 06/40] pipeline: add action Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 07/40] pipeline: add tables Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 08/40] pipeline: add pipeline instructions Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 09/40] pipeline: add rx and extract instructions Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 10/40] pipeline: add tx and emit instructions Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 11/40] pipeline: add header validate and invalidate instructions Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 12/40] pipeline: add mov instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 13/40] pipeline: add dma instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 14/40] pipeline: introduce add instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 15/40] pipeline: introduce sub instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 16/40] pipeline: introduce ckadd instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 17/40] pipeline: introduce cksub instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 18/40] pipeline: introduce and instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 19/40] pipeline: introduce or instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 20/40] pipeline: introduce xor instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 21/40] pipeline: introduce shl instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 22/40] pipeline: introduce shr instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 23/40] pipeline: introduce table instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 24/40] pipeline: introduce extern instruction Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 25/40] pipeline: introduce jmp and return instructions Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 26/40] pipeline: add instruction verifier Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 27/40] pipeline: add instruction optimizer Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 28/40] pipeline: add pipeline query API Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 29/40] pipeline: add pipeline flush Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 30/40] pipeline: add instruction description Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 31/40] pipeline: add table update high level API Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 32/40] port: add ethernet device port Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 33/40] port: add source and sink ports Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 34/40] table: add exact match table Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 35/40] examples/pipeline: add new example application Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 36/40] examples/pipeline: add message passing mechanism Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 37/40] examples/pipeline: add configuration commands Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 38/40] examples/pipeline: add l2fwd example Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 39/40] examples/pipeline: add l2fwd with MAC swap example Cristian Dumitrescu
2020-08-26 15:14 ` [dpdk-dev] [PATCH 40/40] examples/pipeline: add VXLAN encap example Cristian Dumitrescu
2020-08-26 17:05 ` Stephen Hemminger
2020-09-07 21:49 ` Dumitrescu, Cristian
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200923180645.55852-32-cristian.dumitrescu@intel.com \
--to=cristian.dumitrescu@intel.com \
--cc=david.marchand@redhat.com \
--cc=dev@dpdk.org \
--cc=thomas@monjalon.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).