From mboxrd@z Thu Jan 1 00:00:00 1970 From: Pascal Mazon Subject: [PATCH 2/4] net/tap: add preliminary support for rte_flow Date: Fri, 3 Mar 2017 11:45:55 +0100 Message-ID: <60e59987d174810bf7b0c8e49e2767907f321d4d.1488537600.git.pascal.mazon@6wind.com> References: Cc: dev@dpdk.org, Pascal Mazon To: keith.wiles@intel.com Return-path: Received: from proxy.6wind.com (host.76.145.23.62.rev.coltfrance.com [62.23.145.76]) by dpdk.org (Postfix) with ESMTP id CFE932B93 for ; Fri, 3 Mar 2017 11:46:12 +0100 (CET) In-Reply-To: List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The flow API provides the ability to classify packets received by a tap netdevice. This patch only implements skeleton functions for flow API support, no patterns are supported yet. Signed-off-by: Pascal Mazon Acked-by: Olga Shern --- doc/guides/nics/features/tap.ini | 1 + drivers/net/tap/Makefile | 1 + drivers/net/tap/rte_eth_tap.c | 6 ++ drivers/net/tap/tap.h | 2 + drivers/net/tap/tap_flow.c | 185 +++++++++++++++++++++++++++++++++++++++ drivers/net/tap/tap_flow.h | 46 ++++++++++ 6 files changed, 241 insertions(+) create mode 100644 drivers/net/tap/tap_flow.c create mode 100644 drivers/net/tap/tap_flow.h diff --git a/doc/guides/nics/features/tap.ini b/doc/guides/nics/features/tap.ini index a51712dce066..9d73f61cca3b 100644 --- a/doc/guides/nics/features/tap.ini +++ b/doc/guides/nics/features/tap.ini @@ -9,6 +9,7 @@ Jumbo frame = Y Promiscuous mode = Y Allmulticast mode = Y Basic stats = Y +Flow API = Y MTU update = Y Multicast MAC filter = Y Speed capabilities = Y diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile index bdbe69e62a4e..386b8b0594d3 100644 --- a/drivers/net/tap/Makefile +++ b/drivers/net/tap/Makefile @@ -47,6 +47,7 @@ CFLAGS += $(WERROR_FLAGS) # all source are stored in SRCS-y # SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c +SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c # this lib depends upon: DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += lib/librte_eal diff --git a/drivers/net/tap/rte_eth_tap.c b/drivers/net/tap/rte_eth_tap.c index fa57d645f3b1..e80de0c29377 100644 --- a/drivers/net/tap/rte_eth_tap.c +++ b/drivers/net/tap/rte_eth_tap.c @@ -52,6 +52,7 @@ #include #include +#include /* Linux based path to the TUN device */ #define TUN_TAP_DEV_PATH "/dev/net/tun" @@ -788,6 +789,7 @@ static const struct eth_dev_ops ops = { .stats_get = tap_stats_get, .stats_reset = tap_stats_reset, .dev_supported_ptypes_get = tap_dev_supported_ptypes_get, + .filter_ctrl = tap_dev_filter_ctrl, }; static int @@ -850,6 +852,8 @@ eth_dev_tap_create(const char *name, char *tap_name) pmd->txq[i].fd = -1; } + LIST_INIT(&pmd->flows); + return 0; error_exit: @@ -962,6 +966,8 @@ rte_pmd_tap_remove(const char *name) if (!eth_dev) return 0; + tap_flow_flush(eth_dev, NULL); + internals = eth_dev->data->dev_private; for (i = 0; i < internals->nb_queues; i++) if (internals->rxq[i].fd != -1) diff --git a/drivers/net/tap/tap.h b/drivers/net/tap/tap.h index 88f62b895feb..323f5705a324 100644 --- a/drivers/net/tap/tap.h +++ b/drivers/net/tap/tap.h @@ -34,6 +34,7 @@ #ifndef _TAP_H_ #define _TAP_H_ +#include #include #include @@ -66,6 +67,7 @@ struct pmd_internals { uint16_t nb_queues; /* Number of queues supported */ struct ether_addr eth_addr; /* Mac address of the device port */ int if_index; /* IF_INDEX for the port */ + LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */ struct rx_queue rxq[RTE_PMD_TAP_MAX_QUEUES]; /* List of RX queues */ struct tx_queue txq[RTE_PMD_TAP_MAX_QUEUES]; /* List of TX queues */ }; diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c new file mode 100644 index 000000000000..de41c127c920 --- /dev/null +++ b/drivers/net/tap/tap_flow.c @@ -0,0 +1,185 @@ +/*- + * BSD LICENSE + * + * Copyright 2017 6WIND S.A. + * Copyright 2017 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 + +struct rte_flow { + LIST_ENTRY(rte_flow) next; /* Pointer to the next rte_flow structure */ +}; + +static int +tap_flow_validate(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error); + +static struct rte_flow * +tap_flow_create(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error); + +static int +tap_flow_destroy(struct rte_eth_dev *dev, + struct rte_flow *flow, + struct rte_flow_error *error); + +static const struct rte_flow_ops tap_flow_ops = { + .validate = tap_flow_validate, + .create = tap_flow_create, + .destroy = tap_flow_destroy, + .flush = tap_flow_flush, +}; + +/** + * Validate a flow. + * + * @see rte_flow_validate() + * @see rte_flow_ops + */ +static int +tap_flow_validate(struct rte_eth_dev *dev __rte_unused, + const struct rte_flow_attr *attr __rte_unused, + const struct rte_flow_item items[] __rte_unused, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error) +{ + return -rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, "not implemented yet"); +} + +/** + * Create a flow. + * + * @see rte_flow_create() + * @see rte_flow_ops + */ +static struct rte_flow * +tap_flow_create(struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_flow_item items[], + const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + struct pmd_internals *pmd = dev->data->dev_private; + struct rte_flow *flow = NULL; + + if (tap_flow_validate(dev, attr, items, actions, error)) + return NULL; + flow = rte_malloc(__func__, sizeof(struct rte_flow), 0); + if (!flow) { + rte_flow_error_set(error, ENOMEM, RTE_FLOW_ERROR_TYPE_HANDLE, + NULL, "cannot allocate memory for rte_flow"); + return NULL; + } + LIST_INSERT_HEAD(&pmd->flows, flow, next); + return flow; +} + +/** + * Destroy a flow. + * + * @see rte_flow_destroy() + * @see rte_flow_ops + */ +static int +tap_flow_destroy(struct rte_eth_dev *dev __rte_unused, + struct rte_flow *flow, + struct rte_flow_error *error __rte_unused) +{ + LIST_REMOVE(flow, next); + rte_free(flow); + return 0; +} + +/** + * Destroy all flows. + * + * @see rte_flow_flush() + * @see rte_flow_ops + */ +int +tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error) +{ + struct pmd_internals *pmd = dev->data->dev_private; + struct rte_flow *flow; + + while (!LIST_EMPTY(&pmd->flows)) { + flow = LIST_FIRST(&pmd->flows); + if (tap_flow_destroy(dev, flow, error) < 0) + return -1; + } + return 0; +} + +/** + * Manage filter operations. + * + * @param dev + * Pointer to Ethernet device structure. + * @param filter_type + * Filter type. + * @param filter_op + * Operation to perform. + * @param arg + * Pointer to operation-specific structure. + * + * @return + * 0 on success, negative errno value on failure. + */ +int +tap_dev_filter_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg) +{ + switch (filter_type) { + case RTE_ETH_FILTER_GENERIC: + if (filter_op != RTE_ETH_FILTER_GET) + return -EINVAL; + *(const void **)arg = &tap_flow_ops; + return 0; + default: + RTE_LOG(ERR, PMD, "%p: filter type (%d) not supported", + (void *)dev, filter_type); + } + return -EINVAL; +} + diff --git a/drivers/net/tap/tap_flow.h b/drivers/net/tap/tap_flow.h new file mode 100644 index 000000000000..377a9f7b758a --- /dev/null +++ b/drivers/net/tap/tap_flow.h @@ -0,0 +1,46 @@ +/*- + * BSD LICENSE + * + * Copyright 2017 6WIND S.A. + * Copyright 2017 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. + */ + +#ifndef _TAP_FLOW_H_ +#define _TAP_FLOW_H_ + +#include +#include + +int tap_dev_filter_ctrl(struct rte_eth_dev *dev, + enum rte_filter_type filter_type, + enum rte_filter_op filter_op, + void *arg); +int tap_flow_flush(struct rte_eth_dev *dev, struct rte_flow_error *error); + +#endif /* _TAP_FLOW_H_ */ -- 2.8.0.rc0