Add L2 Forwarding example to the pipeline application. Example command
line: ./build/pipeline -l0-1 -- -s ./examples/l2fwd.cli

Signed-off-by: Cristian Dumitrescu <cristian.dumitre...@intel.com>
---
 examples/pipeline/Makefile                |   1 +
 examples/pipeline/cli.c                   |  16 ++-
 examples/pipeline/example_l2fwd.c         | 125 ++++++++++++++++++++++
 examples/pipeline/examples/l2fwd.cli      |  25 +++++
 examples/pipeline/examples/l2fwd_pcap.cli |  20 ++++
 examples/pipeline/examples/packet.txt     | 102 ++++++++++++++++++
 examples/pipeline/meson.build             |   1 +
 7 files changed, 289 insertions(+), 1 deletion(-)
 create mode 100644 examples/pipeline/example_l2fwd.c
 create mode 100644 examples/pipeline/examples/l2fwd.cli
 create mode 100644 examples/pipeline/examples/l2fwd_pcap.cli
 create mode 100644 examples/pipeline/examples/packet.txt

diff --git a/examples/pipeline/Makefile b/examples/pipeline/Makefile
index dcc0f67bf..405978ced 100644
--- a/examples/pipeline/Makefile
+++ b/examples/pipeline/Makefile
@@ -10,6 +10,7 @@ SRCS-y += conn.c
 SRCS-y += main.c
 SRCS-y += obj.c
 SRCS-y += thread.c
+SRCS-y += example_l2fwd.c
 
 # Build using pkg-config variables if possible
 ifeq ($(shell pkg-config --exists libdpdk && echo 0),0)
diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c
index f68a1a924..a54cd79ff 100644
--- a/examples/pipeline/cli.c
+++ b/examples/pipeline/cli.c
@@ -730,6 +730,7 @@ cmd_pipeline_port_out(char **tokens,
 static const char cmd_pipeline_build_help[] =
 "pipeline <pipeline_name> build <app>\n";
 
+int pipeline_setup_l2fwd(struct rte_swx_pipeline *p);
 static void
 cmd_pipeline_build(char **tokens,
        uint32_t n_tokens,
@@ -738,7 +739,7 @@ cmd_pipeline_build(char **tokens,
        void *obj)
 {
        struct pipeline *p;
-       char *name;
+       char *name, *app;
        int status;
 
        if (n_tokens != 4) {
@@ -753,6 +754,19 @@ cmd_pipeline_build(char **tokens,
                return;
        }
 
+       app = tokens[3];
+       if (!strcmp(app, "l2fwd"))
+               status = pipeline_setup_l2fwd(p->p);
+       else {
+               snprintf(out, out_size, MSG_ARG_INVALID, tokens[0]);
+               return;
+       }
+
+       if (status) {
+               snprintf(out, out_size, "Pipeline build: app setup error.");
+               return;
+       }
+
        status = rte_swx_pipeline_build(p->p);
        if (status) {
                snprintf(out, out_size, "Pipeline build failed.");
diff --git a/examples/pipeline/example_l2fwd.c 
b/examples/pipeline/example_l2fwd.c
new file mode 100644
index 000000000..a0b627709
--- /dev/null
+++ b/examples/pipeline/example_l2fwd.c
@@ -0,0 +1,125 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include <rte_common.h>
+
+#include "rte_swx_pipeline.h"
+#include "rte_swx_port_ethdev.h"
+#include "rte_swx_port_source_sink.h"
+#include "rte_swx_table_em.h"
+
+#define CHECK(condition)                                                       
\
+do {                                                                           
\
+       if (!(condition)) {                                                    \
+               printf("Error in function %s at line %d\n",                    \
+                       __FUNCTION__, __LINE__);                               \
+               return -1;                                                     \
+       }                                                                      \
+} while (0)
+
+/*
+ * Packet headers.
+ */
+
+/*
+ * Packet meta-data.
+ */
+static struct rte_swx_field_params metadata_type[] = {
+       {"port_in", 32},
+       {"port_out", 32},
+};
+
+/*
+ * Actions.
+ */
+static const char *action_passthrough_instructions[] = {
+       "return",
+};
+
+/*
+ * Tables.
+ */
+static const char *table_stub_actions[] = {"passthrough"};
+
+static struct rte_swx_pipeline_table_params table_stub_params = {
+       /* Match. */
+       .fields = NULL,
+       .n_fields = 0,
+
+       /* Action. */
+       .action_names = table_stub_actions,
+       .n_actions = RTE_DIM(table_stub_actions),
+       .default_action_name = "passthrough",
+       .default_action_data = NULL,
+       .default_action_is_const = 0,
+};
+
+/*
+ * Pipeline.
+ */
+static const char *pipeline_instructions[] = {
+       "rx m.port_in",
+       "table stub",
+       "tx m.port_in",
+};
+
+int
+pipeline_setup_l2fwd(struct rte_swx_pipeline *p);
+
+int
+pipeline_setup_l2fwd(struct rte_swx_pipeline *p)
+{
+       int err;
+
+       /*
+        * Packet headers.
+        */
+
+       /*
+        * Packet meta-data.
+        */
+       err = rte_swx_pipeline_struct_type_register(p,
+               "metadata_type",
+               metadata_type,
+               RTE_DIM(metadata_type));
+       CHECK(!err);
+
+       err = rte_swx_pipeline_packet_metadata_register(p,
+               "metadata_type");
+       CHECK(!err);
+
+       /*
+        * Actions.
+        */
+       err = rte_swx_pipeline_action_config(p,
+               "passthrough",
+               NULL,
+               action_passthrough_instructions,
+               RTE_DIM(action_passthrough_instructions));
+       CHECK(!err);
+
+       /*
+        * Tables.
+        */
+       err = rte_swx_pipeline_table_config(p,
+               "stub",
+               &table_stub_params,
+               NULL,
+               NULL,
+               0);
+       CHECK(!err);
+
+       /*
+        * Pipeline.
+        */
+       err = rte_swx_pipeline_instructions_config(p,
+               pipeline_instructions,
+               RTE_DIM(pipeline_instructions));
+       CHECK(!err);
+
+       return 0;
+}
diff --git a/examples/pipeline/examples/l2fwd.cli 
b/examples/pipeline/examples/l2fwd.cli
new file mode 100644
index 000000000..15f8b1782
--- /dev/null
+++ b/examples/pipeline/examples/l2fwd.cli
@@ -0,0 +1,25 @@
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2010-2020 Intel Corporation
+
+mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
+
+link LINK0 dev 0000:18:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
+link LINK1 dev 0000:18:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
+link LINK2 dev 0000:3b:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
+link LINK3 dev 0000:3b:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on
+
+pipeline PIPELINE0 create 0
+
+pipeline PIPELINE0 port in 0 link LINK0 rxq 0 bsz 32
+pipeline PIPELINE0 port in 1 link LINK1 rxq 0 bsz 32
+pipeline PIPELINE0 port in 2 link LINK2 rxq 0 bsz 32
+pipeline PIPELINE0 port in 3 link LINK3 rxq 0 bsz 32
+
+pipeline PIPELINE0 port out 0 link LINK0 txq 0 bsz 32
+pipeline PIPELINE0 port out 1 link LINK1 txq 0 bsz 32
+pipeline PIPELINE0 port out 2 link LINK2 txq 0 bsz 32
+pipeline PIPELINE0 port out 3 link LINK3 txq 0 bsz 32
+
+pipeline PIPELINE0 build l2fwd
+
+thread 1 pipeline PIPELINE0 enable
diff --git a/examples/pipeline/examples/l2fwd_pcap.cli 
b/examples/pipeline/examples/l2fwd_pcap.cli
new file mode 100644
index 000000000..f9c37ab7e
--- /dev/null
+++ b/examples/pipeline/examples/l2fwd_pcap.cli
@@ -0,0 +1,20 @@
+; SPDX-License-Identifier: BSD-3-Clause
+; Copyright(c) 2010-2020 Intel Corporation
+
+mempool MEMPOOL0 buffer 2304 pool 32K cache 256 cpu 0
+
+pipeline PIPELINE0 create 0
+
+pipeline PIPELINE0 port in 0 source MEMPOOL0 ./examples/packet.pcap
+pipeline PIPELINE0 port in 1 source MEMPOOL0 ./examples/packet.pcap
+pipeline PIPELINE0 port in 2 source MEMPOOL0 ./examples/packet.pcap
+pipeline PIPELINE0 port in 3 source MEMPOOL0 ./examples/packet.pcap
+
+pipeline PIPELINE0 port out 0 sink none
+pipeline PIPELINE0 port out 1 sink none
+pipeline PIPELINE0 port out 2 sink none
+pipeline PIPELINE0 port out 3 sink none
+
+pipeline PIPELINE0 build l2fwd
+
+thread 1 pipeline PIPELINE0 enable
diff --git a/examples/pipeline/examples/packet.txt 
b/examples/pipeline/examples/packet.txt
new file mode 100644
index 000000000..d1c79b7e7
--- /dev/null
+++ b/examples/pipeline/examples/packet.txt
@@ -0,0 +1,102 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2020 Intel Corporation
+#
+
+#Text to PCAP: text2pcap packet.txt packet.pcap
+#PCAP to text: tcpdump -r packet.pcap -xx
+
+#Packet 0
+000000 aa bb cc dd 00 00 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 1
+000000 aa bb cc dd 00 01 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 2
+000000 aa bb cc dd 00 02 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 3
+000000 aa bb cc dd 00 03 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 4
+000000 aa bb cc dd 00 04 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 5
+000000 aa bb cc dd 00 05 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 6
+000000 aa bb cc dd 00 06 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 7
+000000 aa bb cc dd 00 07 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 8
+000000 aa bb cc dd 00 08 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 9
+000000 aa bb cc dd 00 09 b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 10
+000000 aa bb cc dd 00 0a b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 11
+000000 aa bb cc dd 00 0b b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 12
+000000 aa bb cc dd 00 0c b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 13
+000000 aa bb cc dd 00 0d b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 14
+000000 aa bb cc dd 00 0e b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
+
+#Packet 15
+000000 aa bb cc dd 00 0f b0 b1 b2 b3 b4 b5 08 00 45 00
+000010 00 2e 00 00 00 00 40 11 00 00 c0 c1 c2 c3 d0 d1
+000020 d2 d3 e0 e1 f0 f1 00 1a 00 00 00 01 02 03 04 05
+000030 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11
diff --git a/examples/pipeline/meson.build b/examples/pipeline/meson.build
index 4f47dec3e..b16de3714 100644
--- a/examples/pipeline/meson.build
+++ b/examples/pipeline/meson.build
@@ -15,4 +15,5 @@ sources = files(
        'main.c',
        'obj.c',
        'thread.c',
+       'example_l2fwd.c',
 )
-- 
2.17.1

Reply via email to