[dpdk-dev] dpdk/vpp and cross-version migration for vhost

2016-11-16 Thread Maxime Coquelin
Hi Michael,

On 10/13/2016 07:50 PM, Michael S. Tsirkin wrote:
> Hi!
> So it looks like we face a problem with cross-version
> migration when using vhost. It's not new but became more
> acute with the advent of vhost user.
>
> For users to be able to migrate between different versions
> of the hypervisor the interface exposed to guests
> by hypervisor must stay unchanged.
>
> The problem is that a qemu device is connected
> to a backend in another process, so the interface
> exposed to guests depends on the capabilities of that
> process.
>
> Specifically, for vhost user interface based on virtio, this includes
> the "host features" bitmap that defines the interface, as well as more
> host values such as the max ring size.  Adding new features/changing
> values to this interface is required to make progress, but on the other
> hand we need ability to get the old host features to be compatible.
>
> To solve this problem within qemu, qemu has a versioning system based on
> a machine type concept which fundamentally is a version string, by
> specifying that string one can get hardware compatible with a previous
> qemu version. QEMU also reports the latest version and list of versions
> supported so libvirt records the version at VM creation and then is
> careful to use this machine version whenever it migrates a VM.
>
> One might wonder how is this solved with a kernel vhost backend. The
> answer is that it mostly isn't - instead an assumption is made, that
> qemu versions are deployed together with the kernel - this is generally
> true for downstreams.  Thus whenever qemu gains a new feature, it is
> already supported by the kernel as well.  However, if one attempts
> migration with a new qemu from a system with a new to old kernel, one
> would get a failure.
>
> In the world where we have multiple userspace backends, with some of
> these supplied by ISVs, this seems non-realistic.
>
> IMO we need to support vhost backend versioning, ideally
> in a way that will also work for vhost kernel backends.
>
> So I'd like to get some input from both backend and management
> developers on what a good solution would look like.
>
> If we want to emulate the qemu solution, this involves adding the
> concept of interface versions to dpdk.  For example, dpdk could supply a
> file (or utility printing?) with list of versions: latest and versions
> supported. libvirt could read that and

So if I understand correctly, it would be generated at build time?
One problem I see is that the DPDK's vhost-user lib API provides a way
to disable features:
"
rte_vhost_feature_disable/rte_vhost_feature_enable(feature_mask)

This function disables/enables some features. For example, it can be 
used to disable mergeable buffers and TSO features, which both are 
enabled by default.
"

I think we should not have this capability on host side, it should be
guest's decision to use or not some features, and if it has to be done
on host, QEMU already provides a way to disable features (moreover
per-device, which is not the case with rte_vhost_feature_disable).
IMHO, we should consider deprecating this API in v17.02.

That said, the API is here, and it would break migration if the version
file advertises some features the vSwitch has disabled at runtime.

> - store latest version at vm creation
> - pass it around with the vm
> - pass it to qemu
> From here, qemu could pass this over the vhost-user channel,
> thus making sure it's initialized with the correct
> compatible interface.

Using vhost-user protocol features I guess?

> As version here is an opaque string for libvirt and qemu,
> anything can be used - but I suggest either a list
> of values defining the interface, e.g.
> any_layout=on,max_ring=256
> or a version including the name and vendor of the backend,
> e.g. "org.dpdk.v4.5.6".

I think the first option provides more flexibility.
For example, we could imagine migrating from a process using DPDK's
vhost-user lib, to another process using its own implementation (VPP
has its own implementation currently if I'm not mistaken).
Maybe this scenario does not make sense, but in this case, exposing
values directly would avoid the need for synchronization between
vhost-user implementations.

>
> Note that typically the list of supported versions can only be
> extended, not shrunk. Also, if the host/guest interface
> does not change, don't change the current version as
> this just creates work for everyone.
>
> Thoughts? Would this work well for management? dpdk? vpp?

One thing I'm not clear is how it will work for the MTU feature, if the
process it is migrated to exposes a larger MTU that the guest doesn't
support (if it has sized receive buffers to pre-migration MTU for
example).

Thanks,
Maxime


[dpdk-dev] [PATCH 7/7] examples/eventdev_pipeline: adding example

2016-11-16 Thread Harry van Haaren
This patch adds a sample app to the examples/ directory, which can be used
as a reference application and for general testing. The application requires
two ethdev ports and expects traffic to be flowing. The application must be
run with the --vdev flags as follows to indicate to EAL that a virtual
eventdev device called "evdev_sw0" is available to be used:

./build/eventdev_pipeline --vdev evdev_sw0

The general flow of the traffic is as follows:

Rx core -> Atomic Queue => 4 worker cores => TX core

A scheduler core is required to do the packet scheduling, making this
configuration require 7 cores (Rx, Tx, Scheduler, and 4 workers). Finally
a master core brings the core count to 8 for this configuration. The
application can be configured for various numbers of flows and worker
cores. Run the application with -h for details.

Signed-off-by: Gage Eads 
Signed-off-by: Bruce Richardson 
Signed-off-by: Harry van Haaren 
---
 examples/eventdev_pipeline/Makefile |  49 +++
 examples/eventdev_pipeline/main.c   | 718 
 2 files changed, 767 insertions(+)
 create mode 100644 examples/eventdev_pipeline/Makefile
 create mode 100644 examples/eventdev_pipeline/main.c

diff --git a/examples/eventdev_pipeline/Makefile 
b/examples/eventdev_pipeline/Makefile
new file mode 100644
index 000..bab8916
--- /dev/null
+++ b/examples/eventdev_pipeline/Makefile
@@ -0,0 +1,49 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 Intel Corporation. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+# * Neither the name of Intel Corporation nor the names of its
+#   contributors may be used to endorse or promote products derived
+#   from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ifeq ($(RTE_SDK),)
+$(error "Please define RTE_SDK environment variable")
+endif
+
+# Default target, can be overriden by command line or environment
+RTE_TARGET ?= x86_64-native-linuxapp-gcc
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+# binary name
+APP = eventdev_pipeline
+
+# all source are stored in SRCS-y
+SRCS-y := main.c
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/eventdev_pipeline/main.c 
b/examples/eventdev_pipeline/main.c
new file mode 100644
index 000..6a8052c
--- /dev/null
+++ b/examples/eventdev_pipeline/main.c
@@ -0,0 +1,718 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT

[dpdk-dev] [PATCH 6/7] test/eventdev: unit func makefiles

2016-11-16 Thread Harry van Haaren
Enable the functional and unit tests in the makefile. To run the unit tests,
apply these patches, and run the test app with the following arguments and
choose the unit or functional test to run:
 ./test --vdev evdev_sw0
 RTE>> eventdev_func_autotest
 RTE>> eventdev_unit_autotest

Signed-off-by: Gage Eads 
Signed-off-by: David Hunt 
Signed-off-by: Harry van Haaren 
---
 app/test/Makefile | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..6d43cb7 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -197,6 +197,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += 
test_cryptodev_blockcipher.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev_perf.c
 SRCS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += test_cryptodev.c

+SRCS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += test_eventdev_unit.c
+SRCS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += test_eventdev_func.c
+
 SRCS-$(CONFIG_RTE_LIBRTE_KVARGS) += test_kvargs.c

 CFLAGS += -O3
-- 
2.7.4



[dpdk-dev] [PATCH 5/7] test/eventdev: unit and functional tests

2016-11-16 Thread Harry van Haaren
This commit adds basic unit and functional tests for the eventdev
API. The test code is added in this commit, but not yet enabled until
the next commit.

Signed-off-by: Gage Eads 
Signed-off-by: David Hunt 
Signed-off-by: Harry van Haaren 
---
 app/test/test_eventdev_func.c | 1268 +
 app/test/test_eventdev_unit.c |  557 ++
 2 files changed, 1825 insertions(+)
 create mode 100644 app/test/test_eventdev_func.c
 create mode 100644 app/test/test_eventdev_unit.c

diff --git a/app/test/test_eventdev_func.c b/app/test/test_eventdev_func.c
new file mode 100644
index 000..d7fe481
--- /dev/null
+++ b/app/test/test_eventdev_func.c
@@ -0,0 +1,1268 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include "test.h"
+
+#define MAX_PORTS 16
+#define MAX_QIDS 16
+#define NUM_PACKETS (1<<18)
+
+struct test {
+   struct rte_mempool *mbuf_pool;
+   int ev;
+   int port[MAX_PORTS];
+   int qid[MAX_QIDS];
+   int nb_qids;
+};
+
+static inline struct rte_mbuf *
+rte_gen_arp(int portid, struct rte_mempool *mp)
+{
+   /*
+   * len = 14 + 46
+   * ARP, Request who-has 10.0.0.1 tell 10.0.0.2, length 46
+   */
+   static const uint8_t arp_request[] = {
+   /*0x:*/ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xec, 0xa8,
+   0x6b, 0xfd, 0x02, 0x29, 0x08, 0x06, 0x00, 0x01,
+   /*0x0010:*/ 0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0xec, 0xa8,
+   0x6b, 0xfd, 0x02, 0x29, 0x0a, 0x00, 0x00, 0x01,
+   /*0x0020:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00,
+   0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   /*0x0030:*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00
+   };
+   struct rte_mbuf *m;
+   int pkt_len = sizeof(arp_request) - 1;
+
+   m = rte_pktmbuf_alloc(mp);
+   if (!m)
+   return 0;
+
+   memcpy((void *)((uint64_t)m->buf_addr + m->data_off),
+   arp_request, pkt_len);
+   rte_pktmbuf_pkt_len(m) = pkt_len;
+   rte_pktmbuf_data_len(m) = pkt_len;
+
+   RTE_SET_USED(portid);
+   /*
+* Ignore MAC address for super-simple testing
+* struct ether_addr mac_addr;
+* rte_eth_macaddr_get(portid, _addr);
+* memcpy((void *)((uint64_t)m->buf_addr + m->data_off + 6),
+* _addr, 6);
+*/
+
+   return m;
+}
+
+/* initialization and config */
+static inline int
+init(struct test *t, int nb_queues, int nb_ports)
+{
+   struct rte_event_dev_config config = {
+   .nb_event_queues = nb_queues,
+   .nb_event_ports = nb_ports,
+   };
+   int ret, nevdevs = rte_event_dev_count();
+
+   void *temp = t->mbuf_pool; /* save and restore mbuf pool */
+
+   memset(t, 0, sizeof(*t));
+   t->mbuf_pool = temp;
+
+   if (nevdevs < 1) {
+   printf("%d: No Eventdev Devices Found\n", __LINE__);
+   return -1;
+   }
+
+   const char *eventdev_name = "evdev_sw0";
+
+   t->ev = 

[dpdk-dev] [PATCH 4/7] event/sw: makefiles and config

2016-11-16 Thread Harry van Haaren
This commit modifies the existing Makefiles to have the sw_evdev instance
compiled.  At this point in the patchset, the infrastructure and sw_evdev
pmd is compiled, which means that it can be instantiated and used
successfully.

Signed-off-by: Gage Eads 
Signed-off-by: Bruce Richardson 
Signed-off-by: Harry van Haaren 
---
 config/common_base | 6 ++
 drivers/event/Makefile | 2 ++
 mk/rte.app.mk  | 4 
 3 files changed, 12 insertions(+)

diff --git a/config/common_base b/config/common_base
index a0a07f6..862178a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -417,6 +417,12 @@ CONFIG_RTE_LIBRTE_EVENTDEV=y
 CONFIG_RTE_LIBRTE_EVENTDEV_DEBUG=n

 #
+# Compile a pure sw event device instance
+#
+CONFIG_RTE_LIBRTE_PMD_EVDEV_SW=y
+CONFIG_RTE_LIBRTE_PMD_EVDEV_SW_DEBUG=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
index 93f90eb..b9c37d7 100644
--- a/drivers/event/Makefile
+++ b/drivers/event/Makefile
@@ -31,4 +31,6 @@

 include $(RTE_SDK)/mk/rte.vars.mk

+DIRS-$(CONFIG_RTE_LIBRTE_PMD_EVDEV_SW) += sw
+
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 716725a..2fce863 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -148,6 +148,10 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += 
-lrte_pmd_zuc
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_ZUC) += -L$(LIBSSO_ZUC_PATH)/build 
-lsso_zuc
 endif # CONFIG_RTE_LIBRTE_CRYPTODEV

+ifeq ($(CONFIG_RTE_LIBRTE_EVENTDEV),y)
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_EVDEV_SW)+= -lrte_pmd_evdev_sw
+endif # CONFIG_RTE_LIBRTE_EVENTDEV
+
 endif # !CONFIG_RTE_BUILD_SHARED_LIBS

 _LDLIBS-y += --no-whole-archive
-- 
2.7.4



[dpdk-dev] [PATCH 3/7] event/sw: software eventdev implementation

2016-11-16 Thread Harry van Haaren
This commit adds a software implementation of the eventdev API. The
implementation here is intended to enable the community to use the eventdev
API, and test if the API serves the purpose that it is designed to. It
should be noted this is an RFC implementation, and hence there should be no
performance expectations. Note that the code added here is based on a
prototype implementation, and hence some cleanup is expected to be
necessary.

The main components of the implementation is three files:
  - sw_evdev.c  Creation, configuration, etc
  - sw_evdev_worker.c   Worker cores' enqueue (etc) functions
  - sw_evdev_scheduler.cCore pkt scheduling implementation

This commit only adds the implementation, no existing DPDK files are modified.

Signed-off-by: Gage Eads 
Signed-off-by: Bruce Richardson 
Signed-off-by: Harry van Haaren 
---
 drivers/event/sw/Makefile |  59 +++
 drivers/event/sw/event_ring.h | 142 ++
 drivers/event/sw/iq_ring.h| 160 +++
 drivers/event/sw/rte_pmd_evdev_sw_version.map |   3 +
 drivers/event/sw/sw_evdev.c   | 619 
 drivers/event/sw/sw_evdev.h   | 234 +
 drivers/event/sw/sw_evdev_scheduler.c | 660 ++
 drivers/event/sw/sw_evdev_worker.c| 218 +
 8 files changed, 2095 insertions(+)
 create mode 100644 drivers/event/sw/Makefile
 create mode 100644 drivers/event/sw/event_ring.h
 create mode 100644 drivers/event/sw/iq_ring.h
 create mode 100644 drivers/event/sw/rte_pmd_evdev_sw_version.map
 create mode 100644 drivers/event/sw/sw_evdev.c
 create mode 100644 drivers/event/sw/sw_evdev.h
 create mode 100644 drivers/event/sw/sw_evdev_scheduler.c
 create mode 100644 drivers/event/sw/sw_evdev_worker.c

diff --git a/drivers/event/sw/Makefile b/drivers/event/sw/Makefile
new file mode 100644
index 000..7fc4371
--- /dev/null
+++ b/drivers/event/sw/Makefile
@@ -0,0 +1,59 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 Intel Corporation. All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+# * Neither the name of Intel Corporation nor the names of its
+#   contributors may be used to endorse or promote products derived
+#   from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+
+# library name
+LIB = librte_pmd_evdev_sw.a
+
+# build flags
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+# library version
+LIBABIVER := 1
+
+# versioning export map
+EXPORT_MAP := rte_pmd_evdev_sw_version.map
+
+# library source files
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_EVDEV_SW) += sw_evdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_EVDEV_SW) += sw_evdev_worker.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_EVDEV_SW) += sw_evdev_scheduler.c
+
+# export include files
+SYMLINK-y-include +=
+
+# library dependencies
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_EVDEV_SW) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_EVDEV_SW) += lib/librte_eventdev
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/event/sw/event_ring.h b/drivers/event/sw/event_ring.h
new file mode 100644
index 000..531fb68
--- /dev/null
+++ b/drivers/event/sw/event_ring.h
@@ -0,0 +1,142 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must 

[dpdk-dev] [PATCH 2/7] eventdev: makefiles

2016-11-16 Thread Harry van Haaren
Makefiles that compile the previously committed eventdev header and
infrastructure files.  This commit changes the Makefiles and config/base
to add the config options of building the eventdev.

Signed-off-by: Gage Eads 
Signed-off-by: Bruce Richardson 
Signed-off-by: Harry van Haaren 
---
 config/common_base   |  6 
 drivers/Makefile |  1 +
 drivers/event/Makefile   | 34 
 lib/Makefile |  1 +
 lib/librte_eal/common/include/rte_vdev.h |  1 +
 lib/librte_eventdev/Makefile | 54 
 mk/rte.app.mk|  1 +
 7 files changed, 98 insertions(+)
 create mode 100644 drivers/event/Makefile
 create mode 100644 lib/librte_eventdev/Makefile

diff --git a/config/common_base b/config/common_base
index 4bff83a..a0a07f6 100644
--- a/config/common_base
+++ b/config/common_base
@@ -411,6 +411,12 @@ CONFIG_RTE_LIBRTE_PMD_ZUC_DEBUG=n
 CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO=y

 #
+# Compile event device library
+#
+CONFIG_RTE_LIBRTE_EVENTDEV=y
+CONFIG_RTE_LIBRTE_EVENTDEV_DEBUG=n
+
+#
 # Compile librte_ring
 #
 CONFIG_RTE_LIBRTE_RING=y
diff --git a/drivers/Makefile b/drivers/Makefile
index 81c03a8..40b8347 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -33,5 +33,6 @@ include $(RTE_SDK)/mk/rte.vars.mk

 DIRS-y += net
 DIRS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += crypto
+DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += event

 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/event/Makefile b/drivers/event/Makefile
new file mode 100644
index 000..93f90eb
--- /dev/null
+++ b/drivers/event/Makefile
@@ -0,0 +1,34 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the following disclaimer in
+#   the documentation and/or other materials provided with the
+#   distribution.
+# * Neither the name of Intel Corporation nor the names of its
+#   contributors may be used to endorse or promote products derived
+#   from this software without specific prior written permission.
+#
+#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/lib/Makefile b/lib/Makefile
index 990f23a..75b9868 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -58,6 +58,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_TABLE) += librte_table
 DIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += librte_pipeline
 DIRS-$(CONFIG_RTE_LIBRTE_REORDER) += librte_reorder
 DIRS-$(CONFIG_RTE_LIBRTE_PDUMP) += librte_pdump
+DIRS-$(CONFIG_RTE_LIBRTE_EVENTDEV) += librte_eventdev

 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 DIRS-$(CONFIG_RTE_LIBRTE_KNI) += librte_kni
diff --git a/lib/librte_eal/common/include/rte_vdev.h 
b/lib/librte_eal/common/include/rte_vdev.h
index 784e837..22c1e19 100644
--- a/lib/librte_eal/common/include/rte_vdev.h
+++ b/lib/librte_eal/common/include/rte_vdev.h
@@ -38,6 +38,7 @@ extern "C" {
 #endif

 #include 
+#include 
 #include 

 /** Double linked list of virtual device drivers. */
diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
new file mode 100644
index 000..5e2c467
--- /dev/null
+++ b/lib/librte_eventdev/Makefile
@@ -0,0 +1,54 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2016 Intel Corporation. All rights reserved.
+#   All rights reserved.
+#
+#   Redistribution and use in source and binary forms, with or without
+#   modification, are permitted provided that the following conditions
+#   are met:
+#
+# * Redistributions of source code must retain the above copyright
+#   notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+#   notice, this list of conditions and the 

[dpdk-dev] [PATCH 1/7] eventdev: header and implementation

2016-11-16 Thread Harry van Haaren
This commit adds the eventdev API header, and the library infrastructure
necessary to work with an eventdev instance.  The header is mostly the same
as discussed on the mailing list, in particular see the libeventdev RFC
thread[1].  A second thread[2] gathered input from the community, which
resulted in various modifications to the header.

Since then, some modifications have been made that were discovered during
the implementation of the software implementation of an eventdev. These
changes are present in this header as suggestions, and feedback on these
changes is welcomed. Some of the main items are:
   - A statistics API, similar to rte_ethdev_stats_get()
   - A dump API, similar to rte_ring_dump()
   - Return value of rte_eventdev_enqueue() changed for dequeue consistency
   - rte_event has implementation/operation field as discussed[3]
   - Add enqueue types using operation[4]

This commit does not change any existing DPDK code - only adds the eventdev
header and infrastructure.

Signed-off-by: Gage Eads 
Signed-off-by: Bruce Richardson 
Signed-off-by: Harry van Haaren 

[1] http://dpdk.org/ml/archives/dev/2016-August/045181.html
[2] http://dpdk.org/ml/archives/dev/2016-October/048196.html
[3] http://dpdk.org/ml/archives/dev/2016-October/049459.html
[4] http://dpdk.org/ml/archives/dev/2016-October/049641.html
---
 lib/librte_eventdev/rte_eventdev.c   |  466 ++
 lib/librte_eventdev/rte_eventdev.h   | 1272 ++
 lib/librte_eventdev/rte_eventdev_ops.h   |  177 
 lib/librte_eventdev/rte_eventdev_pmd.h   |   69 ++
 lib/librte_eventdev/rte_eventdev_version.map |   33 +
 5 files changed, 2017 insertions(+)
 create mode 100644 lib/librte_eventdev/rte_eventdev.c
 create mode 100644 lib/librte_eventdev/rte_eventdev.h
 create mode 100644 lib/librte_eventdev/rte_eventdev_ops.h
 create mode 100644 lib/librte_eventdev/rte_eventdev_pmd.h
 create mode 100644 lib/librte_eventdev/rte_eventdev_version.map

diff --git a/lib/librte_eventdev/rte_eventdev.c 
b/lib/librte_eventdev/rte_eventdev.c
new file mode 100644
index 000..aace5ca
--- /dev/null
+++ b/lib/librte_eventdev/rte_eventdev.c
@@ -0,0 +1,466 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2016 Intel Corporation. All rights reserved.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+#include "rte_eventdev.h"
+#include "rte_eventdev_pmd.h"
+#include "rte_eventdev_ops.h"
+
+#define RTE_MAX_EVENT_DEVS 32
+struct rte_event_dev *event_devs[RTE_MAX_EVENT_DEVS];
+static int rte_num_event_dev_pmds;
+
+TAILQ_HEAD(rte_eventdev_list, rte_event_dev);
+
+static struct rte_tailq_elem rte_eventdev_tailq = {
+   .name = "EVENT_DEVS",
+};
+EAL_REGISTER_TAILQ(rte_eventdev_tailq)
+
+#ifdef RTE_LIBRTE_EVENTDEV_DEBUG
+#define RTE_PMD_DEBUG_TRACE(...) \
+   rte_pmd_debug_trace(__func__, __VA_ARGS__)
+#else
+#define RTE_PMD_DEBUG_TRACE(...)
+#endif
+
+
+int
+rte_event_dev_register(struct rte_event_dev *new_dev)
+{
+   uint8_t index = rte_num_event_dev_pmds;
+   struct rte_eventdev_list *list;
+
+   list = RTE_TAILQ_CAST(rte_eventdev_tailq.head, rte_eventdev_list);
+
+   /* The primary process is responsible for adding the eventdevs to the
+* tailQ, and the secondary processes simply look up the eventdev in
+* the list and add it to their local array for fast access.
+*/
+   

[dpdk-dev] [RFC PATCH 0/7] RFC: EventDev Software PMD

2016-11-16 Thread Harry van Haaren
This series of RFC patches implements the libeventdev API and a software
eventdev PMD.

The implementation here is intended to enable the community to use the
eventdev API, specifically to test if the API serves the purpose that it is
designed to. It should be noted this is an RFC implementation, and hence
there should be no performance expectations.

An RFC for the eventdev was sent in August[1] by Jerin Jacob of Cavium,
which introduced the core concepts of the eventdev to the community. Since
then there has been extensive discussion[2] on the mailing list, which had
led to various modifications to the initial proposed API.

The API as presented in the first patch contains a number of changes that
have not yet been discussed. These changes were noticed during the
implementation of the software eventdev PMD, and were added to the API to
enable completion of the PMD. These modifications include a statistics API
and a dump API. For more details, please refer to the commit message of the
patch itself.

The functionality provided by each of the patches is as follows:
  1: Add eventdev API and library infrastructure
  2: Enable compilation of library
  3: Add software eventdev PMD
  4: Enable compilation of PMD
  5: Add test code
  6: Enable test code compilation
  7: Sample application demonstrating basic usage

This breakdown of the patchset hopefully enables the community to experiment
with the eventdev API, and allows us all to gain first-hand experience in
using the eventdev API.  Note also that this patchset has not passed
checkpatch testing just yet - will fix for v2 :)

As next steps I see value in discussing the proposed changes included in
this version of the header file, while welcoming feedback from the community
on the API in general too.

Signed-off-by: Harry van Haaren 

[1] http://dpdk.org/ml/archives/dev/2016-August/045181.html
[2] http://dpdk.org/ml/archives/dev/2016-October/thread.html#48196

Harry van Haaren (7):
  eventdev: header and implementation
  eventdev: makefiles
  event/sw: software eventdev implementation
  event/sw: makefiles and config
  test/eventdev: unit and functional tests
  test/eventdev: unit func makefiles
  examples/eventdev_pipeline: adding example

 app/test/Makefile |3 +
 app/test/test_eventdev_func.c | 1272 
 app/test/test_eventdev_unit.c |  557 +++
 config/common_base|   12 +
 drivers/Makefile  |1 +
 drivers/event/Makefile|   36 +
 drivers/event/sw/Makefile |   59 ++
 drivers/event/sw/event_ring.h |  142 +++
 drivers/event/sw/iq_ring.h|  160 +++
 drivers/event/sw/rte_pmd_evdev_sw_version.map |3 +
 drivers/event/sw/sw_evdev.c   |  619 
 drivers/event/sw/sw_evdev.h   |  234 +
 drivers/event/sw/sw_evdev_scheduler.c |  660 +
 drivers/event/sw/sw_evdev_worker.c|  218 +
 examples/eventdev_pipeline/Makefile   |   49 +
 examples/eventdev_pipeline/main.c |  717 ++
 lib/Makefile  |1 +
 lib/librte_eal/common/include/rte_vdev.h  |1 +
 lib/librte_eventdev/Makefile  |   54 ++
 lib/librte_eventdev/rte_eventdev.c|  466 +
 lib/librte_eventdev/rte_eventdev.h| 1289 +
 lib/librte_eventdev/rte_eventdev_ops.h|  177 
 lib/librte_eventdev/rte_eventdev_pmd.h|   69 ++
 lib/librte_eventdev/rte_eventdev_version.map  |   33 +
 mk/rte.app.mk |5 +
 25 files changed, 6837 insertions(+)
 create mode 100644 app/test/test_eventdev_func.c
 create mode 100644 app/test/test_eventdev_unit.c
 create mode 100644 drivers/event/Makefile
 create mode 100644 drivers/event/sw/Makefile
 create mode 100644 drivers/event/sw/event_ring.h
 create mode 100644 drivers/event/sw/iq_ring.h
 create mode 100644 drivers/event/sw/rte_pmd_evdev_sw_version.map
 create mode 100644 drivers/event/sw/sw_evdev.c
 create mode 100644 drivers/event/sw/sw_evdev.h
 create mode 100644 drivers/event/sw/sw_evdev_scheduler.c
 create mode 100644 drivers/event/sw/sw_evdev_worker.c
 create mode 100644 examples/eventdev_pipeline/Makefile
 create mode 100644 examples/eventdev_pipeline/main.c
 create mode 100644 lib/librte_eventdev/Makefile
 create mode 100644 lib/librte_eventdev/rte_eventdev.c
 create mode 100644 lib/librte_eventdev/rte_eventdev.h
 create mode 100644 lib/librte_eventdev/rte_eventdev_ops.h
 create mode 100644 lib/librte_eventdev/rte_eventdev_pmd.h
 create mode 100644 lib/librte_eventdev/rte_eventdev_version.map

-- 
2.7.4



[dpdk-dev] [PATCH 22/22] app/testpmd: add queue actions to flow command

2016-11-16 Thread Adrien Mazarguil
- QUEUE: assign packets to a given queue index.
- DUP: duplicate packets to a given queue index.
- RSS: spread packets among several queues.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 152 +++
 1 file changed, 152 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index e166045..70e2b76 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -157,8 +157,15 @@ enum index {
ACTION_MARK,
ACTION_MARK_ID,
ACTION_FLAG,
+   ACTION_QUEUE,
+   ACTION_QUEUE_INDEX,
ACTION_DROP,
ACTION_COUNT,
+   ACTION_DUP,
+   ACTION_DUP_INDEX,
+   ACTION_RSS,
+   ACTION_RSS_QUEUES,
+   ACTION_RSS_QUEUE,
ACTION_PF,
ACTION_VF,
ACTION_VF_ORIGINAL,
@@ -172,6 +179,14 @@ enum index {
 #define ITEM_RAW_SIZE \
(offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE)

+/** Number of queue[] entries in struct rte_flow_action_rss. */
+#define ACTION_RSS_NUM 32
+
+/** Storage size for struct rte_flow_action_rss including queues. */
+#define ACTION_RSS_SIZE \
+   (offsetof(struct rte_flow_action_rss, queue) + \
+sizeof(*((struct rte_flow_action_rss *)0)->queue) * ACTION_RSS_NUM)
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16

@@ -489,8 +504,11 @@ static const enum index next_action[] = {
ACTION_PASSTHRU,
ACTION_MARK,
ACTION_FLAG,
+   ACTION_QUEUE,
ACTION_DROP,
ACTION_COUNT,
+   ACTION_DUP,
+   ACTION_RSS,
ACTION_PF,
ACTION_VF,
0,
@@ -502,6 +520,24 @@ static const enum index action_mark[] = {
0,
 };

+static const enum index action_queue[] = {
+   ACTION_QUEUE_INDEX,
+   ACTION_NEXT,
+   0,
+};
+
+static const enum index action_dup[] = {
+   ACTION_DUP_INDEX,
+   ACTION_NEXT,
+   0,
+};
+
+static const enum index action_rss[] = {
+   ACTION_RSS_QUEUES,
+   ACTION_NEXT,
+   0,
+};
+
 static const enum index action_vf[] = {
ACTION_VF_ORIGINAL,
ACTION_VF_ID,
@@ -519,6 +555,9 @@ static int parse_vc_spec(struct context *, const struct 
token *,
 const char *, unsigned int, void *, unsigned int);
 static int parse_vc_conf(struct context *, const struct token *,
 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_action_rss_queue(struct context *, const struct token *,
+const char *, unsigned int, void *,
+unsigned int);
 static int parse_destroy(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -568,6 +607,8 @@ static int comp_port(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_rule_id(struct context *, const struct token *,
unsigned int, char *, unsigned int);
+static int comp_vc_action_rss_queue(struct context *, const struct token *,
+   unsigned int, char *, unsigned int);

 /** Token definitions. */
 static const struct token token_list[] = {
@@ -1169,6 +1210,21 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+   [ACTION_QUEUE] = {
+   .name = "queue",
+   .help = "assign packets to a given queue index",
+   .priv = PRIV_ACTION(QUEUE,
+   sizeof(struct rte_flow_action_queue)),
+   .next = NEXT(action_queue),
+   .call = parse_vc,
+   },
+   [ACTION_QUEUE_INDEX] = {
+   .name = "index",
+   .help = "queue index to use",
+   .next = NEXT(action_queue, NEXT_ENTRY(UNSIGNED)),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_action_queue, index)),
+   .call = parse_vc_conf,
+   },
[ACTION_DROP] = {
.name = "drop",
.help = "drop packets (note: passthru has priority)",
@@ -1183,6 +1239,39 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+   [ACTION_DUP] = {
+   .name = "dup",
+   .help = "duplicate packets to a given queue index",
+   .priv = PRIV_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
+   .next = NEXT(action_dup),
+   .call = parse_vc,
+   },
+   [ACTION_DUP_INDEX] = {
+   .name = "index",
+   .help = "queue index to duplicate packets to",
+   .next = NEXT(action_dup, NEXT_ENTRY(UNSIGNED)),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_action_dup, index)),
+  

[dpdk-dev] [PATCH 21/22] app/testpmd: add various actions to flow command

2016-11-16 Thread Adrien Mazarguil
- MARK: attach 32 bit value to packets.
- FLAG: flag packets.
- DROP: drop packets.
- COUNT: enable counters for a rule.
- PF: redirect packets to physical device function.
- VF: redirect packets to virtual device function.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 121 +++
 1 file changed, 121 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 892f300..e166045 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -154,6 +154,15 @@ enum index {
ACTION_END,
ACTION_VOID,
ACTION_PASSTHRU,
+   ACTION_MARK,
+   ACTION_MARK_ID,
+   ACTION_FLAG,
+   ACTION_DROP,
+   ACTION_COUNT,
+   ACTION_PF,
+   ACTION_VF,
+   ACTION_VF_ORIGINAL,
+   ACTION_VF_ID,
 };

 /** Size of pattern[] field in struct rte_flow_item_raw. */
@@ -478,6 +487,25 @@ static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
ACTION_PASSTHRU,
+   ACTION_MARK,
+   ACTION_FLAG,
+   ACTION_DROP,
+   ACTION_COUNT,
+   ACTION_PF,
+   ACTION_VF,
+   0,
+};
+
+static const enum index action_mark[] = {
+   ACTION_MARK_ID,
+   ACTION_NEXT,
+   0,
+};
+
+static const enum index action_vf[] = {
+   ACTION_VF_ORIGINAL,
+   ACTION_VF_ID,
+   ACTION_NEXT,
0,
 };

@@ -489,6 +517,8 @@ static int parse_vc(struct context *, const struct token *,
void *, unsigned int);
 static int parse_vc_spec(struct context *, const struct token *,
 const char *, unsigned int, void *, unsigned int);
+static int parse_vc_conf(struct context *, const struct token *,
+const char *, unsigned int, void *, unsigned int);
 static int parse_destroy(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -1118,6 +1148,70 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
.call = parse_vc,
},
+   [ACTION_MARK] = {
+   .name = "mark",
+   .help = "attach 32 bit value to packets",
+   .priv = PRIV_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
+   .next = NEXT(action_mark),
+   .call = parse_vc,
+   },
+   [ACTION_MARK_ID] = {
+   .name = "id",
+   .help = "32 bit value to return with packets",
+   .next = NEXT(action_mark, NEXT_ENTRY(UNSIGNED)),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_action_mark, id)),
+   .call = parse_vc_conf,
+   },
+   [ACTION_FLAG] = {
+   .name = "flag",
+   .help = "flag packets",
+   .priv = PRIV_ACTION(FLAG, 0),
+   .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+   .call = parse_vc,
+   },
+   [ACTION_DROP] = {
+   .name = "drop",
+   .help = "drop packets (note: passthru has priority)",
+   .priv = PRIV_ACTION(DROP, 0),
+   .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+   .call = parse_vc,
+   },
+   [ACTION_COUNT] = {
+   .name = "count",
+   .help = "enable counters for this rule",
+   .priv = PRIV_ACTION(COUNT, 0),
+   .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+   .call = parse_vc,
+   },
+   [ACTION_PF] = {
+   .name = "pf",
+   .help = "redirect packets to physical device function",
+   .priv = PRIV_ACTION(PF, 0),
+   .next = NEXT(NEXT_ENTRY(ACTION_NEXT)),
+   .call = parse_vc,
+   },
+   [ACTION_VF] = {
+   .name = "vf",
+   .help = "redirect packets to virtual device function",
+   .priv = PRIV_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+   .next = NEXT(action_vf),
+   .call = parse_vc,
+   },
+   [ACTION_VF_ORIGINAL] = {
+   .name = "original",
+   .help = "use original VF ID if possible",
+   .next = NEXT(action_vf, NEXT_ENTRY(BOOLEAN)),
+   .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_vf,
+  original)),
+   .call = parse_vc_conf,
+   },
+   [ACTION_VF_ID] = {
+   .name = "id",
+   .help = "VF ID to redirect packets to",
+   .next = NEXT(action_vf, NEXT_ENTRY(UNSIGNED)),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_action_vf, id)),
+   .call = parse_vc_conf,
+   },
 };

 /** Remove and return last entry from argument stack. */
@@ -1441,6 +1535,33 @@ parse_vc_spec(struct context *ctx, const struct token 
*token,
return len;
 }

+/** Parse action configuration field. */
+static int
+parse_vc_conf(struct 

[dpdk-dev] [PATCH 20/22] app/testpmd: add L4 items to flow command

2016-11-16 Thread Adrien Mazarguil
Add the ability to match a few properties of common L4[.5] protocol
headers:

- ICMP: type and code.
- UDP: source and destination ports.
- TCP: source and destination ports.
- SCTP: source and destination ports.
- VXLAN: network identifier.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 163 +++
 1 file changed, 163 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 75096df..892f300 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -133,6 +133,20 @@ enum index {
ITEM_IPV6,
ITEM_IPV6_SRC,
ITEM_IPV6_DST,
+   ITEM_ICMP,
+   ITEM_ICMP_TYPE,
+   ITEM_ICMP_CODE,
+   ITEM_UDP,
+   ITEM_UDP_SRC,
+   ITEM_UDP_DST,
+   ITEM_TCP,
+   ITEM_TCP_SRC,
+   ITEM_TCP_DST,
+   ITEM_SCTP,
+   ITEM_SCTP_SRC,
+   ITEM_SCTP_DST,
+   ITEM_VXLAN,
+   ITEM_VXLAN_VNI,

/* Validate/create actions. */
ACTIONS,
@@ -360,6 +374,11 @@ static const enum index next_item[] = {
ITEM_VLAN,
ITEM_IPV4,
ITEM_IPV6,
+   ITEM_ICMP,
+   ITEM_UDP,
+   ITEM_TCP,
+   ITEM_SCTP,
+   ITEM_VXLAN,
0,
 };

@@ -421,6 +440,40 @@ static const enum index item_ipv6[] = {
0,
 };

+static const enum index item_icmp[] = {
+   ITEM_ICMP_TYPE,
+   ITEM_ICMP_CODE,
+   ITEM_NEXT,
+   0,
+};
+
+static const enum index item_udp[] = {
+   ITEM_UDP_SRC,
+   ITEM_UDP_DST,
+   ITEM_NEXT,
+   0,
+};
+
+static const enum index item_tcp[] = {
+   ITEM_TCP_SRC,
+   ITEM_TCP_DST,
+   ITEM_NEXT,
+   0,
+};
+
+static const enum index item_sctp[] = {
+   ITEM_SCTP_SRC,
+   ITEM_SCTP_DST,
+   ITEM_NEXT,
+   0,
+};
+
+static const enum index item_vxlan[] = {
+   ITEM_VXLAN_VNI,
+   ITEM_NEXT,
+   0,
+};
+
 static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -936,6 +989,103 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
 hdr.dst_addr)),
},
+   [ITEM_ICMP] = {
+   .name = "icmp",
+   .help = "match ICMP header",
+   .priv = PRIV_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
+   .next = NEXT(item_icmp),
+   .call = parse_vc,
+   },
+   [ITEM_ICMP_TYPE] = {
+   .name = "type",
+   .help = "ICMP packet type",
+   .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
+hdr.icmp_type)),
+   },
+   [ITEM_ICMP_CODE] = {
+   .name = "code",
+   .help = "ICMP packet code",
+   .next = NEXT(item_icmp, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp,
+hdr.icmp_code)),
+   },
+   [ITEM_UDP] = {
+   .name = "udp",
+   .help = "match UDP header",
+   .priv = PRIV_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
+   .next = NEXT(item_udp),
+   .call = parse_vc,
+   },
+   [ITEM_UDP_SRC] = {
+   .name = "src",
+   .help = "UDP source port",
+   .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
+hdr.src_port)),
+   },
+   [ITEM_UDP_DST] = {
+   .name = "dst",
+   .help = "UDP destination port",
+   .next = NEXT(item_udp, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_udp,
+hdr.dst_port)),
+   },
+   [ITEM_TCP] = {
+   .name = "tcp",
+   .help = "match TCP header",
+   .priv = PRIV_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
+   .next = NEXT(item_tcp),
+   .call = parse_vc,
+   },
+   [ITEM_TCP_SRC] = {
+   .name = "src",
+   .help = "TCP source port",
+   .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
+hdr.src_port)),
+   },
+   [ITEM_TCP_DST] = {
+   .name = "dst",
+   .help = "TCP destination port",
+   .next = NEXT(item_tcp, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_tcp,
+hdr.dst_port)),
+   },
+   [ITEM_SCTP] = {
+   .name = "sctp",
+   .help = 

[dpdk-dev] [PATCH 19/22] app/testpmd: add items ipv4/ipv6 to flow command

2016-11-16 Thread Adrien Mazarguil
Add the ability to match basic fields from IPv4 and IPv6 headers (source
and destination addresses only).

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 177 +++
 1 file changed, 177 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index f2bd405..75096df 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -38,6 +38,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
@@ -61,6 +62,8 @@ enum index {
BOOLEAN,
STRING,
MAC_ADDR,
+   IPV4_ADDR,
+   IPV6_ADDR,
RULE_ID,
PORT_ID,
GROUP_ID,
@@ -124,6 +127,12 @@ enum index {
ITEM_VLAN,
ITEM_VLAN_TPID,
ITEM_VLAN_TCI,
+   ITEM_IPV4,
+   ITEM_IPV4_SRC,
+   ITEM_IPV4_DST,
+   ITEM_IPV6,
+   ITEM_IPV6_SRC,
+   ITEM_IPV6_DST,

/* Validate/create actions. */
ACTIONS,
@@ -349,6 +358,8 @@ static const enum index next_item[] = {
ITEM_RAW,
ITEM_ETH,
ITEM_VLAN,
+   ITEM_IPV4,
+   ITEM_IPV6,
0,
 };

@@ -396,6 +407,20 @@ static const enum index item_vlan[] = {
0,
 };

+static const enum index item_ipv4[] = {
+   ITEM_IPV4_SRC,
+   ITEM_IPV4_DST,
+   ITEM_NEXT,
+   0,
+};
+
+static const enum index item_ipv6[] = {
+   ITEM_IPV6_SRC,
+   ITEM_IPV6_DST,
+   ITEM_NEXT,
+   0,
+};
+
 static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -441,6 +466,12 @@ static int parse_string(struct context *, const struct 
token *,
 static int parse_mac_addr(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
+static int parse_ipv4_addr(struct context *, const struct token *,
+  const char *, unsigned int,
+  void *, unsigned int);
+static int parse_ipv6_addr(struct context *, const struct token *,
+  const char *, unsigned int,
+  void *, unsigned int);
 static int parse_port(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
@@ -511,6 +542,20 @@ static const struct token token_list[] = {
.call = parse_mac_addr,
.comp = comp_none,
},
+   [IPV4_ADDR] = {
+   .name = "{IPv4 address}",
+   .type = "IPV4 ADDRESS",
+   .help = "standard IPv4 address notation",
+   .call = parse_ipv4_addr,
+   .comp = comp_none,
+   },
+   [IPV6_ADDR] = {
+   .name = "{IPv6 address}",
+   .type = "IPV6 ADDRESS",
+   .help = "standard IPv6 address notation",
+   .call = parse_ipv6_addr,
+   .comp = comp_none,
+   },
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@@ -849,6 +894,48 @@ static const struct token token_list[] = {
.next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)),
},
+   [ITEM_IPV4] = {
+   .name = "ipv4",
+   .help = "match IPv4 header",
+   .priv = PRIV_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
+   .next = NEXT(item_ipv4),
+   .call = parse_vc,
+   },
+   [ITEM_IPV4_SRC] = {
+   .name = "src",
+   .help = "source address",
+   .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
+hdr.src_addr)),
+   },
+   [ITEM_IPV4_DST] = {
+   .name = "dst",
+   .help = "destination address",
+   .next = NEXT(item_ipv4, NEXT_ENTRY(IPV4_ADDR), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv4,
+hdr.dst_addr)),
+   },
+   [ITEM_IPV6] = {
+   .name = "ipv6",
+   .help = "match IPv6 header",
+   .priv = PRIV_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
+   .next = NEXT(item_ipv6),
+   .call = parse_vc,
+   },
+   [ITEM_IPV6_SRC] = {
+   .name = "src",
+   .help = "source address",
+   .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6,
+hdr.src_addr)),
+   },
+   [ITEM_IPV6_DST] = {
+   .name = "dst",
+   .help = "destination address",
+   .next = NEXT(item_ipv6, NEXT_ENTRY(IPV6_ADDR), item_param),
+   .args = 

[dpdk-dev] [PATCH 18/22] app/testpmd: add items eth/vlan to flow command

2016-11-16 Thread Adrien Mazarguil
These pattern items match basic Ethernet headers (source, destination and
type) and related 802.1Q/ad VLAN headers.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 126 +++
 1 file changed, 126 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 6f2f26c..f2bd405 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 

 #include "testpmd.h"
@@ -59,6 +60,7 @@ enum index {
PREFIX,
BOOLEAN,
STRING,
+   MAC_ADDR,
RULE_ID,
PORT_ID,
GROUP_ID,
@@ -115,6 +117,13 @@ enum index {
ITEM_RAW_OFFSET,
ITEM_RAW_LIMIT,
ITEM_RAW_PATTERN,
+   ITEM_ETH,
+   ITEM_ETH_DST,
+   ITEM_ETH_SRC,
+   ITEM_ETH_TYPE,
+   ITEM_VLAN,
+   ITEM_VLAN_TPID,
+   ITEM_VLAN_TCI,

/* Validate/create actions. */
ACTIONS,
@@ -239,6 +248,14 @@ struct token {
.size = (sz), \
})

+/** Same as ARGS_ENTRY() using network byte ordering. */
+#define ARGS_ENTRY_HTON(s, f) \
+   (&(const struct arg){ \
+   .hton = 1, \
+   .offset = offsetof(s, f), \
+   .size = sizeof(((s *)0)->f), \
+   })
+
 /** Parser output buffer layout expected by cmd_flow_parsed(). */
 struct buffer {
enum index command; /**< Flow command. */
@@ -330,6 +347,8 @@ static const enum index next_item[] = {
ITEM_VF,
ITEM_PORT,
ITEM_RAW,
+   ITEM_ETH,
+   ITEM_VLAN,
0,
 };

@@ -362,6 +381,21 @@ static const enum index item_raw[] = {
0,
 };

+static const enum index item_eth[] = {
+   ITEM_ETH_DST,
+   ITEM_ETH_SRC,
+   ITEM_ETH_TYPE,
+   ITEM_NEXT,
+   0,
+};
+
+static const enum index item_vlan[] = {
+   ITEM_VLAN_TPID,
+   ITEM_VLAN_TCI,
+   ITEM_NEXT,
+   0,
+};
+
 static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -404,6 +438,9 @@ static int parse_boolean(struct context *, const struct 
token *,
 static int parse_string(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_mac_addr(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
 static int parse_port(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
@@ -467,6 +504,13 @@ static const struct token token_list[] = {
.call = parse_string,
.comp = comp_none,
},
+   [MAC_ADDR] = {
+   .name = "{MAC address}",
+   .type = "MAC-48",
+   .help = "standard MAC address notation",
+   .call = parse_mac_addr,
+   .comp = comp_none,
+   },
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@@ -761,6 +805,50 @@ static const struct token token_list[] = {
pattern,
ITEM_RAW_PATTERN_SIZE)),
},
+   [ITEM_ETH] = {
+   .name = "eth",
+   .help = "match Ethernet header",
+   .priv = PRIV_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
+   .next = NEXT(item_eth),
+   .call = parse_vc,
+   },
+   [ITEM_ETH_DST] = {
+   .name = "dst",
+   .help = "destination MAC",
+   .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_item_eth, dst)),
+   },
+   [ITEM_ETH_SRC] = {
+   .name = "src",
+   .help = "source MAC",
+   .next = NEXT(item_eth, NEXT_ENTRY(MAC_ADDR), item_param),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_item_eth, src)),
+   },
+   [ITEM_ETH_TYPE] = {
+   .name = "type",
+   .help = "EtherType",
+   .next = NEXT(item_eth, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)),
+   },
+   [ITEM_VLAN] = {
+   .name = "vlan",
+   .help = "match 802.1Q/ad VLAN tag",
+   .priv = PRIV_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
+   .next = NEXT(item_vlan),
+   .call = parse_vc,
+   },
+   [ITEM_VLAN_TPID] = {
+   .name = "tpid",
+   .help = "tag protocol identifier",
+   .next = NEXT(item_vlan, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tpid)),
+   },
+   [ITEM_VLAN_TCI] = {
+   .name = "tci",
+   .help = "tag control 

[dpdk-dev] [PATCH 17/22] app/testpmd: add item raw to flow command

2016-11-16 Thread Adrien Mazarguil
Matches arbitrary byte strings with properties:

- relative: look for pattern after the previous item.
- search: search pattern from offset (see also limit).
- offset: absolute or relative offset for pattern.
- limit: search area limit for start of pattern.
- length: pattern length.
- pattern: byte string to look for.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 206 +++
 1 file changed, 206 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index c61e31e..6f2f26c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -57,6 +57,8 @@ enum index {
INTEGER,
UNSIGNED,
PREFIX,
+   BOOLEAN,
+   STRING,
RULE_ID,
PORT_ID,
GROUP_ID,
@@ -107,6 +109,12 @@ enum index {
ITEM_VF_ID,
ITEM_PORT,
ITEM_PORT_INDEX,
+   ITEM_RAW,
+   ITEM_RAW_RELATIVE,
+   ITEM_RAW_SEARCH,
+   ITEM_RAW_OFFSET,
+   ITEM_RAW_LIMIT,
+   ITEM_RAW_PATTERN,

/* Validate/create actions. */
ACTIONS,
@@ -116,6 +124,13 @@ enum index {
ACTION_PASSTHRU,
 };

+/** Size of pattern[] field in struct rte_flow_item_raw. */
+#define ITEM_RAW_PATTERN_SIZE 36
+
+/** Storage size for struct rte_flow_item_raw including pattern. */
+#define ITEM_RAW_SIZE \
+   (offsetof(struct rte_flow_item_raw, pattern) + ITEM_RAW_PATTERN_SIZE)
+
 /** Maximum number of subsequent tokens and arguments on the stack. */
 #define CTX_STACK_SIZE 16

@@ -217,6 +232,13 @@ struct token {
.size = sizeof(*((s *)0)->f), \
})

+/** Static initializer for ARGS() with arbitrary size. */
+#define ARGS_ENTRY_USZ(s, f, sz) \
+   (&(const struct arg){ \
+   .offset = offsetof(s, f), \
+   .size = (sz), \
+   })
+
 /** Parser output buffer layout expected by cmd_flow_parsed(). */
 struct buffer {
enum index command; /**< Flow command. */
@@ -307,6 +329,7 @@ static const enum index next_item[] = {
ITEM_PF,
ITEM_VF,
ITEM_PORT,
+   ITEM_RAW,
0,
 };

@@ -329,6 +352,16 @@ static const enum index item_port[] = {
0,
 };

+static const enum index item_raw[] = {
+   ITEM_RAW_RELATIVE,
+   ITEM_RAW_SEARCH,
+   ITEM_RAW_OFFSET,
+   ITEM_RAW_LIMIT,
+   ITEM_RAW_PATTERN,
+   ITEM_NEXT,
+   0,
+};
+
 static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -365,11 +398,19 @@ static int parse_int(struct context *, const struct token 
*,
 static int parse_prefix(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_boolean(struct context *, const struct token *,
+const char *, unsigned int,
+void *, unsigned int);
+static int parse_string(struct context *, const struct token *,
+   const char *, unsigned int,
+   void *, unsigned int);
 static int parse_port(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
+static int comp_boolean(struct context *, const struct token *,
+   unsigned int, char *, unsigned int);
 static int comp_action(struct context *, const struct token *,
   unsigned int, char *, unsigned int);
 static int comp_port(struct context *, const struct token *,
@@ -412,6 +453,20 @@ static const struct token token_list[] = {
.call = parse_prefix,
.comp = comp_none,
},
+   [BOOLEAN] = {
+   .name = "{boolean}",
+   .type = "BOOLEAN",
+   .help = "any boolean value",
+   .call = parse_boolean,
+   .comp = comp_boolean,
+   },
+   [STRING] = {
+   .name = "{string}",
+   .type = "STRING",
+   .help = "fixed string",
+   .call = parse_string,
+   .comp = comp_none,
+   },
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@@ -662,6 +717,50 @@ static const struct token token_list[] = {
.next = NEXT(item_port, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_port, index)),
},
+   [ITEM_RAW] = {
+   .name = "raw",
+   .help = "match an arbitrary byte string",
+   .priv = PRIV_ITEM(RAW, ITEM_RAW_SIZE),
+   .next = NEXT(item_raw),
+   .call = parse_vc,
+   },
+   [ITEM_RAW_RELATIVE] = {
+   .name = "relative",
+   .help = "look for pattern after the previous item",
+   .next = 

[dpdk-dev] [PATCH 16/22] app/testpmd: add various items to flow command

2016-11-16 Thread Adrien Mazarguil
- PF: match packets addressed to the physical function.
- VF: match packets addressed to a virtual function ID.
- PORT: device-specific physical port index to use.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 53 
 1 file changed, 53 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5816be4..c61e31e 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -102,6 +102,11 @@ enum index {
ITEM_ANY,
ITEM_ANY_MIN,
ITEM_ANY_MAX,
+   ITEM_PF,
+   ITEM_VF,
+   ITEM_VF_ID,
+   ITEM_PORT,
+   ITEM_PORT_INDEX,

/* Validate/create actions. */
ACTIONS,
@@ -299,6 +304,9 @@ static const enum index next_item[] = {
ITEM_VOID,
ITEM_INVERT,
ITEM_ANY,
+   ITEM_PF,
+   ITEM_VF,
+   ITEM_PORT,
0,
 };

@@ -309,6 +317,18 @@ static const enum index item_any[] = {
0,
 };

+static const enum index item_vf[] = {
+   ITEM_VF_ID,
+   ITEM_NEXT,
+   0,
+};
+
+static const enum index item_port[] = {
+   ITEM_PORT_INDEX,
+   ITEM_NEXT,
+   0,
+};
+
 static const enum index next_action[] = {
ACTION_END,
ACTION_VOID,
@@ -609,6 +629,39 @@ static const struct token token_list[] = {
.next = NEXT(item_any, NEXT_ENTRY(UNSIGNED), item_param),
.args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, max)),
},
+   [ITEM_PF] = {
+   .name = "pf",
+   .help = "match packets addressed to the physical function",
+   .priv = PRIV_ITEM(PF, 0),
+   .next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
+   .call = parse_vc,
+   },
+   [ITEM_VF] = {
+   .name = "vf",
+   .help = "match packets addressed to a virtual function ID",
+   .priv = PRIV_ITEM(VF, sizeof(struct rte_flow_item_vf)),
+   .next = NEXT(item_vf),
+   .call = parse_vc,
+   },
+   [ITEM_VF_ID] = {
+   .name = "id",
+   .help = "destination VF ID",
+   .next = NEXT(item_vf, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_item_vf, id)),
+   },
+   [ITEM_PORT] = {
+   .name = "port",
+   .help = "device-specific physical port index to use",
+   .priv = PRIV_ITEM(PORT, sizeof(struct rte_flow_item_port)),
+   .next = NEXT(item_port),
+   .call = parse_vc,
+   },
+   [ITEM_PORT_INDEX] = {
+   .name = "index",
+   .help = "physical port index",
+   .next = NEXT(item_port, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_item_port, index)),
+   },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
-- 
2.1.4



[dpdk-dev] [PATCH 15/22] app/testpmd: add item any to flow command

2016-11-16 Thread Adrien Mazarguil
This pattern item matches any protocol in place of the current layer and
has two properties:

- min: minimum number of layers covered (0 or more).
- max: maximum number of layers covered (0 means infinity).

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 30 ++
 1 file changed, 30 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 81930e1..5816be4 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -99,6 +99,9 @@ enum index {
ITEM_END,
ITEM_VOID,
ITEM_INVERT,
+   ITEM_ANY,
+   ITEM_ANY_MIN,
+   ITEM_ANY_MAX,

/* Validate/create actions. */
ACTIONS,
@@ -295,6 +298,14 @@ static const enum index next_item[] = {
ITEM_END,
ITEM_VOID,
ITEM_INVERT,
+   ITEM_ANY,
+   0,
+};
+
+static const enum index item_any[] = {
+   ITEM_ANY_MIN,
+   ITEM_ANY_MAX,
+   ITEM_NEXT,
0,
 };

@@ -579,6 +590,25 @@ static const struct token token_list[] = {
.next = NEXT(NEXT_ENTRY(ITEM_NEXT)),
.call = parse_vc,
},
+   [ITEM_ANY] = {
+   .name = "any",
+   .help = "match any protocol for the current layer",
+   .priv = PRIV_ITEM(ANY, sizeof(struct rte_flow_item_any)),
+   .next = NEXT(item_any),
+   .call = parse_vc,
+   },
+   [ITEM_ANY_MIN] = {
+   .name = "min",
+   .help = "minimum number of layers covered",
+   .next = NEXT(item_any, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, min)),
+   },
+   [ITEM_ANY_MAX] = {
+   .name = "max",
+   .help = "maximum number of layers covered, 0 for infinity",
+   .next = NEXT(item_any, NEXT_ENTRY(UNSIGNED), item_param),
+   .args = ARGS(ARGS_ENTRY(struct rte_flow_item_any, max)),
+   },
/* Validate/create actions. */
[ACTIONS] = {
.name = "actions",
-- 
2.1.4



[dpdk-dev] [PATCH 14/22] app/testpmd: add rte_flow bit-field support

2016-11-16 Thread Adrien Mazarguil
Several rte_flow structures expose bit-fields that cannot be set in a
generic fashion at byte level. Add bit-mask support to handle them.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 59 
 1 file changed, 59 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 89307cb..81930e1 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -136,6 +136,7 @@ struct arg {
uint32_t sign:1; /**< Value is signed. */
uint32_t offset; /**< Relative offset from ctx->object. */
uint32_t size; /**< Field size. */
+   const uint8_t *mask; /**< Bit-mask to use instead of offset/size. */
 };

 /** Parser token definition. */
@@ -195,6 +196,13 @@ struct token {
.size = sizeof(((s *)0)->f), \
})

+/** Static initializer for ARGS() to target a bit-field. */
+#define ARGS_ENTRY_BF(s, f) \
+   (&(const struct arg){ \
+   .size = sizeof(s), \
+   .mask = (const void *)&(const s){ .f = -1 }, \
+   })
+
 /** Static initializer for ARGS() to target a pointer. */
 #define ARGS_ENTRY_PTR(s, f) \
(&(const struct arg){ \
@@ -622,6 +630,34 @@ push_args(struct context *ctx, const struct arg *arg)
return 0;
 }

+/** Spread value into buffer according to bit-mask. */
+static size_t
+arg_entry_bf_fill(void *dst, uintmax_t val, const struct arg *arg)
+{
+   uint32_t i;
+   size_t len = 0;
+
+   /* Endian conversion is not supported on bit-fields. */
+   if (!arg->mask || arg->hton)
+   return 0;
+   for (i = 0; i != arg->size; ++i) {
+   unsigned int shift = 0;
+   uint8_t *buf = (uint8_t *)dst + i;
+
+   for (shift = 0; arg->mask[i] >> shift; ++shift) {
+   if (!(arg->mask[i] & (1 << shift)))
+   continue;
+   ++len;
+   if (!dst)
+   continue;
+   *buf &= ~(1 << shift);
+   *buf |= (val & 1) << shift;
+   val >>= 1;
+   }
+   }
+   return len;
+}
+
 /**
  * Parse a prefix length and generate a bit-mask.
  *
@@ -648,6 +684,23 @@ parse_prefix(struct context *ctx, const struct token 
*token,
u = strtoumax(str, , 0);
if (errno || (size_t)(end - str) != len)
goto error;
+   if (arg->mask) {
+   uintmax_t v = 0;
+
+   extra = arg_entry_bf_fill(NULL, 0, arg);
+   if (u > extra)
+   goto error;
+   if (!ctx->object)
+   return len;
+   extra -= u;
+   while (u--)
+   (v <<= 1, v |= 1);
+   v <<= extra;
+   if (!arg_entry_bf_fill(ctx->object, v, arg) ||
+   !arg_entry_bf_fill(ctx->objmask, -1, arg))
+   goto error;
+   return len;
+   }
bytes = u / 8;
extra = u % 8;
size = arg->size;
@@ -1071,6 +1124,12 @@ parse_int(struct context *ctx, const struct token *token,
goto error;
if (!ctx->object)
return len;
+   if (arg->mask) {
+   if (!arg_entry_bf_fill(ctx->object, u, arg) ||
+   !arg_entry_bf_fill(ctx->objmask, -1, arg))
+   goto error;
+   return len;
+   }
buf = (uint8_t *)ctx->object + arg->offset;
size = arg->size;
 objmask:
-- 
2.1.4



[dpdk-dev] [PATCH 13/22] app/testpmd: add rte_flow item spec prefix length

2016-11-16 Thread Adrien Mazarguil
Generating bit-masks from prefix lengths is often more convenient than
providing them entirely (e.g. to define IPv4 and IPv6 subnets).

This commit adds the "prefix" operator that assigns generated bit-masks to
any pattern item specification field.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 80 
 1 file changed, 80 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 790b4b8..89307cb 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -56,6 +56,7 @@ enum index {
/* Common tokens. */
INTEGER,
UNSIGNED,
+   PREFIX,
RULE_ID,
PORT_ID,
GROUP_ID,
@@ -93,6 +94,7 @@ enum index {
ITEM_PARAM_SPEC,
ITEM_PARAM_LAST,
ITEM_PARAM_MASK,
+   ITEM_PARAM_PREFIX,
ITEM_NEXT,
ITEM_END,
ITEM_VOID,
@@ -277,6 +279,7 @@ static const enum index item_param[] = {
ITEM_PARAM_SPEC,
ITEM_PARAM_LAST,
ITEM_PARAM_MASK,
+   ITEM_PARAM_PREFIX,
0,
 };

@@ -320,6 +323,9 @@ static int parse_list(struct context *, const struct token 
*,
 static int parse_int(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
+static int parse_prefix(struct context *, const struct token *,
+   const char *, unsigned int,
+   void *, unsigned int);
 static int parse_port(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
@@ -360,6 +366,13 @@ static const struct token token_list[] = {
.call = parse_int,
.comp = comp_none,
},
+   [PREFIX] = {
+   .name = "{prefix}",
+   .type = "PREFIX",
+   .help = "prefix length for bit-mask",
+   .call = parse_prefix,
+   .comp = comp_none,
+   },
[RULE_ID] = {
.name = "{rule id}",
.type = "RULE ID",
@@ -527,6 +540,11 @@ static const struct token token_list[] = {
.help = "specify bit-mask with relevant bits set to one",
.call = parse_vc_spec,
},
+   [ITEM_PARAM_PREFIX] = {
+   .name = "prefix",
+   .help = "generate bit-mask from a prefix length",
+   .call = parse_vc_spec,
+   },
[ITEM_NEXT] = {
.name = "/",
.help = "specify next pattern item",
@@ -604,6 +622,62 @@ push_args(struct context *ctx, const struct arg *arg)
return 0;
 }

+/**
+ * Parse a prefix length and generate a bit-mask.
+ *
+ * Last argument (ctx->args) is retrieved to determine mask size, storage
+ * location and whether the result must use network byte ordering.
+ */
+static int
+parse_prefix(struct context *ctx, const struct token *token,
+const char *str, unsigned int len,
+void *buf, unsigned int size)
+{
+   const struct arg *arg = pop_args(ctx);
+   static const uint8_t conv[] = "\x00\x80\xc0\xe0\xf0\xf8\xfc\xfe\xff";
+   char *end;
+   uintmax_t u;
+   unsigned int bytes;
+   unsigned int extra;
+
+   (void)token;
+   /* Argument is expected. */
+   if (!arg)
+   return -1;
+   errno = 0;
+   u = strtoumax(str, , 0);
+   if (errno || (size_t)(end - str) != len)
+   goto error;
+   bytes = u / 8;
+   extra = u % 8;
+   size = arg->size;
+   if (bytes > size || bytes + !!extra > size)
+   goto error;
+   if (!ctx->object)
+   return len;
+   buf = (uint8_t *)ctx->object + arg->offset;
+#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
+   if (!arg->hton) {
+   memset((uint8_t *)buf + size - bytes, 0xff, bytes);
+   memset(buf, 0x00, size - bytes);
+   if (extra)
+   ((uint8_t *)buf)[size - bytes - 1] = conv[extra];
+   } else
+#endif
+   {
+   memset(buf, 0xff, bytes);
+   memset((uint8_t *)buf + bytes, 0x00, size - bytes);
+   if (extra)
+   ((uint8_t *)buf)[bytes] = conv[extra];
+   }
+   if (ctx->objmask)
+   memset((uint8_t *)ctx->objmask + arg->offset, 0xff, size);
+   return len;
+error:
+   push_args(ctx, arg);
+   return -1;
+}
+
 /** Default parsing function for token name matching. */
 static int
 parse_default(struct context *ctx, const struct token *token,
@@ -775,6 +849,12 @@ parse_vc_spec(struct context *ctx, const struct token 
*token,
case ITEM_PARAM_LAST:
index = 1;
break;
+   case ITEM_PARAM_PREFIX:
+   /* Modify next token to expect a prefix. */
+   if (ctx->next_num < 2)
+   return -1;
+   ctx->next[ctx->next_num 

[dpdk-dev] [PATCH 12/22] app/testpmd: add rte_flow item spec handler

2016-11-16 Thread Adrien Mazarguil
Add parser code to fully set individual fields of pattern item
specification structures, using the following operators:

- fix: sets field and applies full bit-mask for perfect matching.
- spec: sets field without modifying its bit-mask.
- last: sets upper value of the spec => last range.
- mask: sets bit-mask affecting both spec and last from arbitrary value.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 110 +++
 1 file changed, 110 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index e70e8e2..790b4b8 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -89,6 +89,10 @@ enum index {

/* Validate/create pattern. */
PATTERN,
+   ITEM_PARAM_FIX,
+   ITEM_PARAM_SPEC,
+   ITEM_PARAM_LAST,
+   ITEM_PARAM_MASK,
ITEM_NEXT,
ITEM_END,
ITEM_VOID,
@@ -121,6 +125,7 @@ struct context {
uint16_t port; /**< Current port ID (for completions). */
uint32_t objdata; /**< Object-specific data. */
void *object; /**< Address of current object for relative offsets. */
+   void *objmask; /**< Object a full mask must be written to. */
 };

 /** Token argument. */
@@ -267,6 +272,14 @@ static const enum index next_list_attr[] = {
0,
 };

+static const enum index item_param[] = {
+   ITEM_PARAM_FIX,
+   ITEM_PARAM_SPEC,
+   ITEM_PARAM_LAST,
+   ITEM_PARAM_MASK,
+   0,
+};
+
 static const enum index next_item[] = {
ITEM_END,
ITEM_VOID,
@@ -287,6 +300,8 @@ static int parse_init(struct context *, const struct token 
*,
 static int parse_vc(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
+static int parse_vc_spec(struct context *, const struct token *,
+const char *, unsigned int, void *, unsigned int);
 static int parse_destroy(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
@@ -492,6 +507,26 @@ static const struct token token_list[] = {
.next = NEXT(next_item),
.call = parse_vc,
},
+   [ITEM_PARAM_FIX] = {
+   .name = "fix",
+   .help = "match value perfectly (with full bit-mask)",
+   .call = parse_vc_spec,
+   },
+   [ITEM_PARAM_SPEC] = {
+   .name = "spec",
+   .help = "match value according to configured bit-mask",
+   .call = parse_vc_spec,
+   },
+   [ITEM_PARAM_LAST] = {
+   .name = "last",
+   .help = "specify upper bound to establish a range",
+   .call = parse_vc_spec,
+   },
+   [ITEM_PARAM_MASK] = {
+   .name = "mask",
+   .help = "specify bit-mask with relevant bits set to one",
+   .call = parse_vc_spec,
+   },
[ITEM_NEXT] = {
.name = "/",
.help = "specify next pattern item",
@@ -605,6 +640,7 @@ parse_init(struct context *ctx, const struct token *token,
memset((uint8_t *)out + sizeof(*out), 0x22, size - sizeof(*out));
ctx->objdata = 0;
ctx->object = out;
+   ctx->objmask = NULL;
return len;
 }

@@ -632,11 +668,13 @@ parse_vc(struct context *ctx, const struct token *token,
out->command = ctx->curr;
ctx->objdata = 0;
ctx->object = out;
+   ctx->objmask = NULL;
out->args.vc.data = (uint8_t *)out + size;
return len;
}
ctx->objdata = 0;
ctx->object = >args.vc.attr;
+   ctx->objmask = NULL;
switch (ctx->curr) {
case GROUP:
case PRIORITY:
@@ -652,6 +690,7 @@ parse_vc(struct context *ctx, const struct token *token,
(void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
   sizeof(double));
ctx->object = out->args.vc.pattern;
+   ctx->objmask = NULL;
return len;
case ACTIONS:
out->args.vc.actions =
@@ -660,6 +699,7 @@ parse_vc(struct context *ctx, const struct token *token,
out->args.vc.pattern_n),
   sizeof(double));
ctx->object = out->args.vc.actions;
+   ctx->objmask = NULL;
return len;
default:
if (!token->priv)
@@ -682,6 +722,7 @@ parse_vc(struct context *ctx, const struct token *token,
};
++out->args.vc.pattern_n;
ctx->object = item;
+   ctx->objmask = NULL;
} else {
const struct parse_action_priv *priv = token->priv;
struct rte_flow_action *action =
@@ -698,6 +739,7 @@ 

[dpdk-dev] [PATCH 11/22] app/testpmd: add flow query command

2016-11-16 Thread Adrien Mazarguil
Syntax:

 flow query {port_id} {rule_id} {action}

Query a specific action of an existing flow rule.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline.c  |   3 +
 app/test-pmd/cmdline_flow.c | 121 ++-
 2 files changed, 123 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 851cc16..edd1ee3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -831,6 +831,9 @@ static void cmd_help_long_parsed(void *parsed_result,
"flow flush {port_id}\n"
"Destroy all flow rules.\n\n"

+   "flow query {port_id} {rule_id} {action}\n"
+   "Query an existing flow rule.\n\n"
+
"flow list {port_id} [group {group_id}] [...]\n"
"List existing flow rules sorted by priority,"
" filtered by group identifiers.\n\n"
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 1874849..e70e8e2 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -69,11 +69,15 @@ enum index {
CREATE,
DESTROY,
FLUSH,
+   QUERY,
LIST,

/* Destroy arguments. */
DESTROY_RULE,

+   /* Query arguments. */
+   QUERY_ACTION,
+
/* List arguments. */
LIST_GROUP,

@@ -208,6 +212,10 @@ struct buffer {
uint32_t rule_n;
} destroy; /**< Destroy arguments. */
struct {
+   uint32_t rule;
+   enum rte_flow_action_type action;
+   } query; /**< Query arguments. */
+   struct {
uint32_t *group;
uint32_t group_n;
} list; /**< List arguments. */
@@ -285,6 +293,12 @@ static int parse_destroy(struct context *, const struct 
token *,
 static int parse_flush(struct context *, const struct token *,
   const char *, unsigned int,
   void *, unsigned int);
+static int parse_query(struct context *, const struct token *,
+  const char *, unsigned int,
+  void *, unsigned int);
+static int parse_action(struct context *, const struct token *,
+   const char *, unsigned int,
+   void *, unsigned int);
 static int parse_list(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
@@ -296,6 +310,8 @@ static int parse_port(struct context *, const struct token 
*,
  void *, unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
+static int comp_action(struct context *, const struct token *,
+  unsigned int, char *, unsigned int);
 static int comp_port(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_rule_id(struct context *, const struct token *,
@@ -367,7 +383,8 @@ static const struct token token_list[] = {
  CREATE,
  DESTROY,
  FLUSH,
- LIST)),
+ LIST,
+ QUERY)),
.call = parse_init,
},
/* Sub-level commands. */
@@ -399,6 +416,17 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
.call = parse_flush,
},
+   [QUERY] = {
+   .name = "query",
+   .help = "query an existing flow rule",
+   .next = NEXT(NEXT_ENTRY(QUERY_ACTION),
+NEXT_ENTRY(RULE_ID),
+NEXT_ENTRY(PORT_ID)),
+   .args = ARGS(ARGS_ENTRY(struct buffer, args.query.action),
+ARGS_ENTRY(struct buffer, args.query.rule),
+ARGS_ENTRY(struct buffer, port)),
+   .call = parse_query,
+   },
[LIST] = {
.name = "list",
.help = "list existing flow rules",
@@ -414,6 +442,14 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
.call = parse_destroy,
},
+   /* Query arguments. */
+   [QUERY_ACTION] = {
+   .name = "{action}",
+   .type = "ACTION",
+   .help = "action to query, must be part of the rule",
+   .call = parse_action,
+   .comp = comp_action,
+   },
/* List arguments. */
[LIST_GROUP] = {
.name = "group",
@@ -730,6 +766,67 @@ parse_flush(struct context *ctx, const struct token *token,

[dpdk-dev] [PATCH 10/22] app/testpmd: add flow validate/create commands

2016-11-16 Thread Adrien Mazarguil
Syntax:

 flow (validate|create) {port_id}
[group {group_id}] [priority {level}] [ingress] [egress]
pattern {item} [/ {item} [...]] / end
actions {action} [/ {action} [...]] / end

Either check the validity of a flow rule or create it. Any number of
pattern items and actions can be provided in any order. Completion is
available for convenience.

This commit only adds support for the most basic item and action types,
namely:

- END: terminates pattern items and actions lists.
- VOID: item/action filler, no operation.
- INVERT: inverted pattern matching, process packets that do not match.
- PASSTHRU: action that leaves packets up for additional processing by
  subsequent flow rules.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline.c  |  14 ++
 app/test-pmd/cmdline_flow.c | 314 ++-
 2 files changed, 327 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 20a64b6..851cc16 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -811,6 +811,20 @@ static void cmd_help_long_parsed(void *parsed_result,
" (select|add)\n"
"Set the input set for FDir.\n\n"

+   "flow validate {port_id}"
+   " [group {group_id}] [priority {level}]"
+   " [ingress] [egress]"
+   " pattern {item} [/ {item} [...]] / end"
+   " actions {action} [/ {action} [...]] / end\n"
+   "Check whether a flow rule can be created.\n\n"
+
+   "flow create {port_id}"
+   " [group {group_id}] [priority {level}]"
+   " [ingress] [egress]"
+   " pattern {item} [{item} [...]] end"
+   " actions {action} [{action} [...]] end\n"
+   "Create a flow rule.\n\n"
+
"flow destroy {port_id} rule {rule_id} [...]\n"
"Destroy specific flow rules.\n\n"

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 5a8980c..1874849 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -59,11 +59,14 @@ enum index {
RULE_ID,
PORT_ID,
GROUP_ID,
+   PRIORITY_LEVEL,

/* Top-level command. */
FLOW,

/* Sub-level commands. */
+   VALIDATE,
+   CREATE,
DESTROY,
FLUSH,
LIST,
@@ -73,6 +76,26 @@ enum index {

/* List arguments. */
LIST_GROUP,
+
+   /* Validate/create arguments. */
+   GROUP,
+   PRIORITY,
+   INGRESS,
+   EGRESS,
+
+   /* Validate/create pattern. */
+   PATTERN,
+   ITEM_NEXT,
+   ITEM_END,
+   ITEM_VOID,
+   ITEM_INVERT,
+
+   /* Validate/create actions. */
+   ACTIONS,
+   ACTION_NEXT,
+   ACTION_END,
+   ACTION_VOID,
+   ACTION_PASSTHRU,
 };

 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -92,6 +115,7 @@ struct context {
uint32_t eol:1; /**< EOL has been detected. */
uint32_t last:1; /**< No more arguments. */
uint16_t port; /**< Current port ID (for completions). */
+   uint32_t objdata; /**< Object-specific data. */
void *object; /**< Address of current object for relative offsets. */
 };

@@ -109,6 +133,8 @@ struct token {
const char *type;
/** Help displayed during completion (defaults to token name). */
const char *help;
+   /** Private data used by parser functions. */
+   const void *priv;
/**
 * Lists of subsequent tokens to push on the stack. Each call to the
 * parser consumes the last entry of that stack.
@@ -170,6 +196,14 @@ struct buffer {
uint16_t port; /**< Affected port ID. */
union {
struct {
+   struct rte_flow_attr attr;
+   struct rte_flow_item *pattern;
+   struct rte_flow_action *actions;
+   uint32_t pattern_n;
+   uint32_t actions_n;
+   uint8_t *data;
+   } vc; /**< Validate/create arguments. */
+   struct {
uint32_t *rule;
uint32_t rule_n;
} destroy; /**< Destroy arguments. */
@@ -180,6 +214,39 @@ struct buffer {
} args; /**< Command arguments. */
 };

+/** Private data for pattern items. */
+struct parse_item_priv {
+   enum rte_flow_item_type type; /**< Item type. */
+   uint32_t size; /**< Size of item specification structure. */
+};
+
+#define PRIV_ITEM(t, s) \
+   (&(const struct parse_item_priv){ \
+   .type = RTE_FLOW_ITEM_TYPE_ ## t, \
+   .size = s, \
+   })
+
+/** Private data for actions. */
+struct parse_action_priv {
+   enum rte_flow_action_type type; 

[dpdk-dev] [PATCH 09/22] app/testpmd: add flow destroy command

2016-11-16 Thread Adrien Mazarguil
Syntax:

 flow destroy {port_id} rule {rule_id} [...]

Destroy a given set of flow rules associated with a port.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline.c  |   3 ++
 app/test-pmd/cmdline_flow.c | 106 ++-
 2 files changed, 108 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 9f124fc..20a64b6 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -811,6 +811,9 @@ static void cmd_help_long_parsed(void *parsed_result,
" (select|add)\n"
"Set the input set for FDir.\n\n"

+   "flow destroy {port_id} rule {rule_id} [...]\n"
+   "Destroy specific flow rules.\n\n"
+
"flow flush {port_id}\n"
"Destroy all flow rules.\n\n"

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 414bacc..5a8980c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -56,6 +56,7 @@ enum index {
/* Common tokens. */
INTEGER,
UNSIGNED,
+   RULE_ID,
PORT_ID,
GROUP_ID,

@@ -63,9 +64,13 @@ enum index {
FLOW,

/* Sub-level commands. */
+   DESTROY,
FLUSH,
LIST,

+   /* Destroy arguments. */
+   DESTROY_RULE,
+
/* List arguments. */
LIST_GROUP,
 };
@@ -165,12 +170,22 @@ struct buffer {
uint16_t port; /**< Affected port ID. */
union {
struct {
+   uint32_t *rule;
+   uint32_t rule_n;
+   } destroy; /**< Destroy arguments. */
+   struct {
uint32_t *group;
uint32_t group_n;
} list; /**< List arguments. */
} args; /**< Command arguments. */
 };

+static const enum index next_destroy_attr[] = {
+   DESTROY_RULE,
+   END,
+   0,
+};
+
 static const enum index next_list_attr[] = {
LIST_GROUP,
END,
@@ -180,6 +195,9 @@ static const enum index next_list_attr[] = {
 static int parse_init(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
+static int parse_destroy(struct context *, const struct token *,
+const char *, unsigned int,
+void *, unsigned int);
 static int parse_flush(struct context *, const struct token *,
   const char *, unsigned int,
   void *, unsigned int);
@@ -196,6 +214,8 @@ static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
 static int comp_port(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
+static int comp_rule_id(struct context *, const struct token *,
+   unsigned int, char *, unsigned int);

 /** Token definitions. */
 static const struct token token_list[] = {
@@ -225,6 +245,13 @@ static const struct token token_list[] = {
.call = parse_int,
.comp = comp_none,
},
+   [RULE_ID] = {
+   .name = "{rule id}",
+   .type = "RULE ID",
+   .help = "rule identifier",
+   .call = parse_int,
+   .comp = comp_rule_id,
+   },
[PORT_ID] = {
.name = "{port_id}",
.type = "PORT ID",
@@ -245,11 +272,19 @@ static const struct token token_list[] = {
.type = "{command} {port_id} [{arg} [...]]",
.help = "manage ingress/egress flow rules",
.next = NEXT(NEXT_ENTRY
-(FLUSH,
+(DESTROY,
+ FLUSH,
  LIST)),
.call = parse_init,
},
/* Sub-level commands. */
+   [DESTROY] = {
+   .name = "destroy",
+   .help = "destroy specific flow rules",
+   .next = NEXT(NEXT_ENTRY(DESTROY_RULE), NEXT_ENTRY(PORT_ID)),
+   .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+   .call = parse_destroy,
+   },
[FLUSH] = {
.name = "flush",
.help = "destroy all flow rules",
@@ -264,6 +299,14 @@ static const struct token token_list[] = {
.args = ARGS(ARGS_ENTRY(struct buffer, port)),
.call = parse_list,
},
+   /* Destroy arguments. */
+   [DESTROY_RULE] = {
+   .name = "rule",
+   .help = "specify a rule identifier",
+   .next = NEXT(next_destroy_attr, NEXT_ENTRY(RULE_ID)),
+   .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.destroy.rule)),
+   .call = parse_destroy,
+   },
/* List arguments. */
[LIST_GROUP] = {
  

[dpdk-dev] [PATCH 08/22] app/testpmd: add flow flush command

2016-11-16 Thread Adrien Mazarguil
Syntax:

 flow flush {port_id}

Destroy all flow rules on a port.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline.c  |  3 +++
 app/test-pmd/cmdline_flow.c | 43 +++-
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 09357c0..9f124fc 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -811,6 +811,9 @@ static void cmd_help_long_parsed(void *parsed_result,
" (select|add)\n"
"Set the input set for FDir.\n\n"

+   "flow flush {port_id}\n"
+   "Destroy all flow rules.\n\n"
+
"flow list {port_id} [group {group_id}] [...]\n"
"List existing flow rules sorted by priority,"
" filtered by group identifiers.\n\n"
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 727fe78..414bacc 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -63,6 +63,7 @@ enum index {
FLOW,

/* Sub-level commands. */
+   FLUSH,
LIST,

/* List arguments. */
@@ -179,6 +180,9 @@ static const enum index next_list_attr[] = {
 static int parse_init(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
+static int parse_flush(struct context *, const struct token *,
+  const char *, unsigned int,
+  void *, unsigned int);
 static int parse_list(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
@@ -240,10 +244,19 @@ static const struct token token_list[] = {
.name = "flow",
.type = "{command} {port_id} [{arg} [...]]",
.help = "manage ingress/egress flow rules",
-   .next = NEXT(NEXT_ENTRY(LIST)),
+   .next = NEXT(NEXT_ENTRY
+(FLUSH,
+ LIST)),
.call = parse_init,
},
/* Sub-level commands. */
+   [FLUSH] = {
+   .name = "flush",
+   .help = "destroy all flow rules",
+   .next = NEXT(NEXT_ENTRY(PORT_ID)),
+   .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+   .call = parse_flush,
+   },
[LIST] = {
.name = "list",
.help = "list existing flow rules",
@@ -316,6 +329,31 @@ parse_init(struct context *ctx, const struct token *token,
return len;
 }

+/** Parse tokens for flush command. */
+static int
+parse_flush(struct context *ctx, const struct token *token,
+   const char *str, unsigned int len,
+   void *buf, unsigned int size)
+{
+   struct buffer *out = buf;
+
+   /* Token name must match. */
+   if (parse_default(ctx, token, str, len, NULL, 0) < 0)
+   return -1;
+   /* Nothing else to do if there is no buffer. */
+   if (!out)
+   return len;
+   if (!out->command) {
+   if (ctx->curr != FLUSH)
+   return -1;
+   if (sizeof(*out) > size)
+   return -1;
+   out->command = ctx->curr;
+   ctx->object = out;
+   }
+   return len;
+}
+
 /** Parse tokens for list command. */
 static int
 parse_list(struct context *ctx, const struct token *token,
@@ -698,6 +736,9 @@ static void
 cmd_flow_parsed(const struct buffer *in)
 {
switch (in->command) {
+   case FLUSH:
+   port_flow_flush(in->port);
+   break;
case LIST:
port_flow_list(in->port, in->args.list.group_n,
   in->args.list.group);
-- 
2.1.4



[dpdk-dev] [PATCH 07/22] app/testpmd: add flow list command

2016-11-16 Thread Adrien Mazarguil
Syntax:

 flow list {port_id} [group {group_id}] [...]

List configured flow rules on a port. Output can optionally be limited to a
given set of group identifiers.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline.c  |   4 ++
 app/test-pmd/cmdline_flow.c | 141 +++
 2 files changed, 145 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index b7d10b3..09357c0 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -810,6 +810,10 @@ static void cmd_help_long_parsed(void *parsed_result,
"sctp-src-port|sctp-dst-port|sctp-veri-tag|none)"
" (select|add)\n"
"Set the input set for FDir.\n\n"
+
+   "flow list {port_id} [group {group_id}] [...]\n"
+   "List existing flow rules sorted by priority,"
+   " filtered by group identifiers.\n\n"
);
}
 }
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7078f80..727fe78 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -56,9 +56,17 @@ enum index {
/* Common tokens. */
INTEGER,
UNSIGNED,
+   PORT_ID,
+   GROUP_ID,

/* Top-level command. */
FLOW,
+
+   /* Sub-level commands. */
+   LIST,
+
+   /* List arguments. */
+   LIST_GROUP,
 };

 /** Maximum number of subsequent tokens and arguments on the stack. */
@@ -77,6 +85,7 @@ struct context {
uint32_t reparse:1; /**< Start over from the beginning. */
uint32_t eol:1; /**< EOL has been detected. */
uint32_t last:1; /**< No more arguments. */
+   uint16_t port; /**< Current port ID (for completions). */
void *object; /**< Address of current object for relative offsets. */
 };

@@ -153,16 +162,36 @@ struct token {
 struct buffer {
enum index command; /**< Flow command. */
uint16_t port; /**< Affected port ID. */
+   union {
+   struct {
+   uint32_t *group;
+   uint32_t group_n;
+   } list; /**< List arguments. */
+   } args; /**< Command arguments. */
+};
+
+static const enum index next_list_attr[] = {
+   LIST_GROUP,
+   END,
+   0,
 };

 static int parse_init(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
+static int parse_list(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
 static int parse_int(struct context *, const struct token *,
 const char *, unsigned int,
 void *, unsigned int);
+static int parse_port(struct context *, const struct token *,
+ const char *, unsigned int,
+ void *, unsigned int);
 static int comp_none(struct context *, const struct token *,
 unsigned int, char *, unsigned int);
+static int comp_port(struct context *, const struct token *,
+unsigned int, char *, unsigned int);

 /** Token definitions. */
 static const struct token token_list[] = {
@@ -192,13 +221,44 @@ static const struct token token_list[] = {
.call = parse_int,
.comp = comp_none,
},
+   [PORT_ID] = {
+   .name = "{port_id}",
+   .type = "PORT ID",
+   .help = "port identifier",
+   .call = parse_port,
+   .comp = comp_port,
+   },
+   [GROUP_ID] = {
+   .name = "{group_id}",
+   .type = "GROUP ID",
+   .help = "group identifier",
+   .call = parse_int,
+   .comp = comp_none,
+   },
/* Top-level command. */
[FLOW] = {
.name = "flow",
.type = "{command} {port_id} [{arg} [...]]",
.help = "manage ingress/egress flow rules",
+   .next = NEXT(NEXT_ENTRY(LIST)),
.call = parse_init,
},
+   /* Sub-level commands. */
+   [LIST] = {
+   .name = "list",
+   .help = "list existing flow rules",
+   .next = NEXT(next_list_attr, NEXT_ENTRY(PORT_ID)),
+   .args = ARGS(ARGS_ENTRY(struct buffer, port)),
+   .call = parse_list,
+   },
+   /* List arguments. */
+   [LIST_GROUP] = {
+   .name = "group",
+   .help = "specify a group",
+   .next = NEXT(next_list_attr, NEXT_ENTRY(GROUP_ID)),
+   .args = ARGS(ARGS_ENTRY_PTR(struct buffer, args.list.group)),
+   .call = parse_list,
+   },
 };

 /** Remove and return last entry from argument stack. */
@@ -256,6 +316,39 @@ parse_init(struct context *ctx, const struct token *token,
return len;
 }

+/** Parse 

[dpdk-dev] [PATCH 06/22] app/testpmd: add rte_flow integer support

2016-11-16 Thread Adrien Mazarguil
Parse all integer types and handle conversion to network byte order in a
single function.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline_flow.c | 148 +++
 1 file changed, 148 insertions(+)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 7dbda84..7078f80 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -34,11 +34,14 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
 #include 

 #include 
 #include 
+#include 
 #include 
 #include 

@@ -50,6 +53,10 @@ enum index {
ZERO = 0,
END,

+   /* Common tokens. */
+   INTEGER,
+   UNSIGNED,
+
/* Top-level command. */
FLOW,
 };
@@ -61,12 +68,24 @@ enum index {
 struct context {
/** Stack of subsequent token lists to process. */
const enum index *next[CTX_STACK_SIZE];
+   /** Arguments for stacked tokens. */
+   const void *args[CTX_STACK_SIZE];
enum index curr; /**< Current token index. */
enum index prev; /**< Index of the last token seen. */
int next_num; /**< Number of entries in next[]. */
+   int args_num; /**< Number of entries in args[]. */
uint32_t reparse:1; /**< Start over from the beginning. */
uint32_t eol:1; /**< EOL has been detected. */
uint32_t last:1; /**< No more arguments. */
+   void *object; /**< Address of current object for relative offsets. */
+};
+
+/** Token argument. */
+struct arg {
+   uint32_t hton:1; /**< Use network byte ordering. */
+   uint32_t sign:1; /**< Value is signed. */
+   uint32_t offset; /**< Relative offset from ctx->object. */
+   uint32_t size; /**< Field size. */
 };

 /** Parser token definition. */
@@ -80,6 +99,8 @@ struct token {
 * parser consumes the last entry of that stack.
 */
const enum index *const *next;
+   /** Arguments stack for subsequent tokens that need them. */
+   const struct arg *const *args;
/**
 * Token-processing callback, returns -1 in case of error, the
 * length of the matched string otherwise. If NULL, attempts to
@@ -112,6 +133,22 @@ struct token {
 /** Static initializer for a NEXT() entry. */
 #define NEXT_ENTRY(...) (const enum index []){ __VA_ARGS__, 0, }

+/** Static initializer for the args field. */
+#define ARGS(...) (const struct arg *const []){ __VA_ARGS__, NULL, }
+
+/** Static initializer for ARGS() to target a field. */
+#define ARGS_ENTRY(s, f) \
+   (&(const struct arg){ \
+   .offset = offsetof(s, f), \
+   .size = sizeof(((s *)0)->f), \
+   })
+
+/** Static initializer for ARGS() to target a pointer. */
+#define ARGS_ENTRY_PTR(s, f) \
+   (&(const struct arg){ \
+   .size = sizeof(*((s *)0)->f), \
+   })
+
 /** Parser output buffer layout expected by cmd_flow_parsed(). */
 struct buffer {
enum index command; /**< Flow command. */
@@ -121,6 +158,11 @@ struct buffer {
 static int parse_init(struct context *, const struct token *,
  const char *, unsigned int,
  void *, unsigned int);
+static int parse_int(struct context *, const struct token *,
+const char *, unsigned int,
+void *, unsigned int);
+static int comp_none(struct context *, const struct token *,
+unsigned int, char *, unsigned int);

 /** Token definitions. */
 static const struct token token_list[] = {
@@ -135,6 +177,21 @@ static const struct token token_list[] = {
.type = "RETURN",
.help = "command may end here",
},
+   /* Common tokens. */
+   [INTEGER] = {
+   .name = "{int}",
+   .type = "INTEGER",
+   .help = "integer value",
+   .call = parse_int,
+   .comp = comp_none,
+   },
+   [UNSIGNED] = {
+   .name = "{unsigned}",
+   .type = "UNSIGNED",
+   .help = "unsigned integer value",
+   .call = parse_int,
+   .comp = comp_none,
+   },
/* Top-level command. */
[FLOW] = {
.name = "flow",
@@ -144,6 +201,23 @@ static const struct token token_list[] = {
},
 };

+/** Remove and return last entry from argument stack. */
+static const struct arg *
+pop_args(struct context *ctx)
+{
+   return ctx->args_num ? ctx->args[--ctx->args_num] : NULL;
+}
+
+/** Add entry on top of the argument stack. */
+static int
+push_args(struct context *ctx, const struct arg *arg)
+{
+   if (ctx->args_num == CTX_STACK_SIZE)
+   return -1;
+   ctx->args[ctx->args_num++] = arg;
+   return 0;
+}
+
 /** Default parsing function for token name matching. */
 static int
 parse_default(struct context *ctx, const struct token *token,
@@ -178,9 +252,74 @@ parse_init(struct context *ctx, const struct token *token,
/* 

[dpdk-dev] [PATCH 05/22] app/testpmd: add flow command

2016-11-16 Thread Adrien Mazarguil
Managing generic flow API functions from command line requires the use of
dynamic tokens for convenience as flow rules are not fixed and cannot be
defined statically.

This commit adds specific flexible parser code and object for a new "flow"
command in separate file.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/Makefile   |   1 +
 app/test-pmd/cmdline.c  |   4 +
 app/test-pmd/cmdline_flow.c | 439 +++
 3 files changed, 444 insertions(+)

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 891b85a..5988c3e 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -47,6 +47,7 @@ CFLAGS += $(WERROR_FLAGS)
 SRCS-y := testpmd.c
 SRCS-y += parameters.c
 SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline.c
+SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_flow.c
 SRCS-y += config.c
 SRCS-y += iofwd.c
 SRCS-y += macfwd.c
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index c5b015c..b7d10b3 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -9520,6 +9520,9 @@ cmdline_parse_inst_t cmd_set_flow_director_flex_payload = 
{
},
 };

+/* Generic flow interface command. */
+extern cmdline_parse_inst_t cmd_flow;
+
 /* *** Classification Filters Control *** */
 /* *** Get symmetric hash enable per port *** */
 struct cmd_get_sym_hash_ena_per_port_result {
@@ -11557,6 +11560,7 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)_set_hash_global_config,
(cmdline_parse_inst_t *)_set_hash_input_set,
(cmdline_parse_inst_t *)_set_fdir_input_set,
+   (cmdline_parse_inst_t *)_flow,
(cmdline_parse_inst_t *)_mcast_addr,
(cmdline_parse_inst_t *)_config_l2_tunnel_eth_type_all,
(cmdline_parse_inst_t *)_config_l2_tunnel_eth_type_specific,
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
new file mode 100644
index 000..7dbda84
--- /dev/null
+++ b/app/test-pmd/cmdline_flow.c
@@ -0,0 +1,439 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2016 6WIND S.A.
+ *   Copyright 2016 Mellanox.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of 6WIND S.A. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+#include 
+
+#include "testpmd.h"
+
+/** Parser token indices. */
+enum index {
+   /* Special tokens. */
+   ZERO = 0,
+   END,
+
+   /* Top-level command. */
+   FLOW,
+};
+
+/** Maximum number of subsequent tokens and arguments on the stack. */
+#define CTX_STACK_SIZE 16
+
+/** Parser context. */
+struct context {
+   /** Stack of subsequent token lists to process. */
+   const enum index *next[CTX_STACK_SIZE];
+   enum index curr; /**< Current token index. */
+   enum index prev; /**< Index of the last token seen. */
+   int next_num; /**< Number of entries in next[]. */
+   uint32_t reparse:1; /**< Start over from the beginning. */
+   uint32_t eol:1; /**< EOL has been detected. */
+   uint32_t last:1; /**< No more arguments. */
+};
+
+/** Parser token definition. */
+struct token {
+   /** Type displayed during completion (defaults to "TOKEN"). */
+   const char *type;
+   /** Help displayed during completion (defaults to token name). */
+   const char *help;
+   /**
+* Lists of subsequent tokens to push on the stack. Each call to the
+* parser consumes the last entry of that stack.
+*/
+   const enum index *const 

[dpdk-dev] [PATCH 04/22] app/testpmd: implement basic support for rte_flow

2016-11-16 Thread Adrien Mazarguil
Add basic management functions for the generic flow API (validate, create,
destroy, flush, query and list). Flow rule objects and properties are
arranged in lists associated with each port.

Signed-off-by: Adrien Mazarguil 
---
 app/test-pmd/cmdline.c |   1 +
 app/test-pmd/config.c  | 484 
 app/test-pmd/csumonly.c|   1 +
 app/test-pmd/flowgen.c |   1 +
 app/test-pmd/icmpecho.c|   1 +
 app/test-pmd/ieee1588fwd.c |   1 +
 app/test-pmd/iofwd.c   |   1 +
 app/test-pmd/macfwd.c  |   1 +
 app/test-pmd/macswap.c |   1 +
 app/test-pmd/parameters.c  |   1 +
 app/test-pmd/rxonly.c  |   1 +
 app/test-pmd/testpmd.c |   6 +
 app/test-pmd/testpmd.h |  27 +++
 app/test-pmd/txonly.c  |   1 +
 14 files changed, 528 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 63b55dc..c5b015c 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -75,6 +75,7 @@
 #include 
 #include 
 #include 
+#include 

 #include 
 #include 
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 36c47ab..c9dc872 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -92,6 +92,8 @@
 #include 
 #include 
 #include 
+#include 
+#include 

 #include "testpmd.h"

@@ -750,6 +752,488 @@ port_mtu_set(portid_t port_id, uint16_t mtu)
printf("Set MTU failed. diag=%d\n", diag);
 }

+/* Generic flow management functions. */
+
+/** Generate flow_item[] entry. */
+#define MK_FLOW_ITEM(t, s) \
+   [RTE_FLOW_ITEM_TYPE_ ## t] = { \
+   .name = # t, \
+   .size = s, \
+   }
+
+/** Information about known flow pattern items. */
+static const struct {
+   const char *name;
+   size_t size;
+} flow_item[] = {
+   MK_FLOW_ITEM(END, 0),
+   MK_FLOW_ITEM(VOID, 0),
+   MK_FLOW_ITEM(INVERT, 0),
+   MK_FLOW_ITEM(ANY, sizeof(struct rte_flow_item_any)),
+   MK_FLOW_ITEM(PF, 0),
+   MK_FLOW_ITEM(VF, sizeof(struct rte_flow_item_vf)),
+   MK_FLOW_ITEM(PORT, sizeof(struct rte_flow_item_port)),
+   MK_FLOW_ITEM(RAW, sizeof(struct rte_flow_item_raw)), /* +pattern[] */
+   MK_FLOW_ITEM(ETH, sizeof(struct rte_flow_item_eth)),
+   MK_FLOW_ITEM(VLAN, sizeof(struct rte_flow_item_vlan)),
+   MK_FLOW_ITEM(IPV4, sizeof(struct rte_flow_item_ipv4)),
+   MK_FLOW_ITEM(IPV6, sizeof(struct rte_flow_item_ipv6)),
+   MK_FLOW_ITEM(ICMP, sizeof(struct rte_flow_item_icmp)),
+   MK_FLOW_ITEM(UDP, sizeof(struct rte_flow_item_udp)),
+   MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
+   MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
+   MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
+};
+
+/** Compute storage space needed by item specification. */
+static void
+flow_item_spec_size(const struct rte_flow_item *item,
+   size_t *size, size_t *pad)
+{
+   if (!item->spec)
+   goto empty;
+   switch (item->type) {
+   union {
+   const struct rte_flow_item_raw *raw;
+   } spec;
+
+   case RTE_FLOW_ITEM_TYPE_RAW:
+   spec.raw = item->spec;
+   *size = offsetof(struct rte_flow_item_raw, pattern) +
+   spec.raw->length * sizeof(*spec.raw->pattern);
+   break;
+   default:
+empty:
+   *size = 0;
+   break;
+   }
+   *pad = RTE_ALIGN_CEIL(*size, sizeof(double)) - *size;
+}
+
+/** Generate flow_action[] entry. */
+#define MK_FLOW_ACTION(t, s) \
+   [RTE_FLOW_ACTION_TYPE_ ## t] = { \
+   .name = # t, \
+   .size = s, \
+   }
+
+/** Information about known flow actions. */
+static const struct {
+   const char *name;
+   size_t size;
+} flow_action[] = {
+   MK_FLOW_ACTION(END, 0),
+   MK_FLOW_ACTION(VOID, 0),
+   MK_FLOW_ACTION(PASSTHRU, 0),
+   MK_FLOW_ACTION(MARK, sizeof(struct rte_flow_action_mark)),
+   MK_FLOW_ACTION(FLAG, 0),
+   MK_FLOW_ACTION(QUEUE, sizeof(struct rte_flow_action_queue)),
+   MK_FLOW_ACTION(DROP, 0),
+   MK_FLOW_ACTION(COUNT, 0),
+   MK_FLOW_ACTION(DUP, sizeof(struct rte_flow_action_dup)),
+   MK_FLOW_ACTION(RSS, sizeof(struct rte_flow_action_rss)), /* +queue[] */
+   MK_FLOW_ACTION(PF, 0),
+   MK_FLOW_ACTION(VF, sizeof(struct rte_flow_action_vf)),
+};
+
+/** Compute storage space needed by action configuration. */
+static void
+flow_action_conf_size(const struct rte_flow_action *action,
+ size_t *size, size_t *pad)
+{
+   if (!action->conf)
+   goto empty;
+   switch (action->type) {
+   union {
+   const struct rte_flow_action_rss *rss;
+   } conf;
+
+   case RTE_FLOW_ACTION_TYPE_RSS:
+   conf.rss = action->conf;
+   *size = offsetof(struct rte_flow_action_rss, queue) +
+   conf.rss->queues * 

[dpdk-dev] [PATCH 03/22] cmdline: add alignment constraint

2016-11-16 Thread Adrien Mazarguil
This prevents sigbus errors on architectures that cannot handle unexpected
unaligned accesses to the output buffer.

Signed-off-by: Adrien Mazarguil 
---
 lib/librte_cmdline/cmdline_parse.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/lib/librte_cmdline/cmdline_parse.c 
b/lib/librte_cmdline/cmdline_parse.c
index 14f5553..763c286 100644
--- a/lib/librte_cmdline/cmdline_parse.c
+++ b/lib/librte_cmdline/cmdline_parse.c
@@ -255,7 +255,10 @@ cmdline_parse(struct cmdline *cl, const char * buf)
unsigned int inst_num=0;
cmdline_parse_inst_t *inst;
const char *curbuf;
-   char result_buf[CMDLINE_PARSE_RESULT_BUFSIZE];
+   union {
+   char buf[CMDLINE_PARSE_RESULT_BUFSIZE];
+   long double align; /* strong alignment constraint for buf */
+   } result;
cmdline_parse_token_hdr_t *dyn_tokens[CMDLINE_PARSE_DYNAMIC_TOKENS];
void (*f)(void *, struct cmdline *, void *) = NULL;
void *data = NULL;
@@ -318,7 +321,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)
debug_printf("INST %d\n", inst_num);

/* fully parsed */
-   tok = match_inst(inst, buf, 0, result_buf, sizeof(result_buf),
+   tok = match_inst(inst, buf, 0, result.buf, sizeof(result.buf),
 _tokens);

if (tok > 0) /* we matched at least one token */
@@ -353,7 +356,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)

/* call func */
if (f) {
-   f(result_buf, cl, data);
+   f(result.buf, cl, data);
}

/* no match */
-- 
2.1.4



[dpdk-dev] [PATCH 02/22] cmdline: add support for dynamic tokens

2016-11-16 Thread Adrien Mazarguil
Considering tokens must be hard-coded in a list part of the instruction
structure, context-dependent tokens cannot be expressed.

This commit adds support for building dynamic token lists through a
user-provided function, which is called when the static token list is empty
(a single NULL entry).

Because no structures are modified (existing fields are reused), this
commit has no impact on the current ABI.

Signed-off-by: Adrien Mazarguil 
---
 lib/librte_cmdline/cmdline_parse.c | 60 +
 lib/librte_cmdline/cmdline_parse.h | 21 
 2 files changed, 74 insertions(+), 7 deletions(-)

diff --git a/lib/librte_cmdline/cmdline_parse.c 
b/lib/librte_cmdline/cmdline_parse.c
index b496067..14f5553 100644
--- a/lib/librte_cmdline/cmdline_parse.c
+++ b/lib/librte_cmdline/cmdline_parse.c
@@ -146,7 +146,9 @@ nb_common_chars(const char * s1, const char * s2)
  */
 static int
 match_inst(cmdline_parse_inst_t *inst, const char *buf,
-  unsigned int nb_match_token, void *resbuf, unsigned resbuf_size)
+  unsigned int nb_match_token, void *resbuf, unsigned resbuf_size,
+  cmdline_parse_token_hdr_t
+   *(*dyn_tokens)[CMDLINE_PARSE_DYNAMIC_TOKENS])
 {
unsigned int token_num=0;
cmdline_parse_token_hdr_t * token_p;
@@ -155,6 +157,11 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf,
struct cmdline_token_hdr token_hdr;

token_p = inst->tokens[token_num];
+   if (!token_p && dyn_tokens && inst->f) {
+   if (!(*dyn_tokens)[0])
+   inst->f(&(*dyn_tokens)[0], NULL, dyn_tokens);
+   token_p = (*dyn_tokens)[0];
+   }
if (token_p)
memcpy(_hdr, token_p, sizeof(token_hdr));

@@ -196,7 +203,17 @@ match_inst(cmdline_parse_inst_t *inst, const char *buf,
buf += n;

token_num ++;
-   token_p = inst->tokens[token_num];
+   if (!inst->tokens[0]) {
+   if (token_num < (CMDLINE_PARSE_DYNAMIC_TOKENS - 1)) {
+   if (!(*dyn_tokens)[token_num])
+   inst->f(&(*dyn_tokens)[token_num],
+   NULL,
+   dyn_tokens);
+   token_p = (*dyn_tokens)[token_num];
+   } else
+   token_p = NULL;
+   } else
+   token_p = inst->tokens[token_num];
if (token_p)
memcpy(_hdr, token_p, sizeof(token_hdr));
}
@@ -239,6 +256,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)
cmdline_parse_inst_t *inst;
const char *curbuf;
char result_buf[CMDLINE_PARSE_RESULT_BUFSIZE];
+   cmdline_parse_token_hdr_t *dyn_tokens[CMDLINE_PARSE_DYNAMIC_TOKENS];
void (*f)(void *, struct cmdline *, void *) = NULL;
void *data = NULL;
int comment = 0;
@@ -255,6 +273,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)
return CMDLINE_PARSE_BAD_ARGS;

ctx = cl->ctx;
+   memset(_tokens, 0, sizeof(dyn_tokens));

/*
 * - look if the buffer contains at least one line
@@ -299,7 +318,8 @@ cmdline_parse(struct cmdline *cl, const char * buf)
debug_printf("INST %d\n", inst_num);

/* fully parsed */
-   tok = match_inst(inst, buf, 0, result_buf, sizeof(result_buf));
+   tok = match_inst(inst, buf, 0, result_buf, sizeof(result_buf),
+_tokens);

if (tok > 0) /* we matched at least one token */
err = CMDLINE_PARSE_BAD_ARGS;
@@ -355,6 +375,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int 
*state,
cmdline_parse_token_hdr_t *token_p;
struct cmdline_token_hdr token_hdr;
char tmpbuf[CMDLINE_BUFFER_SIZE], comp_buf[CMDLINE_BUFFER_SIZE];
+   cmdline_parse_token_hdr_t *dyn_tokens[CMDLINE_PARSE_DYNAMIC_TOKENS];
unsigned int partial_tok_len;
int comp_len = -1;
int tmp_len = -1;
@@ -374,6 +395,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int 
*state,

debug_printf("%s called\n", __func__);
memset(_hdr, 0, sizeof(token_hdr));
+   memset(_tokens, 0, sizeof(dyn_tokens));

/* count the number of complete token to parse */
for (i=0 ; buf[i] ; i++) {
@@ -396,11 +418,24 @@ cmdline_complete(struct cmdline *cl, const char *buf, int 
*state,
inst = ctx[inst_num];
while (inst) {
/* parse the first tokens of the inst */
-   if (nb_token && match_inst(inst, buf, nb_token, NULL, 
0))
+   if (nb_token &&
+   match_inst(inst, buf, nb_token, NULL, 0,
+  _tokens))
   

[dpdk-dev] [PATCH 01/22] ethdev: introduce generic flow API

2016-11-16 Thread Adrien Mazarguil
This new API supersedes all the legacy filter types described in
rte_eth_ctrl.h. It is slightly higher level and as a result relies more on
PMDs to process and validate flow rules.

Benefits:

- A unified API is easier to program for, applications do not have to be
  written for a specific filter type which may or may not be supported by
  the underlying device.

- The behavior of a flow rule is the same regardless of the underlying
  device, applications do not need to be aware of hardware quirks.

- Extensible by design, API/ABI breakage should rarely occur if at all.

- Documentation is self-standing, no need to look up elsewhere.

Existing filter types will be deprecated and removed in the near future.

Signed-off-by: Adrien Mazarguil 
---
 MAINTAINERS|   4 +
 lib/librte_ether/Makefile  |   3 +
 lib/librte_ether/rte_eth_ctrl.h|   1 +
 lib/librte_ether/rte_ether_version.map |  10 +
 lib/librte_ether/rte_flow.c| 159 +
 lib/librte_ether/rte_flow.h| 947 
 lib/librte_ether/rte_flow_driver.h | 177 ++
 7 files changed, 1301 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index d6bb8f8..3b46630 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -243,6 +243,10 @@ M: Thomas Monjalon 
 F: lib/librte_ether/
 F: scripts/test-null.sh

+Generic flow API
+M: Adrien Mazarguil 
+F: lib/librte_ether/rte_flow*
+
 Crypto API
 M: Declan Doherty 
 F: lib/librte_cryptodev/
diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile
index efe1e5f..9335361 100644
--- a/lib/librte_ether/Makefile
+++ b/lib/librte_ether/Makefile
@@ -44,6 +44,7 @@ EXPORT_MAP := rte_ether_version.map
 LIBABIVER := 5

 SRCS-y += rte_ethdev.c
+SRCS-y += rte_flow.c

 #
 # Export include files
@@ -51,6 +52,8 @@ SRCS-y += rte_ethdev.c
 SYMLINK-y-include += rte_ethdev.h
 SYMLINK-y-include += rte_eth_ctrl.h
 SYMLINK-y-include += rte_dev_info.h
+SYMLINK-y-include += rte_flow.h
+SYMLINK-y-include += rte_flow_driver.h

 # this lib depends upon:
 DEPDIRS-y += lib/librte_net lib/librte_eal lib/librte_mempool lib/librte_ring 
lib/librte_mbuf
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index fe80eb0..8386904 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -99,6 +99,7 @@ enum rte_filter_type {
RTE_ETH_FILTER_FDIR,
RTE_ETH_FILTER_HASH,
RTE_ETH_FILTER_L2_TUNNEL,
+   RTE_ETH_FILTER_GENERIC,
RTE_ETH_FILTER_MAX
 };

diff --git a/lib/librte_ether/rte_ether_version.map 
b/lib/librte_ether/rte_ether_version.map
index 72be66d..b5d2547 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -147,3 +147,13 @@ DPDK_16.11 {
rte_eth_dev_pci_remove;

 } DPDK_16.07;
+
+DPDK_17.02 {
+   global:
+
+   rte_flow_validate;
+   rte_flow_create;
+   rte_flow_destroy;
+   rte_flow_query;
+
+} DPDK_16.11;
diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
new file mode 100644
index 000..064963d
--- /dev/null
+++ b/lib/librte_ether/rte_flow.c
@@ -0,0 +1,159 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2016 6WIND S.A.
+ *   Copyright 2016 Mellanox.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of 6WIND S.A. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include 
+
+#include 
+#include 
+#include "rte_ethdev.h"
+#include "rte_flow_driver.h"
+#include "rte_flow.h"
+
+/* Get generic flow operations structure 

[dpdk-dev] [PATCH 00/22] Generic flow API (rte_flow)

2016-11-16 Thread Adrien Mazarguil
As previously discussed in RFC v1 [1], RFC v2 [2], with changes
described in [3] (also pasted below), here is the first non-draft series
for this new API.

Its capabilities are so generic that its name had to be vague, it may be
called "Generic flow API", "Generic flow interface" (possibly shortened
as "GFI") to refer to the name of the new filter type, or "rte_flow" from
the prefix used for its public symbols. I personally favor the latter.

While it is currently meant to supersede existing filter types in order for
all PMDs to expose a common filtering/classification interface, it may
eventually evolve to cover the following ideas as well:

- Rx/Tx offloads configuration through automatic offloads for specific
  packets, e.g. performing checksum on TCP packets could be expressed with
  an egress rule with a TCP pattern and a kind of checksum action.

- RSS configuration (already defined actually). Could be global or per rule
  depending on hardware capabilities.

- Switching configuration for devices with many physical ports; rules doing
  both ingress and egress could even be used to completely bypass software
  if supported by hardware.

 [1] http://dpdk.org/ml/archives/dev/2016-July/043365.html
 [2] http://dpdk.org/ml/archives/dev/2016-August/045383.html
 [3] http://dpdk.org/ml/archives/dev/2016-November/050044.html

Changes since RFC v2:

- New separate VLAN pattern item (previously part of the ETH definition),
  found to be much more convenient.

- Removed useless "any" field from VF pattern item, the same effect can be
  achieved by not providing a specification structure.

- Replaced bit-fields from the VXLAN pattern item to avoid endianness
  conversion issues on 24-bit fields.

- Updated struct rte_flow_item with a new "last" field to create inclusive
  ranges. They are defined as the interval between (spec & mask) and
  (last & mask). All three parameters are optional.

- Renamed ID action MARK.

- Renamed "queue" fields in actions QUEUE and DUP to "index".

- "rss_conf" field in RSS action is now const.

- VF action now uses a 32 bit ID like its pattern item counterpart.

- Removed redundant struct rte_flow_pattern, API functions now expect
  struct
  rte_flow_item lists terminated by END items.

- Replaced struct rte_flow_actions for the same reason, with struct
  rte_flow_action lists terminated by END actions.

- Error types (enum rte_flow_error_type) have been updated and the cause
  pointer in struct rte_flow_error is now const.

- Function prototypes (rte_flow_create, rte_flow_validate) have also been
  updated for clarity.

Additions:

- Public wrapper functions rte_flow_{validate|create|destroy|flush|query}
  are now implemented in rte_flow.c, with their symbols exported and
  versioned. Related filter type RTE_ETH_FILTER_GENERIC has been added.

- A separate header (rte_flow_driver.h) has been added for driver-side
  functionality, in particular struct rte_flow_ops which contains PMD
  callbacks returned by RTE_ETH_FILTER_GENERIC query.

- testpmd now exposes most of this API through the new "flow" command.

What remains to be done:

- Using endian-aware integer types (rte_beX_t) where necessary for clarity.

- API documentation (based on RFC).

- testpmd flow command documentation (although context-aware command
  completion should already help quite a bit in this regard).

- A few pattern item / action properties cannot be configured yet
  (e.g. rss_conf parameter for RSS action) and a few completions
  (e.g. possible queue IDs) should be added.

Adrien Mazarguil (22):
  ethdev: introduce generic flow API
  cmdline: add support for dynamic tokens
  cmdline: add alignment constraint
  app/testpmd: implement basic support for rte_flow
  app/testpmd: add flow command
  app/testpmd: add rte_flow integer support
  app/testpmd: add flow list command
  app/testpmd: add flow flush command
  app/testpmd: add flow destroy command
  app/testpmd: add flow validate/create commands
  app/testpmd: add flow query command
  app/testpmd: add rte_flow item spec handler
  app/testpmd: add rte_flow item spec prefix length
  app/testpmd: add rte_flow bit-field support
  app/testpmd: add item any to flow command
  app/testpmd: add various items to flow command
  app/testpmd: add item raw to flow command
  app/testpmd: add items eth/vlan to flow command
  app/testpmd: add items ipv4/ipv6 to flow command
  app/testpmd: add L4 items to flow command
  app/testpmd: add various actions to flow command
  app/testpmd: add queue actions to flow command

 MAINTAINERS|4 +
 app/test-pmd/Makefile  |1 +
 app/test-pmd/cmdline.c |   32 +
 app/test-pmd/cmdline_flow.c| 2581 +++
 app/test-pmd/config.c  |  484 +
 app/test-pmd/csumonly.c|1 +
 app/test-pmd/flowgen.c |1 +
 app/test-pmd/icmpecho.c|1 +
 app/test-pmd/ieee1588fwd.c |1 

[dpdk-dev] [PATCH] eal: define generic vector types

2016-11-16 Thread Nelio Laranjeiro
Add common vector type definitions to all CPU architectures.

Signed-off-by: Nelio Laranjeiro 
---
 lib/librte_eal/common/Makefile |   1 +
 lib/librte_eal/common/include/arch/arm/rte_vect.h  |   1 +
 .../common/include/arch/ppc_64/rte_vect.h  |   1 +
 lib/librte_eal/common/include/arch/tile/rte_vect.h |  38 +
 lib/librte_eal/common/include/arch/x86/rte_vect.h  |   7 +-
 lib/librte_eal/common/include/generic/rte_vect.h   | 185 +
 6 files changed, 230 insertions(+), 3 deletions(-)
 create mode 100644 lib/librte_eal/common/include/arch/tile/rte_vect.h
 create mode 100644 lib/librte_eal/common/include/generic/rte_vect.h

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..8af06b1 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -48,6 +48,7 @@ endif

 GENERIC_INC := rte_atomic.h rte_byteorder.h rte_cycles.h rte_prefetch.h
 GENERIC_INC += rte_spinlock.h rte_memcpy.h rte_cpuflags.h rte_rwlock.h
+GENERIC_INC += rte_vect.h
 # defined in mk/arch/$(RTE_ARCH)/rte.vars.mk
 ARCH_DIR ?= $(RTE_ARCH)
 ARCH_INC := $(notdir $(wildcard 
$(RTE_SDK)/lib/librte_eal/common/include/arch/$(ARCH_DIR)/*.h))
diff --git a/lib/librte_eal/common/include/arch/arm/rte_vect.h 
b/lib/librte_eal/common/include/arch/arm/rte_vect.h
index b86c2cf..4107c99 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_vect.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_vect.h
@@ -34,6 +34,7 @@
 #define _RTE_VECT_ARM_H_

 #include 
+#include "generic/rte_vect.h"
 #include "arm_neon.h"

 #ifdef __cplusplus
diff --git a/lib/librte_eal/common/include/arch/ppc_64/rte_vect.h 
b/lib/librte_eal/common/include/arch/ppc_64/rte_vect.h
index 05209e5..99586e5 100644
--- a/lib/librte_eal/common/include/arch/ppc_64/rte_vect.h
+++ b/lib/librte_eal/common/include/arch/ppc_64/rte_vect.h
@@ -34,6 +34,7 @@
 #define _RTE_VECT_PPC_64_H_

 #include 
+#include "generic/rte_vect.h"

 #ifdef __cplusplus
 extern "C" {
diff --git a/lib/librte_eal/common/include/arch/tile/rte_vect.h 
b/lib/librte_eal/common/include/arch/tile/rte_vect.h
new file mode 100644
index 000..f1e1709
--- /dev/null
+++ b/lib/librte_eal/common/include/arch/tile/rte_vect.h
@@ -0,0 +1,38 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright 2016 6WIND S.A.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in
+ *   the documentation and/or other materials provided with the
+ *   distribution.
+ * * Neither the name of 6WIND S.A. nor the names of its
+ *   contributors may be used to endorse or promote products derived
+ *   from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_VECT_TILE_H_
+#define _RTE_VECT_TILE_H_
+
+#include "generic/rte_vect.h"
+
+#endif /* _RTE_VECT_TILE_H_ */
diff --git a/lib/librte_eal/common/include/arch/x86/rte_vect.h 
b/lib/librte_eal/common/include/arch/x86/rte_vect.h
index 77f2e25..1b4b85d 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_vect.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_vect.h
@@ -31,8 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */

-#ifndef _RTE_VECT_H_
-#define _RTE_VECT_H_
+#ifndef _RTE_VECT_X86_H_
+#define _RTE_VECT_X86_H_

 /**
  * @file
@@ -41,6 +41,7 @@
  */

 #include 
+#include "generic/rte_vect.h"

 #if (defined(__ICC) || (__GNUC__ == 4 &&  __GNUC_MINOR__ < 4))

@@ -133,4 +134,4 @@ __extension__ ({ \
 }
 #endif

-#endif /* _RTE_VECT_H_ */
+#endif /* _RTE_VECT_X86_H_ */
diff --git a/lib/librte_eal/common/include/generic/rte_vect.h 
b/lib/librte_eal/common/include/generic/rte_vect.h
new file mode 100644
index 000..d7b9cd9
--- /dev/null
+++ b/lib/librte_eal/common/include/generic/rte_vect.h
@@ -0,0 

[dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread Dai, Wei
Thanks to David, I will submit v3 patch to indicate correct Fixes.

> -Original Message-
> From: David Marchand [mailto:david.marchand at 6wind.com]
> Sent: Wednesday, November 16, 2016 7:24 PM
> To: Dai, Wei 
> Cc: dev at dpdk.org; Burakov, Anatoly 
> Subject: Re: [PATCH v2] eal/linuxapp: fix return value check of mknod()
> 
> Hello Wei,
> 
> On Wed, Nov 16, 2016 at 3:40 AM, Wei Dai  wrote:
> > In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c,
> > The return value of mknod() is ret, not f got by fopen().
> > So the value of ret should be checked for mknod().
> >
> > Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")
> 
> The commit you are pointing is just moving the code.
> I would incriminate f7f97c16048e ("pci: add option --create-uio-dev to run
> without hotplug")
> 
> The rest looks good to me.
> 
> 
> --
> David Marchand


[dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread Dai, Wei
Thanks to Yigit Ferruh and Wenzhuo for your guide.
Several months ago, I download checkpatch.pl and put it in /root/bin/.
In /root/.bash_profile in my server,  there is line :export 
DPDK_CHECKPATCH_PATH=/root/bin/checkpatch.pl
Before I send this patch, I have run checkpath.sh to check it and it show no 
error.
./scripts/checkpatch.sh -v v2-0001-eal-*.patch

By search ' != 0', there are many lines in many modules of DPDK.
So I think ' !=0' is OK.

> -Original Message-
> From: Yigit, Ferruh
> Sent: Wednesday, November 16, 2016 7:04 PM
> To: Lu, Wenzhuo ; Dai, Wei ;
> dev at dpdk.org; Burakov, Anatoly ;
> david.marchand at 6wind.com
> Subject: Re: [dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of
> mknod()
> 
> Hi Wenzhuo,
> 
> On 11/16/2016 3:28 AM, Lu, Wenzhuo wrote:
> > Hi Wei,
> >
> >> -Original Message-
> >> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Wei Dai
> >> Sent: Wednesday, November 16, 2016 10:41 AM
> >> To: dev at dpdk.org; Burakov, Anatoly; david.marchand at 6wind.com; Dai,
> >> Wei
> >> Subject: [dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check
> >> of mknod()
> >>
> >> In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c,
> >> The return value of mknod() is ret, not f got by fopen().
> >> So the value of ret should be checked for mknod().
> >>
> >> Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")
> >>
> >> Signed-off-by: Wei Dai 
> >> ---
> >> fix my local git setting and send same patch again to make merging
> >> easier
> >>
> >>  lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
> >>  1 file changed, 1 insertion(+), 1 deletion(-)
> >>
> >> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> >> b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> >> index 1786b75..3e4ffb5 100644
> >> --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> >> +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> >> @@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path,
> >> unsigned uio_num)
> >>snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
> >>dev = makedev(major, minor);
> >>ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
> >> -  if (f == NULL) {
> >> +  if (ret != 0) {
> > I think checkpatch will suggest to just use if (ret)
> 
> Your are right, default checkpatch.pl complains about this usage (with 
> --strict
> option), but:
> 
> - According DPDK coding style this usage is preferred (although I personally
> prefer kernel one..)
> 
> http://dpdk.org/doc/guides/contributing/coding_style.html#null-pointers
> 
> "
> if (p == NULL) /* Good, compare pointer to NULL */
> 
> if (!p) /* Bad, using ! on pointer */
> "
> 
> - This warning disabled in dpdk scripts/checkpatches.sh by "--ignore
> COMPARISON_TO_NULL", so it shouldn't complain.
> 
> 



[dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread David Marchand
Hello Wei,

On Wed, Nov 16, 2016 at 3:40 AM, Wei Dai  wrote:
> In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c,
> The return value of mknod() is ret, not f got by fopen().
> So the value of ret should be checked for mknod().
>
> Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")

The commit you are pointing is just moving the code.
I would incriminate f7f97c16048e ("pci: add option --create-uio-dev to
run without hotplug")

The rest looks good to me.


-- 
David Marchand


[dpdk-dev] [PATCH] cryptodev: fix crash on null dereference

2016-11-16 Thread Kusztal, ArkadiuszX


> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Jerin Jacob
> Sent: Tuesday, November 15, 2016 7:12 PM
> To: dev at dpdk.org
> Cc: Doherty, Declan ; Jerin Jacob
> 
> Subject: [dpdk-dev] [PATCH] cryptodev: fix crash on null dereference
> 
> crypodev->data->name will be null when
> rte_cryptodev_get_dev_id() invoked without a valid crypto device instance.
> 
> Signed-off-by: Jerin Jacob 
> ---
>  lib/librte_cryptodev/rte_cryptodev.c | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> --
> 2.5.5
Acked-by: Arek Kusztal 


[dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread Ferruh Yigit
Hi Wenzhuo,

On 11/16/2016 3:28 AM, Lu, Wenzhuo wrote:
> Hi Wei,
> 
>> -Original Message-
>> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Wei Dai
>> Sent: Wednesday, November 16, 2016 10:41 AM
>> To: dev at dpdk.org; Burakov, Anatoly; david.marchand at 6wind.com; Dai, Wei
>> Subject: [dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of 
>> mknod()
>>
>> In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c, The 
>> return
>> value of mknod() is ret, not f got by fopen().
>> So the value of ret should be checked for mknod().
>>
>> Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")
>>
>> Signed-off-by: Wei Dai 
>> ---
>> fix my local git setting and send same patch again to make merging easier
>>
>>  lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
>>  1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>> b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>> index 1786b75..3e4ffb5 100644
>> --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>> +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
>> @@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path,
>> unsigned uio_num)
>>  snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
>>  dev = makedev(major, minor);
>>  ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
>> -if (f == NULL) {
>> +if (ret != 0) {
> I think checkpatch will suggest to just use if (ret)

Your are right, default checkpatch.pl complains about this usage (with
--strict option), but:

- According DPDK coding style this usage is preferred (although I
personally prefer kernel one..)

http://dpdk.org/doc/guides/contributing/coding_style.html#null-pointers

"
if (p == NULL) /* Good, compare pointer to NULL */

if (!p) /* Bad, using ! on pointer */
"

- This warning disabled in dpdk scripts/checkpatches.sh by "--ignore
COMPARISON_TO_NULL", so it shouldn't complain.





[dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread Wei Dai
In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c,
The return value of mknod() is ret, not f got by fopen().
So the value of ret should be checked for mknod().

Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")

Signed-off-by: Wei Dai 
---
fix my local git setting and send same patch again to
make merging easier

 lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c 
b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..3e4ffb5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned 
uio_num)
snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
dev = makedev(major, minor);
ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-   if (f == NULL) {
+   if (ret != 0) {
RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
__func__, strerror(errno));
return -1;
-- 
2.5.5



[dpdk-dev] Clarification for eth_driver changes

2016-11-16 Thread Shreyansh Jain
On Monday 14 November 2016 11:08 PM, Ferruh Yigit wrote:
[...]
> What I was thinking is:
>
> rte_device/driver are not abstract classes.
>
> rte_bus device/driver is an abstract class and any bus inherited from
> this class.
> rte_func device/driver is and abstract class and eth/crypto inherited
> from this class.
>
> eal layer only deal with rte_bus
> pmd's only deal with functional device/driver
>
> but still, it is required to know device <-> driver, and functional <->
> bus, relations. rte_dev/rte_driver are to provide this links.
>
> But yes this add extra layer and with second thought I am not sure if it
> is really possible to separate bus and functionality, this was just an
> idea ..
[...]

I understand your point. It would really nice if we can achieve that 
level pluggable-ness where drivers would be able to choose a 'profile' - 
where 'profiles' are like net/crypto etc. In your text, 
profile==functionality.

Maybe once the basic model is in place, we can revisit this idea.

-
Shreyansh


[dpdk-dev] [PATCH] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread Zhiyong Yang
From: Wei Dai 

In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c,
The return value of mknod() is ret, not f got by fopen().
So the value of ret should be checked for mknod().

Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")

Signed-off-by: Wei Dai 
---
 lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c 
b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..3e4ffb5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path, unsigned 
uio_num)
snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
dev = makedev(major, minor);
ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
-   if (f == NULL) {
+   if (ret != 0) {
RTE_LOG(ERR, EAL, "%s(): mknod() failed %s\n",
__func__, strerror(errno));
return -1;
-- 
2.5.5



[dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()

2016-11-16 Thread Lu, Wenzhuo
Hi Wei,

> -Original Message-
> From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Wei Dai
> Sent: Wednesday, November 16, 2016 10:41 AM
> To: dev at dpdk.org; Burakov, Anatoly; david.marchand at 6wind.com; Dai, Wei
> Subject: [dpdk-dev] [PATCH v2] eal/linuxapp: fix return value check of mknod()
> 
> In function pci_mknod_uio_dev() in lib/librte_eal/eal/eal_pci_uio.c, The 
> return
> value of mknod() is ret, not f got by fopen().
> So the value of ret should be checked for mknod().
> 
> Fixes: 67c536bdad93 ("pci: move uio mapping in a dedicated file")
> 
> Signed-off-by: Wei Dai 
> ---
> fix my local git setting and send same patch again to make merging easier
> 
>  lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> index 1786b75..3e4ffb5 100644
> --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
> @@ -133,7 +133,7 @@ pci_mknod_uio_dev(const char *sysfs_uio_path,
> unsigned uio_num)
>   snprintf(filename, sizeof(filename), "/dev/uio%u", uio_num);
>   dev = makedev(major, minor);
>   ret = mknod(filename, S_IFCHR | S_IRUSR | S_IWUSR, dev);
> - if (f == NULL) {
> + if (ret != 0) {
I think checkpatch will suggest to just use if (ret)



[dpdk-dev] [PATCH] cryptodev: fix crash on null dereference

2016-11-16 Thread Jerin Jacob
crypodev->data->name will be null when
rte_cryptodev_get_dev_id() invoked without a valid
crypto device instance.

Signed-off-by: Jerin Jacob 
---
 lib/librte_cryptodev/rte_cryptodev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/librte_cryptodev/rte_cryptodev.c 
b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0..54e95d5 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -225,13 +225,14 @@ rte_cryptodev_create_vdev(const char *name, const char 
*args)
 }

 int
-rte_cryptodev_get_dev_id(const char *name) {
+rte_cryptodev_get_dev_id(const char *name)
+{
unsigned i;

if (name == NULL)
return -1;

-   for (i = 0; i < rte_cryptodev_globals->max_devs; i++)
+   for (i = 0; i < rte_cryptodev_globals->nb_devs; i++)
if ((strcmp(rte_cryptodev_globals->devs[i].data->name, name)
== 0) &&
(rte_cryptodev_globals->devs[i].attached ==
-- 
2.5.5