* [dpdk-dev] [PATCH v4 1/4] ethdev: add ethdev APIs for NIC filters of generic filter
2014-06-16 7:31 [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Jingjing Wu
@ 2014-06-16 7:31 ` Jingjing Wu
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 2/4] e1000: add igb NIC filters of generic filter feature Jingjing Wu
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jingjing Wu @ 2014-06-16 7:31 UTC (permalink / raw)
To: dev
This patch adds APIs for NIC filters list below:
ethertype filter, syn filter, 2tuple filter, flex filter, 5tuple filter
Signed-off-by: jingjing.wu <jingjing.wu@intel.com>
---
lib/librte_ether/rte_ethdev.c | 275 +++++++++++++++++++++++++++
lib/librte_ether/rte_ethdev.h | 428 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 703 insertions(+)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 8011b8b..42333ee 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -41,6 +41,7 @@
#include <errno.h>
#include <stdint.h>
#include <inttypes.h>
+#include <netinet/in.h>
#include <rte_byteorder.h>
#include <rte_log.h>
@@ -2606,3 +2607,277 @@ rte_eth_dev_bypass_wd_reset(uint8_t port_id)
return 0;
}
#endif
+
+int
+rte_eth_dev_add_syn_filter(uint8_t port_id,
+ struct rte_syn_filter *filter, uint16_t rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_syn_filter, -ENOTSUP);
+ return (*dev->dev_ops->add_syn_filter)(dev, filter, rx_queue);
+}
+
+int
+rte_eth_dev_remove_syn_filter(uint8_t port_id)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_syn_filter, -ENOTSUP);
+ return (*dev->dev_ops->remove_syn_filter)(dev);
+}
+
+int
+rte_eth_dev_get_syn_filter(uint8_t port_id,
+ struct rte_syn_filter *filter, uint16_t *rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (filter == NULL || rx_queue == NULL)
+ return -EINVAL;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_syn_filter, -ENOTSUP);
+ return (*dev->dev_ops->get_syn_filter)(dev, filter, rx_queue);
+}
+
+int
+rte_eth_dev_add_ethertype_filter(uint8_t port_id, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+ if (filter->ethertype == ETHER_TYPE_IPv4 ||
+ filter->ethertype == ETHER_TYPE_IPv6){
+ PMD_DEBUG_TRACE("IP and IPv6 are not supported"
+ " in ethertype filter\n");
+ return -EINVAL;
+ }
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_ethertype_filter, -ENOTSUP);
+ return (*dev->dev_ops->add_ethertype_filter)(dev, index,
+ filter, rx_queue);
+}
+
+int
+rte_eth_dev_remove_ethertype_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_ethertype_filter, -ENOTSUP);
+ return (*dev->dev_ops->remove_ethertype_filter)(dev, index);
+}
+
+int
+rte_eth_dev_get_ethertype_filter(uint8_t port_id, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t *rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (filter == NULL || rx_queue == NULL)
+ return -EINVAL;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_ethertype_filter, -ENOTSUP);
+ return (*dev->dev_ops->get_ethertype_filter)(dev, index,
+ filter, rx_queue);
+}
+
+int
+rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+ if (filter->protocol != IPPROTO_TCP &&
+ filter->tcp_flags != 0){
+ PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
+ " is not TCP\n",
+ filter->tcp_flags);
+ return -EINVAL;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_2tuple_filter, -ENOTSUP);
+ return (*dev->dev_ops->add_2tuple_filter)(dev, index, filter, rx_queue);
+}
+
+int
+rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_2tuple_filter, -ENOTSUP);
+ return (*dev->dev_ops->remove_2tuple_filter)(dev, index);
+}
+
+int
+rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t *rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (filter == NULL || rx_queue == NULL)
+ return -EINVAL;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_2tuple_filter, -ENOTSUP);
+ return (*dev->dev_ops->get_2tuple_filter)(dev, index, filter, rx_queue);
+}
+
+int
+rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ if (filter->protocol != IPPROTO_TCP &&
+ filter->tcp_flags != 0){
+ PMD_DEBUG_TRACE("tcp flags is 0x%x, but the protocol value"
+ " is not TCP\n",
+ filter->tcp_flags);
+ return -EINVAL;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_5tuple_filter, -ENOTSUP);
+ return (*dev->dev_ops->add_5tuple_filter)(dev, index, filter, rx_queue);
+}
+
+int
+rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_5tuple_filter, -ENOTSUP);
+ return (*dev->dev_ops->remove_5tuple_filter)(dev, index);
+}
+
+int
+rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t *rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (filter == NULL || rx_queue == NULL)
+ return -EINVAL;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_5tuple_filter, -ENOTSUP);
+ return (*dev->dev_ops->get_5tuple_filter)(dev, index, filter,
+ rx_queue);
+}
+
+int
+rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
+ struct rte_flex_filter *filter, uint16_t rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->add_flex_filter, -ENOTSUP);
+ return (*dev->dev_ops->add_flex_filter)(dev, index, filter, rx_queue);
+}
+
+int
+rte_eth_dev_remove_flex_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_eth_dev *dev;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->remove_flex_filter, -ENOTSUP);
+ return (*dev->dev_ops->remove_flex_filter)(dev, index);
+}
+
+int
+rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
+ struct rte_flex_filter *filter, uint16_t *rx_queue)
+{
+ struct rte_eth_dev *dev;
+
+ if (filter == NULL || rx_queue == NULL)
+ return -EINVAL;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return -ENODEV;
+ }
+
+ dev = &rte_eth_devices[port_id];
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->get_flex_filter, -ENOTSUP);
+ return (*dev->dev_ops->get_flex_filter)(dev, index, filter,
+ rx_queue);
+}
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 67eda50..38ae0b8 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -813,6 +813,73 @@ struct rte_eth_dev_callback;
/** @internal Structure to keep track of registered callbacks */
TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
+#define TCP_UGR_FLAG 0x20
+#define TCP_ACK_FLAG 0x10
+#define TCP_PSH_FLAG 0x08
+#define TCP_RST_FLAG 0x04
+#define TCP_SYN_FLAG 0x02
+#define TCP_FIN_FLAG 0x01
+#define TCP_FLAG_ALL 0x3F
+
+/**
+ * A structure used to define an ethertype filter.
+ */
+struct rte_ethertype_filter {
+ uint16_t ethertype; /**< little endian. */
+ uint8_t priority_en; /**< compare priority enable. */
+ uint8_t priority;
+};
+
+/**
+ * A structure used to define an syn filter.
+ */
+struct rte_syn_filter {
+ uint8_t hig_pri; /**< 1 means higher pri than 2tuple, 5tupe,
+ and flex filter, 0 means lower pri. */
+};
+
+/**
+ * A structure used to define a 2tuple filter.
+ */
+struct rte_2tuple_filter {
+ uint16_t dst_port; /**< big endian. */
+ uint8_t protocol;
+ uint8_t tcp_flags;
+ uint16_t priority; /**< used when more than one filter matches. */
+ uint8_t dst_port_mask:1, /**< if mask is 1b, means not compare. */
+ protocol_mask:1;
+};
+
+/**
+ * A structure used to define a flex filter.
+ */
+struct rte_flex_filter {
+ uint16_t len;
+ uint32_t dwords[32]; /**< flex bytes in big endian. */
+ uint8_t mask[16]; /**< if mask bit is 1b, do not compare
+ corresponding byte in dwords. */
+ uint8_t priority;
+};
+
+/**
+ * A structure used to define a 5tuple filter.
+ */
+struct rte_5tuple_filter {
+ uint32_t dst_ip; /**< destination IP address in big endian. */
+ uint32_t src_ip; /**< source IP address in big endian. */
+ uint16_t dst_port; /**< destination port in big endian. */
+ uint16_t src_port; /**< source Port big endian. */
+ uint8_t protocol; /**< l4 protocol. */
+ uint8_t tcp_flags; /**< tcp flags. */
+ uint16_t priority; /**< seven evels (001b-111b), 111b is highest,
+ used when more than one filter matches. */
+ uint8_t dst_ip_mask:1, /**< if mask is 1b, do not compare dst ip. */
+ src_ip_mask:1, /**< if mask is 1b, do not compare src ip. */
+ dst_port_mask:1, /**< if mask is 1b, do not compare dst port. */
+ src_port_mask:1, /**< if mask is 1b, do not compare src port. */
+ protocol_mask:1; /**< if mask is 1b, do not compare protocol. */
+};
+
/*
* Definitions of all functions exported by an Ethernet driver through the
* the generic structure of type *eth_dev_ops* supplied in the *rte_eth_dev*
@@ -1114,6 +1181,72 @@ typedef int32_t (*bypass_ver_show_t)(struct rte_eth_dev *dev, uint32_t *ver);
typedef int32_t (*bypass_wd_reset_t)(struct rte_eth_dev *dev);
#endif
+typedef int (*eth_add_syn_filter_t)(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t rx_queue);
+/**< @internal add syn filter rule on an Ethernet device */
+
+typedef int (*eth_remove_syn_filter_t)(struct rte_eth_dev *dev);
+/**< @internal remove syn filter rule on an Ethernet device */
+
+typedef int (*eth_get_syn_filter_t)(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t *rx_queue);
+/**< @internal Get syn filter rule on an Ethernet device */
+
+typedef int (*eth_add_ethertype_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_ethertype_filter *filter,
+ uint16_t rx_queue);
+/**< @internal Setup a new ethertype filter rule on an Ethernet device */
+
+typedef int (*eth_remove_ethertype_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index);
+/**< @internal Remove an ethertype filter rule on an Ethernet device */
+
+typedef int (*eth_get_ethertype_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_ethertype_filter *filter,
+ uint16_t *rx_queue);
+/**< @internal Get an ethertype filter rule on an Ethernet device */
+
+typedef int (*eth_add_2tuple_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_2tuple_filter *filter,
+ uint16_t rx_queue);
+/**< @internal Setup a new 2tuple filter rule on an Ethernet device */
+
+typedef int (*eth_remove_2tuple_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index);
+/**< @internal Remove a 2tuple filter rule on an Ethernet device */
+
+typedef int (*eth_get_2tuple_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_2tuple_filter *filter,
+ uint16_t *rx_queue);
+/**< @internal Get a 2tuple filter rule on an Ethernet device */
+
+typedef int (*eth_add_5tuple_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_5tuple_filter *filter,
+ uint16_t rx_queue);
+/**< @internal Setup a new 5tuple filter rule on an Ethernet device */
+
+typedef int (*eth_remove_5tuple_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index);
+/**< @internal Remove a 5tuple filter rule on an Ethernet device */
+
+typedef int (*eth_get_5tuple_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_5tuple_filter *filter,
+ uint16_t *rx_queue);
+/**< @internal Get a 5tuple filter rule on an Ethernet device */
+
+typedef int (*eth_add_flex_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_flex_filter *filter,
+ uint16_t rx_queue);
+/**< @internal Setup a new flex filter rule on an Ethernet device */
+
+typedef int (*eth_remove_flex_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index);
+/**< @internal Remove a flex filter rule on an Ethernet device */
+
+typedef int (*eth_get_flex_filter_t)(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_flex_filter *filter,
+ uint16_t *rx_queue);
+/**< @internal Get a flex filter rule on an Ethernet device */
/**
* @internal A structure containing the functions exported by an Ethernet driver.
@@ -1203,6 +1336,21 @@ struct eth_dev_ops {
rss_hash_update_t rss_hash_update;
/** Get current RSS hash configuration. */
rss_hash_conf_get_t rss_hash_conf_get;
+ eth_add_syn_filter_t add_syn_filter; /**< add syn filter. */
+ eth_remove_syn_filter_t remove_syn_filter; /**< remove syn filter. */
+ eth_get_syn_filter_t get_syn_filter; /**< get syn filter. */
+ eth_add_ethertype_filter_t add_ethertype_filter; /**< add ethertype filter. */
+ eth_remove_ethertype_filter_t remove_ethertype_filter; /**< remove ethertype filter. */
+ eth_get_ethertype_filter_t get_ethertype_filter; /**< get ethertype filter. */
+ eth_add_2tuple_filter_t add_2tuple_filter; /**< add 2tuple filter. */
+ eth_remove_2tuple_filter_t remove_2tuple_filter; /**< remove 2tuple filter. */
+ eth_get_2tuple_filter_t get_2tuple_filter; /**< get 2tuple filter. */
+ eth_add_5tuple_filter_t add_5tuple_filter; /**< add 5tuple filter. */
+ eth_remove_5tuple_filter_t remove_5tuple_filter; /**< remove 5tuple filter. */
+ eth_get_5tuple_filter_t get_5tuple_filter; /**< get 5tuple filter. */
+ eth_add_flex_filter_t add_flex_filter; /**< add flex filter. */
+ eth_remove_flex_filter_t remove_flex_filter; /**< remove flex filter. */
+ eth_get_flex_filter_t get_flex_filter; /**< get flex filter. */
};
/**
@@ -2937,6 +3085,286 @@ int
rte_eth_dev_rss_hash_conf_get(uint8_t port_id,
struct rte_eth_rss_conf *rss_conf);
+/**
+ * add syn filter
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param rx_queue
+ * The index of RX queue where to store RX packets matching the syn filter.
+ * @param filter
+ * The pointer to the structure describing the syn filter rule.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_eth_dev_add_syn_filter(uint8_t port_id,
+ struct rte_syn_filter *filter, uint16_t rx_queue);
+
+/**
+ * remove syn filter
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_eth_dev_remove_syn_filter(uint8_t port_id);
+
+/**
+ * get syn filter
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param filter
+ * The pointer to the structure describing the syn filter.
+ * @param rx_queue
+ * the point of a int type to get the queue of syn filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support.
+ * - (-EINVAL) if bad parameter.
+ */
+int rte_eth_dev_get_syn_filter(uint8_t port_id,
+ struct rte_syn_filter *filter, uint16_t *rx_queue);
+
+/**
+ * Add a new ethertype filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of ethertype filter.
+ * @param filter
+ * The pointer to the structure describing the ethertype filter rule.
+ * The *rte_ethertype_filter* structure includes the values of the different
+ * fields to match: ethertype and priority in vlan tag.
+ * priority in vlan tag is not supported for E1000 dev.
+ * @param rx_queue
+ * The index of the RX queue where to store RX packets matching the added
+ * ethertype filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support ethertype filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+int rte_eth_dev_add_ethertype_filter(uint8_t port_id, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t rx_queue);
+/**
+ * remove an ethertype filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of ethertype filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support ethertype filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+int rte_eth_dev_remove_ethertype_filter(uint8_t port_id,
+ uint16_t index);
+
+/**
+ * Get an ethertype filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of ethertype filter.
+ * @param filter
+ * A pointer to a structure of type *rte_ethertype_filter* to be filled with
+ * the information of the Ethertype filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support ethertype filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ * - (-ENOENT) if no enabled filter in this index.
+ */
+
+int rte_eth_dev_get_ethertype_filter(uint8_t port_id, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t *rx_queue);
+/**
+ * Add a new 2tuple filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of 2tuple filter.
+ * @param filter
+ * The pointer to the structure describing the 2tuple filter rule.
+ * The *rte_2tuple_filter* structure includes the values of the different
+ * fields to match: protocol, dst_port and
+ * tcp_flags if the protocol is tcp type.
+ * @param rx_queue
+ * The index of the RX queue where to store RX packets matching the added
+ * 2tuple filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support 2tuple filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+
+int rte_eth_dev_add_2tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t rx_queue);
+/**
+ * remove a 2tuple filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of 2tuple filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support 2tuple filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+int rte_eth_dev_remove_2tuple_filter(uint8_t port_id, uint16_t index);
+
+/**
+ * Get an 2tuple filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of 2tuple filter.
+ * @param filter
+ * A pointer to a structure of type *rte_2tuple_filter* to be filled with
+ * the information of the 2tuple filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support 2tuple filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ * - (-ENOENT) if no enabled filter in this index.
+ */
+int rte_eth_dev_get_2tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t *rx_queue);
+
+/**
+ * Add a new 5tuple filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of 5tuple filter.
+ * @param filter
+ * The pointer to the structure describing the 5tuple filter rule.
+ * The *rte_5tuple_filter* structure includes the values of the different
+ * fields to match: dst src IP, dst src port, protocol and relative masks
+ * @param rx_queue
+ * The index of the RX queue where to store RX packets matching the added
+ * 5tuple filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support 5tuple filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+int rte_eth_dev_add_5tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t rx_queue);
+
+/**
+ * remove a 5tuple filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of 5tuple filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support 5tuple filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+int rte_eth_dev_remove_5tuple_filter(uint8_t port_id, uint16_t index);
+
+/**
+ * Get an 5tuple filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of 5tuple filter.
+ * @param filter
+ * A pointer to a structure of type *rte_5tuple_filter* to be filled with
+ * the information of the 5tuple filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support 5tuple filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+int rte_eth_dev_get_5tuple_filter(uint8_t port_id, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t *rx_queue);
+
+/**
+ * Add a new flex filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of flex filter.
+ * @param filter
+ * The pointer to the structure describing the flex filter rule.
+ * The *rte_flex_filter* structure includes the values of the different fields
+ * to match: the dwords (first len bytes of packet ) and relative masks.
+ * @param rx_queue
+ * The index of the RX queue where to store RX packets matching the added
+ * flex filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support flex filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ * - (-ENOENT) if no enabled filter in this index.
+ */
+int rte_eth_dev_add_flex_filter(uint8_t port_id, uint16_t index,
+ struct rte_flex_filter *filter, uint16_t rx_queue);
+/**
+ * remove a flex filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of flex filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support flex filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ */
+int rte_eth_dev_remove_flex_filter(uint8_t port_id, uint16_t index);
+
+/**
+ * Get an flex filter rule on an Ethernet device.
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param index
+ * The identifier of flex filter.
+ * @param filter
+ * A pointer to a structure of type *rte_flex_filter* to be filled with
+ * the information of the flex filter.
+ * @return
+ * - (0) if successful.
+ * - (-ENOTSUP) if hardware doesn't support flex filter.
+ * - (-ENODEV) if *port_id* invalid.
+ * - (-EINVAL) if the filter information is not correct.
+ * - (-ENOENT) if no enabled filter in this index.
+ */
+
+int rte_eth_dev_get_flex_filter(uint8_t port_id, uint16_t index,
+ struct rte_flex_filter *filter, uint16_t *rx_queue);
+
#ifdef __cplusplus
}
#endif
--
1.8.1.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v4 2/4] e1000: add igb NIC filters of generic filter feature
2014-06-16 7:31 [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Jingjing Wu
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 1/4] ethdev: add ethdev APIs for NIC filters of " Jingjing Wu
@ 2014-06-16 7:31 ` Jingjing Wu
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 3/4] ixgbe: add ixgbe " Jingjing Wu
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jingjing Wu @ 2014-06-16 7:31 UTC (permalink / raw)
To: dev
This patch adds following igb NIC filters implement:
syn filter, ethertype filter, 2tuple filter, flex filter for intel NIC 82580 and i350
syn filter, ethertype filter, 5tuple filter for intel NIC 82576
Signed-off-by: jingjing.wu <jingjing.wu@intel.com>
---
lib/librte_pmd_e1000/e1000_ethdev.h | 53 +++
lib/librte_pmd_e1000/igb_ethdev.c | 768 ++++++++++++++++++++++++++++++++++++
2 files changed, 821 insertions(+)
diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index a287f40..71eb5fb 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -52,6 +52,59 @@
#define E1000_CTRL_EXT_EXTEND_VLAN (1<<26) /* EXTENDED VLAN */
#define IGB_VFTA_SIZE 128
+#define IGB_MAX_RX_QUEUE_NUM 8
+#define IGB_MAX_RX_QUEUE_NUM_82576 16
+
+#define E1000_SYN_FILTER_ENABLE 0x00000001 /* syn filter enable field */
+#define E1000_SYN_FILTER_QUEUE 0x0000000E /* syn filter queue field */
+#define E1000_SYN_FILTER_QUEUE_SHIFT 1 /* syn filter queue field */
+#define E1000_RFCTL_SYNQFP 0x00080000 /* SYNQFP in RFCTL register */
+
+#define E1000_ETQF_ETHERTYPE 0x0000FFFF
+#define E1000_ETQF_QUEUE 0x00070000
+#define E1000_ETQF_QUEUE_SHIFT 16
+#define E1000_MAX_ETQF_FILTERS 8
+
+#define E1000_IMIR_DSTPORT 0x0000FFFF
+#define E1000_IMIR_PRIORITY 0xE0000000
+#define E1000_IMIR_EXT_SIZE_BP 0x00001000
+#define E1000_IMIR_EXT_CTRL_UGR 0x00002000
+#define E1000_IMIR_EXT_CTRL_ACK 0x00004000
+#define E1000_IMIR_EXT_CTRL_PSH 0x00008000
+#define E1000_IMIR_EXT_CTRL_RST 0x00010000
+#define E1000_IMIR_EXT_CTRL_SYN 0x00020000
+#define E1000_IMIR_EXT_CTRL_FIN 0x00040000
+#define E1000_IMIR_EXT_CTRL_BP 0x00080000
+#define E1000_MAX_TTQF_FILTERS 8
+#define E1000_2TUPLE_MAX_PRI 7
+
+#define E1000_MAX_FLEXIBLE_FILTERS 8
+#define E1000_MAX_FHFT 4
+#define E1000_MAX_FHFT_EXT 4
+#define E1000_MAX_FLEX_FILTER_PRI 7
+#define E1000_MAX_FLEX_FILTER_LEN 128
+#define E1000_FHFT_QUEUEING_LEN 0x0000007F
+#define E1000_FHFT_QUEUEING_QUEUE 0x00000700
+#define E1000_FHFT_QUEUEING_PRIO 0x00070000
+#define E1000_FHFT_QUEUEING_OFFSET 0xFC
+#define E1000_FHFT_QUEUEING_QUEUE_SHIFT 8
+#define E1000_FHFT_QUEUEING_PRIO_SHIFT 16
+#define E1000_WUFC_FLEX_HQ 0x00004000
+
+#define E1000_SPQF_SRCPORT 0x0000FFFF
+
+#define E1000_MAX_FTQF_FILTERS 8
+#define E1000_FTQF_PROTOCOL_MASK 0x000000FF
+#define E1000_FTQF_5TUPLE_MASK_SHIFT 28
+#define E1000_FTQF_PROTOCOL_COMP_MASK 0x10000000
+#define E1000_FTQF_SOURCE_ADDR_MASK 0x20000000
+#define E1000_FTQF_DEST_ADDR_MASK 0x40000000
+#define E1000_FTQF_SOURCE_PORT_MASK 0x80000000
+#define E1000_FTQF_VF_MASK_EN 0x00008000
+#define E1000_FTQF_QUEUE_MASK 0x03ff0000
+#define E1000_FTQF_QUEUE_SHIFT 16
+#define E1000_FTQF_QUEUE_ENABLE 0x00000100
+
/* structure for interrupt relative data */
struct e1000_interrupt {
uint32_t flags;
diff --git a/lib/librte_pmd_e1000/igb_ethdev.c b/lib/librte_pmd_e1000/igb_ethdev.c
index 6e835c3..343a78c 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -124,6 +124,44 @@ static int eth_igb_rss_reta_update(struct rte_eth_dev *dev,
static int eth_igb_rss_reta_query(struct rte_eth_dev *dev,
struct rte_eth_rss_reta *reta_conf);
+static int eth_igb_add_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t rx_queue);
+static int eth_igb_remove_syn_filter(struct rte_eth_dev *dev);
+static int eth_igb_get_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t *rx_queue);
+static int eth_igb_add_ethertype_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t rx_queue);
+static int eth_igb_remove_ethertype_filter(struct rte_eth_dev *dev,
+ uint16_t index);
+static int eth_igb_get_ethertype_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t *rx_queue);
+static int eth_igb_add_2tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t rx_queue);
+static int eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index);
+static int eth_igb_get_2tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t *rx_queue);
+static int eth_igb_add_flex_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_flex_filter *filter, uint16_t rx_queue);
+static int eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
+ uint16_t index);
+static int eth_igb_get_flex_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_flex_filter *filter, uint16_t *rx_queue);
+static int eth_igb_add_5tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t rx_queue);
+static int eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index);
+static int eth_igb_get_5tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t *rx_queue);
+
/*
* Define VF Stats MACRO for Non "cleared on read" register
*/
@@ -196,6 +234,21 @@ static struct eth_dev_ops eth_igb_ops = {
.reta_query = eth_igb_rss_reta_query,
.rss_hash_update = eth_igb_rss_hash_update,
.rss_hash_conf_get = eth_igb_rss_hash_conf_get,
+ .add_syn_filter = eth_igb_add_syn_filter,
+ .remove_syn_filter = eth_igb_remove_syn_filter,
+ .get_syn_filter = eth_igb_get_syn_filter,
+ .add_ethertype_filter = eth_igb_add_ethertype_filter,
+ .remove_ethertype_filter = eth_igb_remove_ethertype_filter,
+ .get_ethertype_filter = eth_igb_get_ethertype_filter,
+ .add_2tuple_filter = eth_igb_add_2tuple_filter,
+ .remove_2tuple_filter = eth_igb_remove_2tuple_filter,
+ .get_2tuple_filter = eth_igb_get_2tuple_filter,
+ .add_flex_filter = eth_igb_add_flex_filter,
+ .remove_flex_filter = eth_igb_remove_flex_filter,
+ .get_flex_filter = eth_igb_get_flex_filter,
+ .add_5tuple_filter = eth_igb_add_5tuple_filter,
+ .remove_5tuple_filter = eth_igb_remove_5tuple_filter,
+ .get_5tuple_filter = eth_igb_get_5tuple_filter,
};
/*
@@ -2186,6 +2239,721 @@ eth_igb_rss_reta_query(struct rte_eth_dev *dev,
return 0;
}
+#define MAC_TYPE_FILTER_SUP(type) do {\
+ if ((type) != e1000_82580 && (type) != e1000_i350 &&\
+ (type) != e1000_82576)\
+ return -ENOSYS;\
+} while (0)
+
+/*
+ * add the syn filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_add_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t synqf, rfctl;
+
+ MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+ if (rx_queue >= IGB_MAX_RX_QUEUE_NUM)
+ return -EINVAL;
+
+ synqf = E1000_READ_REG(hw, E1000_SYNQF(0));
+ if (synqf & E1000_SYN_FILTER_ENABLE)
+ return -EINVAL;
+
+ synqf = (uint32_t)(((rx_queue << E1000_SYN_FILTER_QUEUE_SHIFT) &
+ E1000_SYN_FILTER_QUEUE) | E1000_SYN_FILTER_ENABLE);
+
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+ if (filter->hig_pri)
+ rfctl |= E1000_RFCTL_SYNQFP;
+ else
+ rfctl &= ~E1000_RFCTL_SYNQFP;
+
+ E1000_WRITE_REG(hw, E1000_SYNQF(0), synqf);
+ E1000_WRITE_REG(hw, E1000_RFCTL, rfctl);
+ return 0;
+}
+
+/*
+ * remove the syn filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_remove_syn_filter(struct rte_eth_dev *dev)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+ E1000_WRITE_REG(hw, E1000_SYNQF(0), 0);
+ return 0;
+}
+
+
+/*
+ * get the syn filter's info
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * filter: ponter to the filter that returns.
+ * *rx_queue: pointer to the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_get_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t *rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t synqf, rfctl;
+
+ MAC_TYPE_FILTER_SUP(hw->mac.type);
+ synqf = E1000_READ_REG(hw, E1000_SYNQF(0));
+ if (synqf & E1000_SYN_FILTER_ENABLE) {
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+ filter->hig_pri = (rfctl & E1000_RFCTL_SYNQFP) ? 1 : 0;
+ *rx_queue = (uint8_t)((synqf & E1000_SYN_FILTER_QUEUE) >>
+ E1000_SYN_FILTER_QUEUE_SHIFT);
+ return 0;
+ }
+ return -ENOENT;
+}
+
+/*
+ * add an ethertype filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t etqf;
+
+ MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+ if (index >= E1000_MAX_ETQF_FILTERS || rx_queue >= IGB_MAX_RX_QUEUE_NUM)
+ return -EINVAL;
+
+ etqf = E1000_READ_REG(hw, E1000_ETQF(index));
+ if (etqf & E1000_ETQF_FILTER_ENABLE)
+ return -EINVAL; /* filter index is in use. */
+ else
+ etqf = 0;
+
+ etqf |= E1000_ETQF_FILTER_ENABLE | E1000_ETQF_QUEUE_ENABLE;
+ etqf |= (uint32_t)(filter->ethertype & E1000_ETQF_ETHERTYPE);
+ etqf |= rx_queue << E1000_ETQF_QUEUE_SHIFT;
+
+ if (filter->priority_en) {
+ PMD_INIT_LOG(ERR, "vlan and priority (%d) is not support"
+ " in E1000.\n", filter->priority);
+ return -EINVAL;
+ }
+
+ E1000_WRITE_REG(hw, E1000_ETQF(index), etqf);
+ return 0;
+}
+
+/*
+ * remove an ethertype filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_remove_ethertype_filter(struct rte_eth_dev *dev, uint16_t index)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+ if (index >= E1000_MAX_ETQF_FILTERS)
+ return -EINVAL;
+
+ E1000_WRITE_REG(hw, E1000_ETQF(index), 0);
+ return 0;
+}
+
+/*
+ * gets an ethertype filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be gotten.
+ * *rx_queue: the ponited of the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_get_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t *rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t etqf;
+
+ MAC_TYPE_FILTER_SUP(hw->mac.type);
+
+ if (index >= E1000_MAX_ETQF_FILTERS)
+ return -EINVAL;
+
+ etqf = E1000_READ_REG(hw, E1000_ETQF(index));
+ if (etqf & E1000_ETQF_FILTER_ENABLE) {
+ filter->ethertype = etqf & E1000_ETQF_ETHERTYPE;
+ filter->priority_en = 0;
+ *rx_queue = (etqf & E1000_ETQF_QUEUE) >> E1000_ETQF_QUEUE_SHIFT;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+#define MAC_TYPE_FILTER_SUP_EXT(type) do {\
+ if ((type) != e1000_82580 && (type) != e1000_i350)\
+ return -ENOSYS; \
+} while (0)
+
+/*
+ * add a 2tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_add_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t ttqf, imir = 0;
+ uint32_t imir_ext = 0;
+
+ MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+ if (index >= E1000_MAX_TTQF_FILTERS ||
+ rx_queue >= IGB_MAX_RX_QUEUE_NUM ||
+ filter->priority > E1000_2TUPLE_MAX_PRI)
+ return -EINVAL; /* filter index is out of range. */
+ if (filter->tcp_flags > TCP_FLAG_ALL)
+ return -EINVAL; /* flags is invalid. */
+
+ ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
+ if (ttqf & E1000_TTQF_QUEUE_ENABLE)
+ return -EINVAL; /* filter index is in use. */
+
+ imir = (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
+ if (filter->dst_port_mask == 1) /* 1b means not compare. */
+ imir |= E1000_IMIR_PORT_BP;
+ else
+ imir &= ~E1000_IMIR_PORT_BP;
+
+ imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+
+ ttqf = 0;
+ ttqf |= E1000_TTQF_QUEUE_ENABLE;
+ ttqf |= (uint32_t)(rx_queue << E1000_TTQF_QUEUE_SHIFT);
+ ttqf |= (uint32_t)(filter->protocol & E1000_TTQF_PROTOCOL_MASK);
+ if (filter->protocol_mask == 1)
+ ttqf |= E1000_TTQF_MASK_ENABLE;
+ else
+ ttqf &= ~E1000_TTQF_MASK_ENABLE;
+
+ imir_ext |= E1000_IMIR_EXT_SIZE_BP;
+ /* tcp flags bits setting. */
+ if (filter->tcp_flags & TCP_FLAG_ALL) {
+ if (filter->tcp_flags & TCP_UGR_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
+ if (filter->tcp_flags & TCP_ACK_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
+ if (filter->tcp_flags & TCP_PSH_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
+ if (filter->tcp_flags & TCP_RST_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_RST;
+ if (filter->tcp_flags & TCP_SYN_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
+ if (filter->tcp_flags & TCP_FIN_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
+ imir_ext &= ~E1000_IMIR_EXT_CTRL_BP;
+ } else
+ imir_ext |= E1000_IMIR_EXT_CTRL_BP;
+ E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
+ E1000_WRITE_REG(hw, E1000_TTQF(index), ttqf);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
+ return 0;
+}
+
+/*
+ * remove a 2tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_remove_2tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+ if (index >= E1000_MAX_TTQF_FILTERS)
+ return -EINVAL; /* filter index is out of range */
+
+ E1000_WRITE_REG(hw, E1000_TTQF(index), 0);
+ E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+ return 0;
+}
+
+/*
+ * get a 2tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that returns.
+ * *rx_queue: pointer of the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_get_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_2tuple_filter *filter, uint16_t *rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t imir, ttqf, imir_ext;
+
+ MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+ if (index >= E1000_MAX_TTQF_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ ttqf = E1000_READ_REG(hw, E1000_TTQF(index));
+ if (ttqf & E1000_TTQF_QUEUE_ENABLE) {
+ imir = E1000_READ_REG(hw, E1000_IMIR(index));
+ filter->protocol = ttqf & E1000_TTQF_PROTOCOL_MASK;
+ filter->protocol_mask = (ttqf & E1000_TTQF_MASK_ENABLE) ? 1 : 0;
+ *rx_queue = (ttqf & E1000_TTQF_RX_QUEUE_MASK) >>
+ E1000_TTQF_QUEUE_SHIFT;
+ filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
+ filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
+ filter->priority = (imir & E1000_IMIR_PRIORITY) >>
+ E1000_IMIR_PRIORITY_SHIFT;
+
+ imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
+ if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
+ if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
+ filter->tcp_flags |= TCP_UGR_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
+ filter->tcp_flags |= TCP_ACK_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
+ filter->tcp_flags |= TCP_PSH_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
+ filter->tcp_flags |= TCP_RST_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
+ filter->tcp_flags |= TCP_SYN_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
+ filter->tcp_flags |= TCP_FIN_FLAG;
+ } else
+ filter->tcp_flags = 0;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+/*
+ * add a flex filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_add_flex_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_flex_filter *filter, uint16_t rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t wufc, en_bits = 0;
+ uint32_t queueing = 0;
+ uint32_t reg_off = 0;
+ uint8_t i, j = 0;
+
+ MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+ if (index >= E1000_MAX_FLEXIBLE_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ if (filter->len == 0 || filter->len > E1000_MAX_FLEX_FILTER_LEN ||
+ filter->len % 8 != 0 ||
+ filter->priority > E1000_MAX_FLEX_FILTER_PRI)
+ return -EINVAL;
+
+ wufc = E1000_READ_REG(hw, E1000_WUFC);
+ en_bits = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
+ if ((wufc & en_bits) == en_bits)
+ return -EINVAL; /* the filter is in use. */
+
+ E1000_WRITE_REG(hw, E1000_WUFC,
+ wufc | E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index));
+
+ j = 0;
+ if (index < E1000_MAX_FHFT)
+ reg_off = E1000_FHFT(index);
+ else
+ reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
+
+ for (i = 0; i < 16; i++) {
+ E1000_WRITE_REG(hw, reg_off + i*4*4, filter->dwords[j]);
+ E1000_WRITE_REG(hw, reg_off + (i*4+1)*4, filter->dwords[++j]);
+ E1000_WRITE_REG(hw, reg_off + (i*4+2)*4,
+ (uint32_t)filter->mask[i]);
+ ++j;
+ }
+ queueing |= filter->len |
+ (rx_queue << E1000_FHFT_QUEUEING_QUEUE_SHIFT) |
+ (filter->priority << E1000_FHFT_QUEUEING_PRIO_SHIFT);
+ E1000_WRITE_REG(hw, reg_off + E1000_FHFT_QUEUEING_OFFSET, queueing);
+ return 0;
+}
+
+/*
+ * remove a flex filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_remove_flex_filter(struct rte_eth_dev *dev,
+ uint16_t index)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t wufc, reg_off = 0;
+ uint8_t i;
+
+ MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+ if (index >= E1000_MAX_FLEXIBLE_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ wufc = E1000_READ_REG(hw, E1000_WUFC);
+ E1000_WRITE_REG(hw, E1000_WUFC, wufc & (~(E1000_WUFC_FLX0 << index)));
+
+ if (index < E1000_MAX_FHFT)
+ reg_off = E1000_FHFT(index);
+ else
+ reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
+
+ for (i = 0; i < 64; i++)
+ E1000_WRITE_REG(hw, reg_off + i*4, 0);
+ return 0;
+}
+
+/*
+ * get a flex filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that returns.
+ * *rx_queue: the pointer of the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_get_flex_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_flex_filter *filter, uint16_t *rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t wufc, queueing, wufc_en = 0;
+ uint8_t i, j;
+
+ MAC_TYPE_FILTER_SUP_EXT(hw->mac.type);
+
+ if (index >= E1000_MAX_FLEXIBLE_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ wufc = E1000_READ_REG(hw, E1000_WUFC);
+ wufc_en = E1000_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
+
+ if ((wufc & wufc_en) == wufc_en) {
+ uint32_t reg_off = 0;
+ j = 0;
+ if (index < E1000_MAX_FHFT)
+ reg_off = E1000_FHFT(index);
+ else
+ reg_off = E1000_FHFT_EXT(index - E1000_MAX_FHFT);
+
+ for (i = 0; i < 16; i++, j = i * 2) {
+ filter->dwords[j] =
+ E1000_READ_REG(hw, reg_off + i*4*4);
+ filter->dwords[j+1] =
+ E1000_READ_REG(hw, reg_off + (i*4+1)*4);
+ filter->mask[i] =
+ E1000_READ_REG(hw, reg_off + (i*4+2)*4);
+ }
+ queueing = E1000_READ_REG(hw,
+ reg_off + E1000_FHFT_QUEUEING_OFFSET);
+ filter->len = queueing & E1000_FHFT_QUEUEING_LEN;
+ filter->priority = (queueing & E1000_FHFT_QUEUEING_PRIO) >>
+ E1000_FHFT_QUEUEING_PRIO_SHIFT;
+ *rx_queue = (queueing & E1000_FHFT_QUEUEING_QUEUE) >>
+ E1000_FHFT_QUEUEING_QUEUE_SHIFT;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+/*
+ * add a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t ftqf, spqf = 0;
+ uint32_t imir = 0;
+ uint32_t imir_ext = 0;
+
+ if (hw->mac.type != e1000_82576)
+ return -ENOSYS;
+
+ if (index >= E1000_MAX_FTQF_FILTERS ||
+ rx_queue >= IGB_MAX_RX_QUEUE_NUM_82576)
+ return -EINVAL; /* filter index is out of range. */
+
+ ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
+ if (ftqf & E1000_FTQF_QUEUE_ENABLE)
+ return -EINVAL; /* filter index is in use. */
+
+ ftqf = 0;
+ ftqf |= filter->protocol & E1000_FTQF_PROTOCOL_MASK;
+ if (filter->src_ip_mask == 1) /* 1b means not compare. */
+ ftqf |= E1000_FTQF_SOURCE_ADDR_MASK;
+ if (filter->dst_ip_mask == 1)
+ ftqf |= E1000_FTQF_DEST_ADDR_MASK;
+ if (filter->src_port_mask == 1)
+ ftqf |= E1000_FTQF_SOURCE_PORT_MASK;
+ if (filter->protocol_mask == 1)
+ ftqf |= E1000_FTQF_PROTOCOL_COMP_MASK;
+ ftqf |= (rx_queue << E1000_FTQF_QUEUE_SHIFT) & E1000_FTQF_QUEUE_MASK;
+ ftqf |= E1000_FTQF_VF_MASK_EN;
+ ftqf |= E1000_FTQF_QUEUE_ENABLE;
+ E1000_WRITE_REG(hw, E1000_FTQF(index), ftqf);
+ E1000_WRITE_REG(hw, E1000_DAQF(index), filter->dst_ip);
+ E1000_WRITE_REG(hw, E1000_SAQF(index), filter->src_ip);
+
+ spqf |= filter->src_port & E1000_SPQF_SRCPORT;
+ E1000_WRITE_REG(hw, E1000_SPQF(index), spqf);
+
+ imir |= (uint32_t)(filter->dst_port & E1000_IMIR_DSTPORT);
+ if (filter->dst_port_mask == 1) /* 1b means not compare. */
+ imir |= E1000_IMIR_PORT_BP;
+ else
+ imir &= ~E1000_IMIR_PORT_BP;
+ imir |= filter->priority << E1000_IMIR_PRIORITY_SHIFT;
+
+ imir_ext |= E1000_IMIR_EXT_SIZE_BP;
+ /* tcp flags bits setting. */
+ if (filter->tcp_flags & TCP_FLAG_ALL) {
+ if (filter->tcp_flags & TCP_UGR_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_UGR;
+ if (filter->tcp_flags & TCP_ACK_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_ACK;
+ if (filter->tcp_flags & TCP_PSH_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_PSH;
+ if (filter->tcp_flags & TCP_RST_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_RST;
+ if (filter->tcp_flags & TCP_SYN_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_SYN;
+ if (filter->tcp_flags & TCP_FIN_FLAG)
+ imir_ext |= E1000_IMIR_EXT_CTRL_FIN;
+ } else
+ imir_ext |= E1000_IMIR_EXT_CTRL_BP;
+ E1000_WRITE_REG(hw, E1000_IMIR(index), imir);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(index), imir_ext);
+ return 0;
+}
+
+/*
+ * remove a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_remove_5tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (hw->mac.type != e1000_82576)
+ return -ENOSYS;
+
+ if (index >= E1000_MAX_FTQF_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ E1000_WRITE_REG(hw, E1000_FTQF(index), 0);
+ E1000_WRITE_REG(hw, E1000_DAQF(index), 0);
+ E1000_WRITE_REG(hw, E1000_SAQF(index), 0);
+ E1000_WRITE_REG(hw, E1000_SPQF(index), 0);
+ E1000_WRITE_REG(hw, E1000_IMIR(index), 0);
+ E1000_WRITE_REG(hw, E1000_IMIREXT(index), 0);
+ return 0;
+}
+
+/*
+ * get a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates
+ * filter: ponter to the filter that returns
+ * *rx_queue: pointer of the queue id the filter assigned to
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t *rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t spqf, ftqf, imir, imir_ext;
+
+ if (hw->mac.type != e1000_82576)
+ return -ENOSYS;
+
+ if (index >= E1000_MAX_FTQF_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ ftqf = E1000_READ_REG(hw, E1000_FTQF(index));
+ if (ftqf & E1000_FTQF_QUEUE_ENABLE) {
+ filter->src_ip_mask =
+ (ftqf & E1000_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
+ filter->dst_ip_mask =
+ (ftqf & E1000_FTQF_DEST_ADDR_MASK) ? 1 : 0;
+ filter->src_port_mask =
+ (ftqf & E1000_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
+ filter->protocol_mask =
+ (ftqf & E1000_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
+ filter->protocol =
+ (uint8_t)ftqf & E1000_FTQF_PROTOCOL_MASK;
+ *rx_queue = (uint16_t)((ftqf & E1000_FTQF_QUEUE_MASK) >>
+ E1000_FTQF_QUEUE_SHIFT);
+
+ spqf = E1000_READ_REG(hw, E1000_SPQF(index));
+ filter->src_port = spqf & E1000_SPQF_SRCPORT;
+
+ filter->dst_ip = E1000_READ_REG(hw, E1000_DAQF(index));
+ filter->src_ip = E1000_READ_REG(hw, E1000_SAQF(index));
+
+ imir = E1000_READ_REG(hw, E1000_IMIR(index));
+ filter->dst_port_mask = (imir & E1000_IMIR_PORT_BP) ? 1 : 0;
+ filter->dst_port = (uint16_t)(imir & E1000_IMIR_DSTPORT);
+ filter->priority = (imir & E1000_IMIR_PRIORITY) >>
+ E1000_IMIR_PRIORITY_SHIFT;
+
+ imir_ext = E1000_READ_REG(hw, E1000_IMIREXT(index));
+ if (!(imir_ext & E1000_IMIR_EXT_CTRL_BP)) {
+ if (imir_ext & E1000_IMIR_EXT_CTRL_UGR)
+ filter->tcp_flags |= TCP_UGR_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_ACK)
+ filter->tcp_flags |= TCP_ACK_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_PSH)
+ filter->tcp_flags |= TCP_PSH_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_RST)
+ filter->tcp_flags |= TCP_RST_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_SYN)
+ filter->tcp_flags |= TCP_SYN_FLAG;
+ if (imir_ext & E1000_IMIR_EXT_CTRL_FIN)
+ filter->tcp_flags |= TCP_FIN_FLAG;
+ } else
+ filter->tcp_flags = 0;
+ return 0;
+ }
+ return -ENOENT;
+}
+
static struct rte_driver pmd_igb_drv = {
.type = PMD_PDEV,
.init = rte_igb_pmd_init,
--
1.8.1.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v4 3/4] ixgbe: add ixgbe NIC filters of generic filter feature
2014-06-16 7:31 [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Jingjing Wu
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 1/4] ethdev: add ethdev APIs for NIC filters of " Jingjing Wu
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 2/4] e1000: add igb NIC filters of generic filter feature Jingjing Wu
@ 2014-06-16 7:31 ` Jingjing Wu
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 4/4] app/test-pmd: add commands in testpmd for NIC filters Jingjing Wu
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Jingjing Wu @ 2014-06-16 7:31 UTC (permalink / raw)
To: dev
This patch adds following ixgbe NIC filters implement:
syn filter, ethertype filter, 5tuple filter for intel NIC 82599
Signed-off-by: jingjing.wu <jingjing.wu@intel.com>
---
lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 440 ++++++++++++++++++++++++++++++++++++
lib/librte_pmd_ixgbe/ixgbe_ethdev.h | 34 +++
2 files changed, 474 insertions(+)
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index 10e5633..ed34386 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -39,6 +39,7 @@
#include <unistd.h>
#include <stdarg.h>
#include <inttypes.h>
+#include <netinet/in.h>
#include <rte_byteorder.h>
#include <rte_common.h>
#include <rte_cycles.h>
@@ -196,6 +197,23 @@ static void ixgbevf_add_mac_addr(struct rte_eth_dev *dev,
struct ether_addr *mac_addr,
uint32_t index, uint32_t pool);
static void ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index);
+static int ixgbe_add_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t rx_queue);
+static int ixgbe_remove_syn_filter(struct rte_eth_dev *dev);
+static int ixgbe_get_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t *rx_queue);
+static int ixgbe_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t rx_queue);
+static int ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev,
+ uint16_t index);
+static int ixgbe_get_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_ethertype_filter *filter, uint16_t *rx_queue);
+static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t rx_queue);
+static int ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index);
+static int ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t *rx_queue);
/*
* Define VF Stats MACRO for Non "cleared on read" register
@@ -326,6 +344,15 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
#endif /* RTE_NIC_BYPASS */
.rss_hash_update = ixgbe_dev_rss_hash_update,
.rss_hash_conf_get = ixgbe_dev_rss_hash_conf_get,
+ .add_syn_filter = ixgbe_add_syn_filter,
+ .remove_syn_filter = ixgbe_remove_syn_filter,
+ .get_syn_filter = ixgbe_get_syn_filter,
+ .add_ethertype_filter = ixgbe_add_ethertype_filter,
+ .remove_ethertype_filter = ixgbe_remove_ethertype_filter,
+ .get_ethertype_filter = ixgbe_get_ethertype_filter,
+ .add_5tuple_filter = ixgbe_add_5tuple_filter,
+ .remove_5tuple_filter = ixgbe_remove_5tuple_filter,
+ .get_5tuple_filter = ixgbe_get_5tuple_filter,
};
/*
@@ -3388,6 +3415,419 @@ ixgbevf_remove_mac_addr(struct rte_eth_dev *dev, uint32_t index)
}
}
+/*
+ * add syn filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_add_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t rx_queue)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t synqf;
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ if (rx_queue >= IXGBE_MAX_RX_QUEUE_NUM)
+ return -EINVAL;
+
+ synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF);
+
+ if (synqf & IXGBE_SYN_FILTER_ENABLE)
+ return -EINVAL;
+
+ synqf = (uint32_t)(((rx_queue << IXGBE_SYN_FILTER_QUEUE_SHIFT) &
+ IXGBE_SYN_FILTER_QUEUE) | IXGBE_SYN_FILTER_ENABLE);
+
+ if (filter->hig_pri)
+ synqf |= IXGBE_SYN_FILTER_SYNQFP;
+ else
+ synqf &= ~IXGBE_SYN_FILTER_SYNQFP;
+
+ IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf);
+ return 0;
+}
+
+/*
+ * remove syn filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_remove_syn_filter(struct rte_eth_dev *dev)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t synqf;
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF);
+
+ synqf &= ~(IXGBE_SYN_FILTER_QUEUE | IXGBE_SYN_FILTER_ENABLE);
+
+ IXGBE_WRITE_REG(hw, IXGBE_SYNQF, synqf);
+ return 0;
+}
+
+
+/*
+ * get the syn filter's info
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * filter: ponter to the filter that returns.
+ * *rx_queue: pointer to the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_get_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint16_t *rx_queue)
+
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t synqf;
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ synqf = IXGBE_READ_REG(hw, IXGBE_SYNQF);
+ if (synqf & IXGBE_SYN_FILTER_ENABLE) {
+ filter->hig_pri = (synqf & IXGBE_SYN_FILTER_SYNQFP) ? 1 : 0;
+ *rx_queue = (uint16_t)((synqf & IXGBE_SYN_FILTER_QUEUE) >> 1);
+ return 0;
+ }
+ return -ENOENT;
+}
+
+/*
+ * add an ethertype filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_add_ethertype_filter(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_ethertype_filter *filter,
+ uint16_t rx_queue)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t etqf, etqs = 0;
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ if (index >= IXGBE_MAX_ETQF_FILTERS ||
+ rx_queue >= IXGBE_MAX_RX_QUEUE_NUM)
+ return -EINVAL;
+
+ etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(index));
+ if (etqf & IXGBE_ETQF_FILTER_EN)
+ return -EINVAL; /* filter index is in use. */
+
+ etqf = 0;
+ etqf |= IXGBE_ETQF_FILTER_EN;
+ etqf |= (uint32_t)filter->ethertype;
+
+ if (filter->priority_en) {
+ if (filter->priority > IXGBE_ETQF_MAX_PRI)
+ return -EINVAL;
+ etqf |= (uint32_t)((filter->priority << IXGBE_ETQF_SHIFT) & IXGBE_ETQF_UP);
+ etqf |= IXGBE_ETQF_UP_EN;
+ }
+ etqs |= (uint32_t)((rx_queue << IXGBE_ETQS_RX_QUEUE_SHIFT) & IXGBE_ETQS_RX_QUEUE);
+ etqs |= IXGBE_ETQS_QUEUE_EN;
+
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(index), etqf);
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(index), etqs);
+ return 0;
+}
+
+/*
+ * remove an ethertype filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_remove_ethertype_filter(struct rte_eth_dev *dev,
+ uint16_t index)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ if (index >= IXGBE_MAX_ETQF_FILTERS)
+ return -EINVAL;
+
+ IXGBE_WRITE_REG(hw, IXGBE_ETQF(index), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_ETQS(index), 0);
+
+ return 0;
+}
+
+/*
+ * gets an ethertype filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be gotten.
+ * *rx_queue: the ponited of the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_get_ethertype_filter(struct rte_eth_dev *dev,
+ uint16_t index, struct rte_ethertype_filter *filter,
+ uint16_t *rx_queue)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t etqf, etqs;
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ if (index >= IXGBE_MAX_ETQF_FILTERS)
+ return -EINVAL;
+
+ etqf = IXGBE_READ_REG(hw, IXGBE_ETQF(index));
+ etqs = IXGBE_READ_REG(hw, IXGBE_ETQS(index));
+ if (etqf & IXGBE_ETQF_FILTER_EN) {
+ filter->ethertype = etqf & IXGBE_ETQF_ETHERTYPE;
+ filter->priority_en = (etqf & IXGBE_ETQF_UP_EN) ? 1 : 0;
+ if (filter->priority_en)
+ filter->priority = (etqf & IXGBE_ETQF_UP) >> 16;
+ *rx_queue = (etqs & IXGBE_ETQS_RX_QUEUE) >> IXGBE_ETQS_RX_QUEUE_SHIFT;
+ return 0;
+ }
+ return -ENOENT;
+}
+
+static inline enum ixgbe_5tuple_protocol
+convert_protocol_type(uint8_t protocol_value)
+{
+ if (protocol_value == IPPROTO_TCP)
+ return IXGBE_FILTER_PROTOCOL_TCP;
+ else if (protocol_value == IPPROTO_UDP)
+ return IXGBE_FILTER_PROTOCOL_UDP;
+ else if (protocol_value == IPPROTO_SCTP)
+ return IXGBE_FILTER_PROTOCOL_SCTP;
+ else
+ return IXGBE_FILTER_PROTOCOL_NONE;
+}
+
+static inline uint8_t
+revert_protocol_type(enum ixgbe_5tuple_protocol protocol)
+{
+ if (protocol == IXGBE_FILTER_PROTOCOL_TCP)
+ return IPPROTO_TCP;
+ else if (protocol == IXGBE_FILTER_PROTOCOL_UDP)
+ return IPPROTO_UDP;
+ else if (protocol == IXGBE_FILTER_PROTOCOL_SCTP)
+ return IPPROTO_SCTP;
+ else
+ return 0;
+}
+
+/*
+ * add a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ * filter: ponter to the filter that will be added.
+ * rx_queue: the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t rx_queue)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t ftqf, sdpqf = 0;
+ uint32_t l34timir = 0;
+ uint8_t mask = 0xff;
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ if (index >= IXGBE_MAX_FTQF_FILTERS ||
+ rx_queue >= IXGBE_MAX_RX_QUEUE_NUM ||
+ filter->priority > IXGBE_5TUPLE_MAX_PRI ||
+ filter->priority < IXGBE_5TUPLE_MIN_PRI)
+ return -EINVAL; /* filter index is out of range. */
+
+ if (filter->tcp_flags) {
+ PMD_INIT_LOG(INFO, "82599EB not tcp flags in 5tuple");
+ return -EINVAL;
+ }
+
+ ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
+ if (ftqf & IXGBE_FTQF_QUEUE_ENABLE)
+ return -EINVAL; /* filter index is in use. */
+
+ ftqf = 0;
+ sdpqf = (uint32_t)(filter->dst_port << IXGBE_SDPQF_DSTPORT_SHIFT);
+ sdpqf = sdpqf | (filter->src_port & IXGBE_SDPQF_SRCPORT);
+
+ ftqf |= (uint32_t)(convert_protocol_type(filter->protocol) &
+ IXGBE_FTQF_PROTOCOL_MASK);
+ ftqf |= (uint32_t)((filter->priority & IXGBE_FTQF_PRIORITY_MASK) <<
+ IXGBE_FTQF_PRIORITY_SHIFT);
+ if (filter->src_ip_mask == 0) /* 0 means compare. */
+ mask &= IXGBE_FTQF_SOURCE_ADDR_MASK;
+ if (filter->dst_ip_mask == 0)
+ mask &= IXGBE_FTQF_DEST_ADDR_MASK;
+ if (filter->src_port_mask == 0)
+ mask &= IXGBE_FTQF_SOURCE_PORT_MASK;
+ if (filter->dst_port_mask == 0)
+ mask &= IXGBE_FTQF_DEST_PORT_MASK;
+ if (filter->protocol_mask == 0)
+ mask &= IXGBE_FTQF_PROTOCOL_COMP_MASK;
+ ftqf |= mask << IXGBE_FTQF_5TUPLE_MASK_SHIFT;
+ ftqf |= IXGBE_FTQF_POOL_MASK_EN;
+ ftqf |= IXGBE_FTQF_QUEUE_ENABLE;
+
+ IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), filter->dst_ip);
+ IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), filter->src_ip);
+ IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), sdpqf);
+ IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), ftqf);
+
+ l34timir |= IXGBE_L34T_IMIR_RESERVE;
+ l34timir |= (uint32_t)(rx_queue << IXGBE_L34T_IMIR_QUEUE_SHIFT);
+ IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), l34timir);
+ return 0;
+}
+
+/*
+ * remove a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_remove_5tuple_filter(struct rte_eth_dev *dev,
+ uint16_t index)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ if (index >= IXGBE_MAX_FTQF_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ IXGBE_WRITE_REG(hw, IXGBE_DAQF(index), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_SAQF(index), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_SDPQF(index), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_FTQF(index), 0);
+ IXGBE_WRITE_REG(hw, IXGBE_L34T_IMIR(index), 0);
+ return 0;
+}
+
+/*
+ * get a 5tuple filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * index: the index the filter allocates
+ * filter: ponter to the filter that returns.
+ * *rx_queue: pointer of the queue id the filter assigned to.
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_get_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_5tuple_filter *filter, uint16_t *rx_queue)
+{
+ struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t sdpqf, ftqf, l34timir;
+ uint8_t mask;
+ enum ixgbe_5tuple_protocol proto;
+
+ if (hw->mac.type != ixgbe_mac_82599EB)
+ return -ENOSYS;
+
+ if (index >= IXGBE_MAX_FTQF_FILTERS)
+ return -EINVAL; /* filter index is out of range. */
+
+ ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
+ if (ftqf & IXGBE_FTQF_QUEUE_ENABLE) {
+ proto = (enum ixgbe_5tuple_protocol)(ftqf & IXGBE_FTQF_PROTOCOL_MASK);
+ filter->protocol = revert_protocol_type(proto);
+ filter->priority = (ftqf >> IXGBE_FTQF_PRIORITY_SHIFT) &
+ IXGBE_FTQF_PRIORITY_MASK;
+ mask = (uint8_t)((ftqf >> IXGBE_FTQF_5TUPLE_MASK_SHIFT) &
+ IXGBE_FTQF_5TUPLE_MASK_MASK);
+ filter->src_ip_mask =
+ (mask & IXGBE_FTQF_SOURCE_ADDR_MASK) ? 1 : 0;
+ filter->dst_ip_mask =
+ (mask & IXGBE_FTQF_DEST_ADDR_MASK) ? 1 : 0;
+ filter->src_port_mask =
+ (mask & IXGBE_FTQF_SOURCE_PORT_MASK) ? 1 : 0;
+ filter->dst_port_mask =
+ (mask & IXGBE_FTQF_DEST_PORT_MASK) ? 1 : 0;
+ filter->protocol_mask =
+ (mask & IXGBE_FTQF_PROTOCOL_COMP_MASK) ? 1 : 0;
+
+ sdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(index));
+ filter->dst_port = (sdpqf & IXGBE_SDPQF_DSTPORT) >>
+ IXGBE_SDPQF_DSTPORT_SHIFT;
+ filter->src_port = sdpqf & IXGBE_SDPQF_SRCPORT;
+ filter->dst_ip = IXGBE_READ_REG(hw, IXGBE_DAQF(index));
+ filter->src_ip = IXGBE_READ_REG(hw, IXGBE_SAQF(index));
+
+ l34timir = IXGBE_READ_REG(hw, IXGBE_L34T_IMIR(index));
+ *rx_queue = (l34timir & IXGBE_L34T_IMIR_QUEUE) >>
+ IXGBE_L34T_IMIR_QUEUE_SHIFT;
+ return 0;
+ }
+ return -ENOENT;
+}
+
static struct rte_driver rte_ixgbe_driver = {
.type = PMD_PDEV,
.init = rte_ixgbe_pmd_init,
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
index 7a4f84c..a5159e5 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
@@ -74,6 +74,30 @@
(IXGBE_RTTBCNRC_RF_INT_MASK_BASE << IXGBE_RTTBCNRC_RF_INT_SHIFT)
#define IXGBE_MAX_QUEUE_NUM_PER_VF 8
+
+#define IXGBE_SYN_FILTER_ENABLE 0x00000001 /* syn filter enable field */
+#define IXGBE_SYN_FILTER_QUEUE 0x000000FE /* syn filter queue field */
+#define IXGBE_SYN_FILTER_QUEUE_SHIFT 1 /* syn filter queue field shift */
+#define IXGBE_SYN_FILTER_SYNQFP 0x80000000 /* syn filter SYNQFP */
+
+#define IXGBE_ETQF_UP 0x00070000 /* ethertype filter priority field */
+#define IXGBE_ETQF_SHIFT 16
+#define IXGBE_ETQF_UP_EN 0x00080000
+#define IXGBE_ETQF_ETHERTYPE 0x0000FFFF /* ethertype filter ethertype field */
+#define IXGBE_ETQF_MAX_PRI 7
+
+#define IXGBE_SDPQF_DSTPORT 0xFFFF0000 /* dst port field */
+#define IXGBE_SDPQF_DSTPORT_SHIFT 16 /* dst port field shift */
+#define IXGBE_SDPQF_SRCPORT 0x0000FFFF /* src port field */
+
+#define IXGBE_L34T_IMIR_SIZE_BP 0x00001000
+#define IXGBE_L34T_IMIR_RESERVE 0x00080000 /* bit 13 to 19 must be set to 1000000b. */
+#define IXGBE_L34T_IMIR_LLI 0x00100000
+#define IXGBE_L34T_IMIR_QUEUE 0x0FE00000
+#define IXGBE_L34T_IMIR_QUEUE_SHIFT 21
+#define IXGBE_5TUPLE_MAX_PRI 7
+#define IXGBE_5TUPLE_MIN_PRI 1
+
/*
* Information about the fdir mode.
*/
@@ -157,6 +181,16 @@ struct ixgbe_adapter {
#endif /* RTE_NIC_BYPASS */
};
+/*
+ * Possible l4type of 5tuple filters.
+ */
+enum ixgbe_5tuple_protocol {
+ IXGBE_FILTER_PROTOCOL_TCP = 0,
+ IXGBE_FILTER_PROTOCOL_UDP,
+ IXGBE_FILTER_PROTOCOL_SCTP,
+ IXGBE_FILTER_PROTOCOL_NONE,
+};
+
#define IXGBE_DEV_PRIVATE_TO_HW(adapter)\
(&((struct ixgbe_adapter *)adapter)->hw)
--
1.8.1.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* [dpdk-dev] [PATCH v4 4/4] app/test-pmd: add commands in testpmd for NIC filters
2014-06-16 7:31 [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Jingjing Wu
` (2 preceding siblings ...)
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 3/4] ixgbe: add ixgbe " Jingjing Wu
@ 2014-06-16 7:31 ` Jingjing Wu
2014-06-16 14:15 ` [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Cao, Waterman
2014-06-16 18:00 ` Thomas Monjalon
5 siblings, 0 replies; 7+ messages in thread
From: Jingjing Wu @ 2014-06-16 7:31 UTC (permalink / raw)
To: dev
add commands in testpmd for NIC filters:
add_ethertype_filter
remove_ethertype_filter
get_ethertype_filter
add_2tuple_filter
remove_2tuple_filter
get_2tuple_filter
add_5tuple_filter
remove_5tuple_filter
get_5tuple_filter
add_syn_filter
remove_syn_filter
get_syn_filter
add_flex_filter
remove_flex_filter
get_flex_filter
Signed-off-by: jingjing.wu <jingjing.wu@intel.com>
---
app/test-pmd/cmdline.c | 909 ++++++++++++++++++++++++++++++++++++++++++++++++-
app/test-pmd/config.c | 147 ++++++++
app/test-pmd/testpmd.h | 5 +
3 files changed, 1060 insertions(+), 1 deletion(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 4678977..8065836 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -113,6 +113,7 @@ static void cmd_help_brief_parsed(__attribute__((unused)) void *parsed_result,
" help ports : Configuring ports.\n"
" help flowdir : Flow Director filter help.\n"
" help registers : Reading and setting port registers.\n"
+ " help filters : Filters configuration help.\n"
" help all : All of the above sections.\n\n"
);
@@ -554,6 +555,67 @@ static void cmd_help_long_parsed(void *parsed_result,
" Set single bit value of a port register.\n\n"
);
}
+ if (show_all || !strcmp(res->section, "filters")) {
+
+ cmdline_printf(
+ cl,
+ "\n"
+ "filters:\n"
+ "----------\n\n"
+
+ "add_ethertype_filter (port_id) ethertype (eth_value)"
+ " priority (enable|disable)(pri_value) queue (queue_id) index (idx)\n"
+ " add an ethertype filter.\n\n"
+
+ "remove_ethertype_filter (port_id) index (idx)\n"
+ " remove an ethertype filter.\n\n"
+
+ "get_ethertype_filter (port_id) index (idx)\n"
+ " get info of a ethertype filter.\n\n"
+
+ "add_2tuple_filter (port_id) protocol (pro_value) (pro_mask)"
+ " dst_port (port_value) (port_mask) flags (flg_value) priority (prio_value)"
+ " queue (queue_id) index (idx)\n"
+ " add a 2tuple filter.\n\n"
+
+ "remove_2tuple_filter (port_id) index (idx)\n"
+ " remove a 2tuple filter.\n\n"
+
+ "get_2tuple_filter (port_id) index (idx)\n"
+ " get info of a 2tuple filter.\n\n"
+
+ "add_5tuple_filter (port_id) dst_ip (dst_address) src_ip (src_address)"
+ " dst_port (dst_port_value) src_port (src_port_value) protocol (protocol_value)"
+ " mask (mask_value) flags (flags_value) priority (prio_value)"
+ " queue (queue_id) index (idx)\n"
+ " add a 5tuple filter.\n\n"
+
+ "remove_5tuple_filter (port_id) index (idx)\n"
+ " remove a 5tuple filter.\n\n"
+
+ "get_5tuple_filter (port_id) index (idx)\n"
+ " get info of a 5tuple filter.\n\n"
+
+ "add_syn_filter (port_id) priority (high|low) queue (queue_id)"
+ " add syn filter.\n\n"
+
+ "remove_syn_filter (port_id)"
+ " remove syn filter.\n\n"
+
+ "get_syn_filter (port_id) "
+ " get syn filter info.\n\n"
+
+ "add_flex_filter (port_id) len (len_value) bytes (bytes_string) mask (mask_value)"
+ " priority (prio_value) queue (queue_id) index (idx)\n"
+ " add a flex filter.\n\n"
+
+ "remove_flex_filter (port_id) index (idx)\n"
+ " remove a flex filter.\n\n"
+
+ "get_flex_filter (port_id) index (idx)\n"
+ " get info of a flex filter.\n\n"
+ );
+ }
}
cmdline_parse_token_string_t cmd_help_long_help =
@@ -562,7 +624,7 @@ cmdline_parse_token_string_t cmd_help_long_help =
cmdline_parse_token_string_t cmd_help_long_section =
TOKEN_STRING_INITIALIZER(struct cmd_help_long_result, section,
"all#control#display#config#flowdir#"
- "ports#registers");
+ "ports#registers#filters");
cmdline_parse_inst_t cmd_help_long = {
.f = cmd_help_long_parsed,
@@ -5534,6 +5596,836 @@ cmdline_parse_inst_t cmd_dump_one = {
},
};
+/* *** ADD/REMOVE an ethertype FILTER *** */
+struct cmd_ethertype_filter_result {
+ cmdline_fixed_string_t filter;
+ uint8_t port_id;
+ cmdline_fixed_string_t ethertype;
+ uint16_t ethertype_value;
+ cmdline_fixed_string_t priority;
+ cmdline_fixed_string_t priority_en;
+ uint8_t priority_value;
+ cmdline_fixed_string_t queue;
+ uint16_t queue_id;
+ cmdline_fixed_string_t index;
+ uint16_t index_value;
+};
+
+static void
+cmd_ethertype_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret = 0;
+ struct cmd_ethertype_filter_result *res = parsed_result;
+ struct rte_ethertype_filter filter;
+
+ memset(&filter, 0, sizeof(struct rte_ethertype_filter));
+ filter.ethertype = rte_cpu_to_le_16(res->ethertype_value);
+ filter.priority = res->priority_value;
+
+ if (!strcmp(res->priority_en, "enable"))
+ filter.priority_en = 1;
+ if (!strcmp(res->filter, "add_ethertype_filter"))
+ ret = rte_eth_dev_add_ethertype_filter(res->port_id,
+ res->index_value,
+ &filter, res->queue_id);
+ else if (!strcmp(res->filter, "remove_ethertype_filter"))
+ ret = rte_eth_dev_remove_ethertype_filter(res->port_id,
+ res->index_value);
+ else if (!strcmp(res->filter, "get_ethertype_filter"))
+ get_ethertype_filter(res->port_id, res->index_value);
+
+ if (ret < 0)
+ printf("ethertype filter setting error: (%s)\n",
+ strerror(-ret));
+}
+
+cmdline_parse_token_num_t cmd_ethertype_filter_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_ethertype_filter_ethertype =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ ethertype, "ethertype");
+cmdline_parse_token_ipaddr_t cmd_ethertype_filter_ethertype_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+ ethertype_value, UINT16);
+cmdline_parse_token_string_t cmd_ethertype_filter_priority =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ priority, "priority");
+cmdline_parse_token_string_t cmd_ethertype_filter_priority_en =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ priority_en, "enable#disable");
+cmdline_parse_token_num_t cmd_ethertype_filter_priority_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+ priority_value, UINT8);
+cmdline_parse_token_string_t cmd_ethertype_filter_queue =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ queue, "queue");
+cmdline_parse_token_num_t cmd_ethertype_filter_queue_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+ queue_id, UINT16);
+cmdline_parse_token_string_t cmd_ethertype_filter_index =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ index, "index");
+cmdline_parse_token_num_t cmd_ethertype_filter_index_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_ethertype_filter_result,
+ index_value, UINT16);
+cmdline_parse_token_string_t cmd_ethertype_filter_add_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ filter, "add_ethertype_filter");
+cmdline_parse_inst_t cmd_add_ethertype_filter = {
+ .f = cmd_ethertype_filter_parsed,
+ .data = NULL,
+ .help_str = "add an ethertype filter",
+ .tokens = {
+ (void *)&cmd_ethertype_filter_add_filter,
+ (void *)&cmd_ethertype_filter_port_id,
+ (void *)&cmd_ethertype_filter_ethertype,
+ (void *)&cmd_ethertype_filter_ethertype_value,
+ (void *)&cmd_ethertype_filter_priority,
+ (void *)&cmd_ethertype_filter_priority_en,
+ (void *)&cmd_ethertype_filter_priority_value,
+ (void *)&cmd_ethertype_filter_queue,
+ (void *)&cmd_ethertype_filter_queue_id,
+ (void *)&cmd_ethertype_filter_index,
+ (void *)&cmd_ethertype_filter_index_value,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_ethertype_filter_remove_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ filter, "remove_ethertype_filter");
+cmdline_parse_inst_t cmd_remove_ethertype_filter = {
+ .f = cmd_ethertype_filter_parsed,
+ .data = NULL,
+ .help_str = "remove an ethertype filter",
+ .tokens = {
+ (void *)&cmd_ethertype_filter_remove_filter,
+ (void *)&cmd_ethertype_filter_port_id,
+ (void *)&cmd_ethertype_filter_index,
+ (void *)&cmd_ethertype_filter_index_value,
+ NULL,
+ },
+};
+cmdline_parse_token_string_t cmd_ethertype_filter_get_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_ethertype_filter_result,
+ filter, "get_ethertype_filter");
+cmdline_parse_inst_t cmd_get_ethertype_filter = {
+ .f = cmd_ethertype_filter_parsed,
+ .data = NULL,
+ .help_str = "get an ethertype filter",
+ .tokens = {
+ (void *)&cmd_ethertype_filter_get_filter,
+ (void *)&cmd_ethertype_filter_port_id,
+ (void *)&cmd_ethertype_filter_index,
+ (void *)&cmd_ethertype_filter_index_value,
+ NULL,
+ },
+};
+
+/* *** set SYN filter *** */
+struct cmd_set_syn_filter_result {
+ cmdline_fixed_string_t filter;
+ uint8_t port_id;
+ cmdline_fixed_string_t priority;
+ cmdline_fixed_string_t high;
+ cmdline_fixed_string_t queue;
+ uint16_t queue_id;
+};
+
+static void
+cmd_set_syn_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret = 0;
+ struct cmd_set_syn_filter_result *res = parsed_result;
+ struct rte_syn_filter filter;
+
+ if (!strcmp(res->filter, "add_syn_filter")) {
+ if (!strcmp(res->high, "high"))
+ filter.hig_pri = 1;
+ else
+ filter.hig_pri = 0;
+ ret = rte_eth_dev_add_syn_filter(res->port_id,
+ &filter, res->queue_id);
+ } else if (!strcmp(res->filter, "remove_syn_filter"))
+ ret = rte_eth_dev_remove_syn_filter(res->port_id);
+ else if (!strcmp(res->filter, "get_syn_filter"))
+ get_syn_filter(res->port_id);
+ if (ret < 0)
+ printf("syn filter setting error: (%s)\n", strerror(-ret));
+
+}
+cmdline_parse_token_string_t cmd_syn_filter_portid =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_syn_filter_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_syn_filter_priority =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
+ priority, "priority");
+cmdline_parse_token_string_t cmd_syn_filter_high =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
+ high, "high#low");
+cmdline_parse_token_string_t cmd_syn_filter_queue =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
+ queue, "queue");
+cmdline_parse_token_num_t cmd_syn_filter_queue_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_set_syn_filter_result,
+ queue_id, UINT16);
+cmdline_parse_token_string_t cmd_syn_filter_add_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
+ filter, "add_syn_filter");
+cmdline_parse_token_string_t cmd_syn_filter_remove_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
+ filter, "remove_syn_filter");
+cmdline_parse_inst_t cmd_add_syn_filter = {
+ .f = cmd_set_syn_filter_parsed,
+ .data = NULL,
+ .help_str = "add syn filter",
+ .tokens = {
+ (void *)&cmd_syn_filter_add_filter,
+ (void *)&cmd_syn_filter_portid,
+ (void *)&cmd_syn_filter_priority,
+ (void *)&cmd_syn_filter_high,
+ (void *)&cmd_syn_filter_queue,
+ (void *)&cmd_syn_filter_queue_id,
+ NULL,
+ },
+};
+cmdline_parse_inst_t cmd_remove_syn_filter = {
+ .f = cmd_set_syn_filter_parsed,
+ .data = NULL,
+ .help_str = "remove syn filter",
+ .tokens = {
+ (void *)&cmd_syn_filter_remove_filter,
+ (void *)&cmd_syn_filter_portid,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_syn_filter_get_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_set_syn_filter_result,
+ filter, "get_syn_filter");
+
+cmdline_parse_inst_t cmd_get_syn_filter = {
+ .f = cmd_set_syn_filter_parsed,
+ .data = NULL,
+ .help_str = "get syn filter",
+ .tokens = {
+ (void *)&cmd_syn_filter_get_filter,
+ (void *)&cmd_syn_filter_portid,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE A 2tuple FILTER *** */
+struct cmd_2tuple_filter_result {
+ cmdline_fixed_string_t filter;
+ uint8_t port_id;
+ cmdline_fixed_string_t protocol;
+ uint8_t protocol_value;
+ uint8_t protocol_mask;
+ cmdline_fixed_string_t dst_port;
+ uint16_t dst_port_value;
+ uint16_t dst_port_mask;
+ cmdline_fixed_string_t flags;
+ uint8_t flags_value;
+ cmdline_fixed_string_t priority;
+ uint8_t priority_value;
+ cmdline_fixed_string_t queue;
+ uint16_t queue_id;
+ cmdline_fixed_string_t index;
+ uint16_t index_value;
+};
+
+static void
+cmd_2tuple_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret = 0;
+ struct rte_2tuple_filter filter;
+ struct cmd_2tuple_filter_result *res = parsed_result;
+
+ memset(&filter, 0, sizeof(struct rte_2tuple_filter));
+
+ if (!strcmp(res->filter, "add_2tuple_filter")) {
+ /* need convert to big endian. */
+ filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+ filter.protocol = res->protocol_value;
+ filter.dst_port_mask = (res->dst_port_mask) ? 0 : 1;
+ filter.protocol_mask = (res->protocol_mask) ? 0 : 1;
+ filter.priority = res->priority_value;
+ filter.tcp_flags = res->flags_value;
+ ret = rte_eth_dev_add_2tuple_filter(res->port_id,
+ res->index_value, &filter, res->queue_id);
+ } else if (!strcmp(res->filter, "remove_2tuple_filter"))
+ ret = rte_eth_dev_remove_2tuple_filter(res->port_id,
+ res->index_value);
+ else if (!strcmp(res->filter, "get_2tuple_filter"))
+ get_2tuple_filter(res->port_id, res->index_value);
+
+ if (ret < 0)
+ printf("2tuple filter setting error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_num_t cmd_2tuple_filter_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_protocol =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ protocol, "protocol");
+cmdline_parse_token_string_t cmd_2tuple_filter_protocol_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ protocol_value, UINT8);
+cmdline_parse_token_num_t cmd_2tuple_filter_protocol_mask =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ protocol_mask, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_dst_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ dst_port, "dst_port");
+cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ dst_port_value, UINT16);
+cmdline_parse_token_num_t cmd_2tuple_filter_dst_port_mask =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ dst_port_mask, UINT16);
+cmdline_parse_token_string_t cmd_2tuple_filter_flags =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ flags, "flags");
+cmdline_parse_token_string_t cmd_2tuple_filter_flags_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ flags_value, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_priority =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ priority, "priority");
+cmdline_parse_token_num_t cmd_2tuple_filter_priority_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ priority_value, UINT8);
+cmdline_parse_token_string_t cmd_2tuple_filter_queue =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ queue, "queue");
+cmdline_parse_token_num_t cmd_2tuple_filter_queue_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ queue_id, UINT16);
+cmdline_parse_token_string_t cmd_2tuple_filter_index =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ index, "index");
+cmdline_parse_token_num_t cmd_2tuple_filter_index_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_2tuple_filter_result,
+ index_value, UINT16);
+cmdline_parse_token_string_t cmd_2tuple_filter_add_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ filter, "add_2tuple_filter");
+cmdline_parse_inst_t cmd_add_2tuple_filter = {
+ .f = cmd_2tuple_filter_parsed,
+ .data = NULL,
+ .help_str = "add a 2tuple filter",
+ .tokens = {
+ (void *)&cmd_2tuple_filter_add_filter,
+ (void *)&cmd_2tuple_filter_port_id,
+ (void *)&cmd_2tuple_filter_protocol,
+ (void *)&cmd_2tuple_filter_protocol_value,
+ (void *)&cmd_2tuple_filter_protocol_mask,
+ (void *)&cmd_2tuple_filter_dst_port,
+ (void *)&cmd_2tuple_filter_dst_port_value,
+ (void *)&cmd_2tuple_filter_dst_port_mask,
+ (void *)&cmd_2tuple_filter_flags,
+ (void *)&cmd_2tuple_filter_flags_value,
+ (void *)&cmd_2tuple_filter_priority,
+ (void *)&cmd_2tuple_filter_priority_value,
+ (void *)&cmd_2tuple_filter_queue,
+ (void *)&cmd_2tuple_filter_queue_id,
+ (void *)&cmd_2tuple_filter_index,
+ (void *)&cmd_2tuple_filter_index_value,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_2tuple_filter_remove_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ filter, "remove_2tuple_filter");
+cmdline_parse_inst_t cmd_remove_2tuple_filter = {
+ .f = cmd_2tuple_filter_parsed,
+ .data = NULL,
+ .help_str = "remove a 2tuple filter",
+ .tokens = {
+ (void *)&cmd_2tuple_filter_remove_filter,
+ (void *)&cmd_2tuple_filter_port_id,
+ (void *)&cmd_2tuple_filter_index,
+ (void *)&cmd_2tuple_filter_index_value,
+ NULL,
+ },
+};
+cmdline_parse_token_string_t cmd_2tuple_filter_get_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_2tuple_filter_result,
+ filter, "get_2tuple_filter");
+cmdline_parse_inst_t cmd_get_2tuple_filter = {
+ .f = cmd_2tuple_filter_parsed,
+ .data = NULL,
+ .help_str = "get a 2tuple filter",
+ .tokens = {
+ (void *)&cmd_2tuple_filter_get_filter,
+ (void *)&cmd_2tuple_filter_port_id,
+ (void *)&cmd_2tuple_filter_index,
+ (void *)&cmd_2tuple_filter_index_value,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE A 5tuple FILTER *** */
+struct cmd_5tuple_filter_result {
+ cmdline_fixed_string_t filter;
+ uint8_t port_id;
+ cmdline_fixed_string_t dst_ip;
+ cmdline_ipaddr_t dst_ip_value;
+ cmdline_fixed_string_t src_ip;
+ cmdline_ipaddr_t src_ip_value;
+ cmdline_fixed_string_t dst_port;
+ uint16_t dst_port_value;
+ cmdline_fixed_string_t src_port;
+ uint16_t src_port_value;
+ cmdline_fixed_string_t protocol;
+ uint8_t protocol_value;
+ cmdline_fixed_string_t mask;
+ uint8_t mask_value;
+ cmdline_fixed_string_t flags;
+ uint8_t flags_value;
+ cmdline_fixed_string_t priority;
+ uint8_t priority_value;
+ cmdline_fixed_string_t queue;
+ uint16_t queue_id;
+ cmdline_fixed_string_t index;
+ uint16_t index_value;
+};
+
+static void
+cmd_5tuple_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret = 0;
+ struct rte_5tuple_filter filter;
+ struct cmd_5tuple_filter_result *res = parsed_result;
+
+ memset(&filter, 0, sizeof(struct rte_5tuple_filter));
+
+ if (!strcmp(res->filter, "add_5tuple_filter")) {
+ filter.dst_ip_mask = (res->mask_value & 0x10) ? 0 : 1;
+ filter.src_ip_mask = (res->mask_value & 0x08) ? 0 : 1;
+ filter.dst_port_mask = (res->mask_value & 0x04) ? 0 : 1;
+ filter.src_port_mask = (res->mask_value & 0x02) ? 0 : 1;
+ filter.protocol = res->protocol_value;
+ filter.protocol_mask = (res->mask_value & 0x01) ? 0 : 1;
+ filter.priority = res->priority_value;
+ filter.tcp_flags = res->flags_value;
+
+ if (res->dst_ip_value.family == AF_INET)
+ /* no need to convert, already big endian. */
+ filter.dst_ip = res->dst_ip_value.addr.ipv4.s_addr;
+ else {
+ if (filter.dst_ip_mask == 0) {
+ printf("can not support ipv6 involved compare.\n");
+ return;
+ }
+ filter.dst_ip = 0;
+ }
+
+ if (res->src_ip_value.family == AF_INET)
+ /* no need to convert, already big endian. */
+ filter.src_ip = res->src_ip_value.addr.ipv4.s_addr;
+ else {
+ if (filter.src_ip_mask == 0) {
+ printf("can not support ipv6 involved compare.\n");
+ return;
+ }
+ filter.src_ip = 0;
+ }
+ /* need convert to big endian. */
+ filter.dst_port = rte_cpu_to_be_16(res->dst_port_value);
+ filter.src_port = rte_cpu_to_be_16(res->src_port_value);
+
+ ret = rte_eth_dev_add_5tuple_filter(res->port_id,
+ res->index_value, &filter, res->queue_id);
+ } else if (!strcmp(res->filter, "remove_5tuple_filter"))
+ ret = rte_eth_dev_remove_5tuple_filter(res->port_id,
+ res->index_value);
+ else if (!strcmp(res->filter, "get_5tuple_filter"))
+ get_5tuple_filter(res->port_id, res->index_value);
+ if (ret < 0)
+ printf("5tuple filter setting error: (%s)\n", strerror(-ret));
+}
+
+
+cmdline_parse_token_num_t cmd_5tuple_filter_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_dst_ip =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ dst_ip, "dst_ip");
+cmdline_parse_token_ipaddr_t cmd_5tuple_filter_dst_ip_value =
+ TOKEN_IPADDR_INITIALIZER(struct cmd_5tuple_filter_result,
+ dst_ip_value);
+cmdline_parse_token_string_t cmd_5tuple_filter_src_ip =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ src_ip, "src_ip");
+cmdline_parse_token_ipaddr_t cmd_5tuple_filter_src_ip_value =
+ TOKEN_IPADDR_INITIALIZER(struct cmd_5tuple_filter_result,
+ src_ip_value);
+cmdline_parse_token_string_t cmd_5tuple_filter_dst_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ dst_port, "dst_port");
+cmdline_parse_token_num_t cmd_5tuple_filter_dst_port_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ dst_port_value, UINT16);
+cmdline_parse_token_string_t cmd_5tuple_filter_src_port =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ src_port, "src_port");
+cmdline_parse_token_num_t cmd_5tuple_filter_src_port_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ src_port_value, UINT16);
+cmdline_parse_token_string_t cmd_5tuple_filter_protocol =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ protocol, "protocol");
+cmdline_parse_token_string_t cmd_5tuple_filter_protocol_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ protocol_value, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ mask, "mask");
+cmdline_parse_token_num_t cmd_5tuple_filter_mask_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ mask_value, INT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_flags =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ flags, "flags");
+cmdline_parse_token_num_t cmd_5tuple_filter_flags_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ flags_value, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_priority =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ priority, "priority");
+cmdline_parse_token_num_t cmd_5tuple_filter_priority_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ priority_value, UINT8);
+cmdline_parse_token_string_t cmd_5tuple_filter_queue =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ queue, "queue");
+cmdline_parse_token_num_t cmd_5tuple_filter_queue_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ queue_id, UINT16);
+cmdline_parse_token_string_t cmd_5tuple_filter_index =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ index, "index");
+cmdline_parse_token_num_t cmd_5tuple_filter_index_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_5tuple_filter_result,
+ index_value, UINT16);
+
+cmdline_parse_token_string_t cmd_5tuple_filter_add_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ filter, "add_5tuple_filter");
+cmdline_parse_inst_t cmd_add_5tuple_filter = {
+ .f = cmd_5tuple_filter_parsed,
+ .data = NULL,
+ .help_str = "add a 5tuple filter",
+ .tokens = {
+ (void *)&cmd_5tuple_filter_add_filter,
+ (void *)&cmd_5tuple_filter_port_id,
+ (void *)&cmd_5tuple_filter_dst_ip,
+ (void *)&cmd_5tuple_filter_dst_ip_value,
+ (void *)&cmd_5tuple_filter_src_ip,
+ (void *)&cmd_5tuple_filter_src_ip_value,
+ (void *)&cmd_5tuple_filter_dst_port,
+ (void *)&cmd_5tuple_filter_dst_port_value,
+ (void *)&cmd_5tuple_filter_src_port,
+ (void *)&cmd_5tuple_filter_src_port_value,
+ (void *)&cmd_5tuple_filter_protocol,
+ (void *)&cmd_5tuple_filter_protocol_value,
+ (void *)&cmd_5tuple_filter_mask,
+ (void *)&cmd_5tuple_filter_mask_value,
+ (void *)&cmd_5tuple_filter_flags,
+ (void *)&cmd_5tuple_filter_flags_value,
+ (void *)&cmd_5tuple_filter_priority,
+ (void *)&cmd_5tuple_filter_priority_value,
+ (void *)&cmd_5tuple_filter_queue,
+ (void *)&cmd_5tuple_filter_queue_id,
+ (void *)&cmd_5tuple_filter_index,
+ (void *)&cmd_5tuple_filter_index_value,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_5tuple_filter_remove_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ filter, "remove_5tuple_filter");
+cmdline_parse_inst_t cmd_remove_5tuple_filter = {
+ .f = cmd_5tuple_filter_parsed,
+ .data = NULL,
+ .help_str = "remove a 5tuple filter",
+ .tokens = {
+ (void *)&cmd_5tuple_filter_remove_filter,
+ (void *)&cmd_5tuple_filter_port_id,
+ (void *)&cmd_5tuple_filter_index,
+ (void *)&cmd_5tuple_filter_index_value,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_5tuple_filter_get_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ filter, "get_5tuple_filter");
+cmdline_parse_inst_t cmd_get_5tuple_filter = {
+ .f = cmd_5tuple_filter_parsed,
+ .data = NULL,
+ .help_str = "get a 5tuple filter",
+ .tokens = {
+ (void *)&cmd_5tuple_filter_get_filter,
+ (void *)&cmd_5tuple_filter_port_id,
+ (void *)&cmd_5tuple_filter_index,
+ (void *)&cmd_5tuple_filter_index_value,
+ NULL,
+ },
+};
+
+/* *** ADD/REMOVE A flex FILTER *** */
+struct cmd_flex_filter_result {
+ cmdline_fixed_string_t filter;
+ uint8_t port_id;
+ cmdline_fixed_string_t len;
+ uint8_t len_value;
+ cmdline_fixed_string_t bytes;
+ cmdline_fixed_string_t bytes_value;
+ cmdline_fixed_string_t mask;
+ cmdline_fixed_string_t mask_value;
+ cmdline_fixed_string_t priority;
+ uint8_t priority_value;
+ cmdline_fixed_string_t queue;
+ uint16_t queue_id;
+ cmdline_fixed_string_t index;
+ uint16_t index_value;
+};
+
+static int xdigit2val(unsigned char c)
+{
+ int val;
+ if (isdigit(c))
+ val = c - '0';
+ else if (isupper(c))
+ val = c - 'A' + 10;
+ else
+ val = c - 'a' + 10;
+ return val;
+}
+
+static void
+cmd_flex_filter_parsed(void *parsed_result,
+ __attribute__((unused)) struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret = 0;
+ struct rte_flex_filter filter;
+ struct cmd_flex_filter_result *res = parsed_result;
+ char *bytes_ptr, *mask_ptr;
+ uint16_t len, i, j;
+ char c;
+ int val, mod = 0;
+ uint32_t dword = 0;
+ uint8_t byte = 0;
+ uint8_t hex = 0;
+
+ if (!strcmp(res->filter, "add_flex_filter")) {
+ if (res->len_value > 128) {
+ printf("the len exceed the max length 128\n");
+ return;
+ }
+ memset(&filter, 0, sizeof(struct rte_flex_filter));
+ filter.len = res->len_value;
+ filter.priority = res->priority_value;
+ bytes_ptr = res->bytes_value;
+ mask_ptr = res->mask_value;
+
+ j = 0;
+ /* translate bytes string to uint_32 array. */
+ if (bytes_ptr[0] == '0' && ((bytes_ptr[1] == 'x') ||
+ (bytes_ptr[1] == 'X')))
+ bytes_ptr += 2;
+ len = strnlen(bytes_ptr, res->len_value * 2);
+ if (len == 0 || (len % 8 != 0)) {
+ printf("please check len and bytes input\n");
+ return;
+ }
+ for (i = 0; i < len; i++) {
+ c = bytes_ptr[i];
+ if (isxdigit(c) == 0) {
+ /* invalid characters. */
+ printf("invalid input\n");
+ return;
+ }
+ val = xdigit2val(c);
+ mod = i % 8;
+ if (i % 2) {
+ byte |= val;
+ dword |= byte << (4 * mod - 4);
+ byte = 0;
+ } else
+ byte |= val << 4;
+ if (mod == 7) {
+ filter.dwords[j] = dword;
+ printf("dwords[%d]:%08x ", j, filter.dwords[j]);
+ j++;
+ dword = 0;
+ }
+ }
+ printf("\n");
+ /* translate mask string to uint8_t array. */
+ j = 0;
+ if (mask_ptr[0] == '0' && ((mask_ptr[1] == 'x') ||
+ (mask_ptr[1] == 'X')))
+ mask_ptr += 2;
+ len = strnlen(mask_ptr, (res->len_value+3)/4);
+ if (len == 0) {
+ printf("invalid input\n");
+ return;
+ }
+ for (i = 0; i < len; i++) {
+ c = mask_ptr[i];
+ if (isxdigit(c) == 0) {
+ /* invalid characters. */
+ printf("invalid input\n");
+ return;
+ }
+ val = xdigit2val(c);
+ hex |= (uint8_t)(val & 0x8) >> 3;
+ hex |= (uint8_t)(val & 0x4) >> 1;
+ hex |= (uint8_t)(val & 0x2) << 1;
+ hex |= (uint8_t)(val & 0x1) << 3;
+ if (i % 2) {
+ byte |= hex << 4;
+ filter.mask[j] = byte;
+ printf("mask[%d]:%02x ", j, filter.mask[j]);
+ j++;
+ byte = 0;
+ } else
+ byte |= hex;
+ hex = 0;
+ }
+ printf("\n");
+ printf("call function rte_eth_dev_add_flex_filter: "
+ "index = %d, queue-id = %d, len = %d, priority = %d\n",
+ res->index_value, res->queue_id,
+ filter.len, filter.priority);
+ ret = rte_eth_dev_add_flex_filter(res->port_id, res->index_value,
+ &filter, res->queue_id);
+
+ } else if (!strcmp(res->filter, "remove_flex_filter"))
+ ret = rte_eth_dev_remove_flex_filter(res->port_id,
+ res->index_value);
+ else if (!strcmp(res->filter, "get_flex_filter"))
+ get_flex_filter(res->port_id, res->index_value);
+
+ if (ret < 0)
+ printf("flex filter setting error: (%s)\n", strerror(-ret));
+}
+
+cmdline_parse_token_num_t cmd_flex_filter_port_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
+ port_id, UINT8);
+cmdline_parse_token_string_t cmd_flex_filter_len =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ len, "len");
+cmdline_parse_token_string_t cmd_flex_filter_len_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
+ len_value, UINT8);
+cmdline_parse_token_string_t cmd_flex_filter_bytes =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ bytes, "bytes");
+cmdline_parse_token_string_t cmd_flex_filter_bytes_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ bytes_value, NULL);
+cmdline_parse_token_string_t cmd_flex_filter_mask =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ mask, "mask");
+cmdline_parse_token_string_t cmd_flex_filter_mask_value =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ mask_value, NULL);
+cmdline_parse_token_string_t cmd_flex_filter_priority =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ priority, "priority");
+cmdline_parse_token_num_t cmd_flex_filter_priority_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
+ priority_value, UINT8);
+cmdline_parse_token_string_t cmd_flex_filter_queue =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ queue, "queue");
+cmdline_parse_token_num_t cmd_flex_filter_queue_id =
+ TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
+ queue_id, UINT16);
+cmdline_parse_token_string_t cmd_flex_filter_index =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ index, "index");
+cmdline_parse_token_num_t cmd_flex_filter_index_value =
+ TOKEN_NUM_INITIALIZER(struct cmd_flex_filter_result,
+ index_value, UINT16);
+cmdline_parse_token_string_t cmd_flex_filter_add_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ filter, "add_flex_filter");
+cmdline_parse_inst_t cmd_add_flex_filter = {
+ .f = cmd_flex_filter_parsed,
+ .data = NULL,
+ .help_str = "add a flex filter",
+ .tokens = {
+ (void *)&cmd_flex_filter_add_filter,
+ (void *)&cmd_flex_filter_port_id,
+ (void *)&cmd_flex_filter_len,
+ (void *)&cmd_flex_filter_len_value,
+ (void *)&cmd_flex_filter_bytes,
+ (void *)&cmd_flex_filter_bytes_value,
+ (void *)&cmd_flex_filter_mask,
+ (void *)&cmd_flex_filter_mask_value,
+ (void *)&cmd_flex_filter_priority,
+ (void *)&cmd_flex_filter_priority_value,
+ (void *)&cmd_flex_filter_queue,
+ (void *)&cmd_flex_filter_queue_id,
+ (void *)&cmd_flex_filter_index,
+ (void *)&cmd_flex_filter_index_value,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_flex_filter_remove_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ filter, "remove_flex_filter");
+cmdline_parse_inst_t cmd_remove_flex_filter = {
+ .f = cmd_flex_filter_parsed,
+ .data = NULL,
+ .help_str = "remove a flex filter",
+ .tokens = {
+ (void *)&cmd_flex_filter_remove_filter,
+ (void *)&cmd_flex_filter_port_id,
+ (void *)&cmd_flex_filter_index,
+ (void *)&cmd_flex_filter_index_value,
+ NULL,
+ },
+};
+
+cmdline_parse_token_string_t cmd_flex_filter_get_filter =
+ TOKEN_STRING_INITIALIZER(struct cmd_flex_filter_result,
+ filter, "get_flex_filter");
+cmdline_parse_inst_t cmd_get_flex_filter = {
+ .f = cmd_flex_filter_parsed,
+ .data = NULL,
+ .help_str = "get a flex filter",
+ .tokens = {
+ (void *)&cmd_flex_filter_get_filter,
+ (void *)&cmd_flex_filter_port_id,
+ (void *)&cmd_flex_filter_index,
+ (void *)&cmd_flex_filter_index_value,
+ NULL,
+ },
+};
+
/* ******************************************************************************** */
/* list of instructions */
@@ -5624,6 +6516,21 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_config_rss_hash_key,
(cmdline_parse_inst_t *)&cmd_dump,
(cmdline_parse_inst_t *)&cmd_dump_one,
+ (cmdline_parse_inst_t *)&cmd_add_ethertype_filter,
+ (cmdline_parse_inst_t *)&cmd_remove_ethertype_filter,
+ (cmdline_parse_inst_t *)&cmd_get_ethertype_filter,
+ (cmdline_parse_inst_t *)&cmd_add_syn_filter,
+ (cmdline_parse_inst_t *)&cmd_remove_syn_filter,
+ (cmdline_parse_inst_t *)&cmd_get_syn_filter,
+ (cmdline_parse_inst_t *)&cmd_add_2tuple_filter,
+ (cmdline_parse_inst_t *)&cmd_remove_2tuple_filter,
+ (cmdline_parse_inst_t *)&cmd_get_2tuple_filter,
+ (cmdline_parse_inst_t *)&cmd_add_5tuple_filter,
+ (cmdline_parse_inst_t *)&cmd_remove_5tuple_filter,
+ (cmdline_parse_inst_t *)&cmd_get_5tuple_filter,
+ (cmdline_parse_inst_t *)&cmd_add_flex_filter,
+ (cmdline_parse_inst_t *)&cmd_remove_flex_filter,
+ (cmdline_parse_inst_t *)&cmd_get_flex_filter,
NULL,
};
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 52ad01a..7a505a1 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1871,3 +1871,150 @@ set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
return diag;
}
+void
+get_ethertype_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_ethertype_filter filter;
+ int ret = 0;
+ uint16_t rx_queue;
+
+ memset(&filter, 0, sizeof(filter));
+ ret = rte_eth_dev_get_ethertype_filter(port_id, index,
+ &filter, &rx_queue);
+ if (ret < 0) {
+ if (ret == (-ENOENT))
+ printf("filter[%d] is not enabled\n", index);
+ else
+ printf("get ethertype filter fails(%s)\n", strerror(-ret));
+ return;
+ } else {
+ printf("filter[%d]:\n", index);
+ printf(" ethertype: 0x%04x\n",
+ rte_le_to_cpu_32(filter.ethertype));
+ printf(" priority: %s, %d\n",
+ filter.priority_en ? "enable" : "disable",
+ filter.priority);
+ printf(" queue: %d\n", rx_queue);
+ }
+}
+
+void
+get_syn_filter(uint8_t port_id)
+{
+ struct rte_syn_filter filter;
+ int ret = 0;
+ uint16_t rx_queue;
+
+ memset(&filter, 0, sizeof(filter));
+ ret = rte_eth_dev_get_syn_filter(port_id, &filter, &rx_queue);
+
+ if (ret < 0) {
+ if (ret == (-ENOENT))
+ printf("syn filter is not enabled\n");
+ else
+ printf("get syn filter fails(%s)\n", strerror(-ret));
+ return;
+ }
+ printf("syn filter: priority: %s, queue: %d\n",
+ filter.hig_pri ? "high" : "low",
+ rx_queue);
+}
+void
+get_2tuple_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_2tuple_filter filter;
+ int ret = 0;
+ uint16_t rx_queue;
+
+ memset(&filter, 0, sizeof(filter));
+ ret = rte_eth_dev_get_2tuple_filter(port_id, index,
+ &filter, &rx_queue);
+ if (ret < 0) {
+ if (ret == (-ENOENT))
+ printf("filter[%d] is not enabled\n", index);
+ else
+ printf("get 2tuple filter fails(%s)\n", strerror(-ret));
+ return;
+ } else {
+ printf("filter[%d]:\n", index);
+ printf(" Destination Port: 0x%04x mask: %d\n",
+ rte_be_to_cpu_16(filter.dst_port),
+ filter.dst_port_mask ? 0 : 1);
+ printf(" protocol: 0x%02x mask:%d tcp_flags: 0x%02x\n",
+ filter.protocol, filter.protocol_mask ? 0 : 1,
+ filter.tcp_flags);
+ printf(" priority: %d queue: %d\n",
+ filter.priority, rx_queue);
+ }
+}
+
+void
+get_5tuple_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_5tuple_filter filter;
+ int ret = 0;
+ uint16_t rx_queue;
+
+ memset(&filter, 0, sizeof(filter));
+ ret = rte_eth_dev_get_5tuple_filter(port_id, index,
+ &filter, &rx_queue);
+ if (ret < 0) {
+ if (ret == (-ENOENT))
+ printf("filter[%d] is not enabled\n", index);
+ else
+ printf("get 5tuple filter fails(%s)\n", strerror(-ret));
+ return;
+ } else {
+ printf("filter[%d]:\n", index);
+ printf(" Destination IP: 0x%08x mask: %d\n",
+ (unsigned)rte_be_to_cpu_32(filter.dst_ip),
+ filter.dst_ip_mask ? 0 : 1);
+ printf(" Source IP: 0x%08x mask: %d\n",
+ (unsigned)rte_be_to_cpu_32(filter.src_ip),
+ filter.src_ip_mask ? 0 : 1);
+ printf(" Destination Port: 0x%04x mask: %d\n",
+ rte_be_to_cpu_16(filter.dst_port),
+ filter.dst_port_mask ? 0 : 1);
+ printf(" Source Port: 0x%04x mask: %d\n",
+ rte_be_to_cpu_16(filter.src_port),
+ filter.src_port_mask ? 0 : 1);
+ printf(" protocol: 0x%02x mask: %d\n",
+ filter.protocol,
+ filter.protocol_mask ? 0 : 1);
+ printf(" priority: %d flags: 0x%02x queue: %d\n",
+ filter.priority, filter.tcp_flags, rx_queue);
+ }
+}
+void
+get_flex_filter(uint8_t port_id, uint16_t index)
+
+{
+ struct rte_flex_filter filter;
+ int ret = 0;
+ uint16_t rx_queue;
+ int i, j;
+
+ memset(&filter, 0, sizeof(filter));
+ ret = rte_eth_dev_get_flex_filter(port_id, index,
+ &filter, &rx_queue);
+ if (ret < 0) {
+ if (ret == (-ENOENT))
+ printf("filter[%d] is not enabled\n", index);
+ else
+ printf("get flex filter fails(%s)\n", strerror(-ret));
+ return;
+ } else {
+ printf("filter[%d]: ", index);
+ printf("\n length: %d", filter.len);
+ printf("\n dword[]: 0x");
+ for (i = 0; i < 32; i++)
+ printf("%08x ", (unsigned)rte_be_to_cpu_32(filter.dwords[i]));
+ printf("\n mask[]: 0b");
+ for (i = 0; i < 16; i++) {
+ for (j = 0; j < 8; j++)
+ printf("%c", (filter.mask[i] & (1 << j)) ? '1' : '0');
+ }
+ printf("\n priority: %d queue: %d\n",
+ filter.priority, rx_queue);
+ }
+}
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 4fabf1c..d750a35 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -538,6 +538,11 @@ int set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate,
void port_rss_hash_conf_show(portid_t port_id, int show_rss_key);
void port_rss_hash_key_update(portid_t port_id, uint8_t *hash_key);
+void get_syn_filter(uint8_t port_id);
+void get_ethertype_filter(uint8_t port_id, uint16_t index);
+void get_2tuple_filter(uint8_t port_id, uint16_t index);
+void get_5tuple_filter(uint8_t port_id, uint16_t index);
+void get_flex_filter(uint8_t port_id, uint16_t index);
/*
* Work-around of a compilation error with ICC on invocations of the
--
1.8.1.4
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter
2014-06-16 7:31 [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Jingjing Wu
` (3 preceding siblings ...)
2014-06-16 7:31 ` [dpdk-dev] [PATCH v4 4/4] app/test-pmd: add commands in testpmd for NIC filters Jingjing Wu
@ 2014-06-16 14:15 ` Cao, Waterman
2014-06-16 18:00 ` Thomas Monjalon
5 siblings, 0 replies; 7+ messages in thread
From: Cao, Waterman @ 2014-06-16 14:15 UTC (permalink / raw)
To: Wu, Jingjing, dev
Tested-by: Waterman Cao <waterman.cao@intel.com>
This patch includes 4 files, and has been tested by Intel.
Please see test environment information as the following:
Fedora 20 x86_64, Linux Kernel 3.11.10-301, GCC 4.8.2 Intel Xeon CPU E5-2680 v2 @ 2.80GHz
NIC: Intel Niantic 82599, Intel i350, Intel 82580 and Intel 82576
We verified ethertype filter, 2-tuple filter, 5-tuple filter, flex filter and SYN filter with above NICs.
Total cases Passed Failed
27 25 2
Failures were caused by HW issues, no impact on functionality.
Please see example: how to distribute specific packet to assigned queue.
Firstly, launch testpmd firstly, then run the following command:
---add syn filter ---
testpmd> add_syn_filter (port_id) priority (high|low) queue (queue_id)
---get syn filter info ---
testpmd> get_syn_filter (port_id)
---remove syn filter ---
testpmd> remove_syn_filter (port_id)
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter
2014-06-16 7:31 [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Jingjing Wu
` (4 preceding siblings ...)
2014-06-16 14:15 ` [dpdk-dev] [PATCH v4 0/4] NIC filters support for generic filter Cao, Waterman
@ 2014-06-16 18:00 ` Thomas Monjalon
5 siblings, 0 replies; 7+ messages in thread
From: Thomas Monjalon @ 2014-06-16 18:00 UTC (permalink / raw)
To: Jingjing Wu; +Cc: dev
2014-06-16 15:31, Jingjing Wu:
> A generic filter mechanism for handling special packet is required.
> It will allow filters to be set in HW when available so that specific
> packet may be filtered by NICs to specific descriptor queues for
> processing. Currently only Flow Director for Intel's 10GbE 82599
> devices is available. Other types of filter are not support.
> NIC filters list below are implemented in this patchset:
> ethertype filter, syn filter, 2tuple filter and flex filter for 82580 and i350
> ethertype filter, syn filter, 5tuple filter for 82576
> ethertype filter, syn filter and 5tuple filter for 82599
Reviewed-by: Vladimir Medvedkin <medvedkinv@gmail.com>
Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
I've fixed some doxygen comments and logs.
Applied for version 1.7.0.
Hope to see more patches about filtering in coming weeks.
Thanks
--
Thomas
^ permalink raw reply [flat|nested] 7+ messages in thread