* [dpdk-dev] [PATCH 1/4][PMD][GENERIC_FILTER]add ethdev APIs for NIC filters of generic filter feature
2014-05-20 3:53 [dpdk-dev] [PATCH 0/4][PMD][GENERIC_FILTER] ***NIC filters support of generic feature*** Jingjing Wu
@ 2014-05-20 3:53 ` Jingjing Wu
2014-05-20 3:53 ` [dpdk-dev] [PATCH 2/4][PMD][GENERIC_FILTER]add igb " Jingjing Wu
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Jingjing Wu @ 2014-05-20 3:53 UTC (permalink / raw)
To: dev
This patch add 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 | 300 +++++++++++++++++++++++++++++
lib/librte_ether/rte_ethdev.h | 428 +++++++++++++++++++++++++++++++++++++++++-
2 files changed, 727 insertions(+), 1 deletion(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a5727dd..ec411db 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>
@@ -2335,3 +2336,302 @@ rte_eth_dev_bypass_wd_reset(uint8_t port_id)
return 0;
}
#endif
+
+int
+rte_eth_dev_add_syn_filter(uint8_t port_id, uint8_t high_pri,
+ uint8_t rx_queue)
+{
+ struct rte_eth_dev *dev;
+ struct rte_syn_filter filter;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return (-ENODEV);
+ }
+
+ dev = &rte_eth_devices[port_id];
+ filter.enable = 1;
+ filter.hig_pri = high_pri;
+
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_syn_filter, -ENOTSUP);
+ return (*dev->dev_ops->set_syn_filter)(dev, &filter, rx_queue);
+}
+
+int
+rte_eth_dev_remove_syn_filter(uint8_t port_id)
+{
+ struct rte_eth_dev *dev;
+ struct rte_syn_filter filter;
+
+ if (port_id >= nb_ports) {
+ PMD_DEBUG_TRACE("Invalid port_id=%d\n", port_id);
+ return (-ENODEV);
+ }
+
+ dev = &rte_eth_devices[port_id];
+ filter.enable = 0;
+ filter.hig_pri = 0;
+
+ FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_syn_filter, -ENOTSUP);
+ return (*dev->dev_ops->set_syn_filter)(dev, &filter, 0);
+}
+
+int
+rte_eth_dev_get_syn_filter(uint8_t port_id,
+ struct rte_syn_filter *filter, uint8_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, uint8_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, uint8_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, uint8_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, uint8_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, uint8_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->l4type == RTE_FILTER_L4TYPE_NONE) &&
+ (filter->dst_port_mask == 0 || filter->src_port_mask == 0)) {
+ PMD_DEBUG_TRACE(" the L4 protocol type is none, port are meaningless " \
+ "should not involve!\n");
+ 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, uint8_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, uint8_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, uint8_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 dea7471..1e5c09b 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -808,6 +808,80 @@ struct rte_eth_dev_callback;
/** @internal Structure to keep track of registered callbacks */
TAILQ_HEAD(rte_eth_dev_cb_list, rte_eth_dev_callback);
+
+/**
+ * Possible l4type of 5tuple filters.
+ */
+enum rte_filter_l4type{
+ RTE_FILTER_L4TYPE_TCP = 0,
+ RTE_FILTER_L4TYPE_UDP,
+ RTE_FILTER_L4TYPE_SCTP,
+ RTE_FILTER_L4TYPE_NONE,
+};
+#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 enable; /**<1 means enable, 0 means disable*/
+ uint8_t hig_pri; /**< 1 means higher pri than 2tuple,5tupe, and flex filter, 0 means llower 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{ /** for E1000 filters*/
+ uint16_t len;
+ uint32_t dwords[32]; /**<flex bytes in big endian*/
+ uint8_t mask[16]; /**<if mask bit is 1b, means 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*/
+ enum rte_filter_l4type l4type; /**< l4type to match: TCP/UDP/SCTP/NONE. */
+ 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*/
+ l4type_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*
@@ -1076,6 +1150,69 @@ 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_set_syn_filter_t)(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_t rx_queue);
+/**< @internal Set syn filter rule on an Ethernet device */
+
+typedef int (*eth_get_syn_filter_t)(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_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,
+ uint8_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,
+ uint8_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,
+ uint8_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,
+ uint8_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,
+ uint8_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,
+ uint8_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,
+ uint8_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,
+ uint8_t *rx_queue);
+/**< @internal Get a flex filter rule on an Ethernet device */
/**
* @internal A structure containing the functions exported by an Ethernet driver.
@@ -1152,7 +1289,20 @@ struct eth_dev_ops {
bypass_ver_show_t bypass_ver_show;
bypass_wd_reset_t bypass_wd_reset;
#endif
-
+ eth_set_syn_filter_t set_syn_filter; /**< set 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*/
};
/**
@@ -2859,6 +3009,282 @@ int rte_eth_dev_bypass_wd_timeout_show(uint8_t port, uint32_t *wd_timeout);
*/
int rte_eth_dev_bypass_wd_reset(uint8_t port);
+/**
+ * add syn filter
+ *
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @param rx_queue
+ * The index of the RX queue where to store RX packets matching the syn filter.
+ * @param high_pri
+ * 1 means higher pri than 2tuple,5tupe, and flex filter, 0 means lower priority
+ * @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, uint8_t high_pri,
+ uint8_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, uint8_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, uint8_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 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, uint8_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, uint8_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, uint8_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, l4type 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, uint8_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, uint8_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, uint8_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, uint8_t *rx_queue);
+
#ifdef __cplusplus
}
#endif
--
1.8.1.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [PATCH 2/4][PMD][GENERIC_FILTER]add igb NIC filters of generic filter feature
2014-05-20 3:53 [dpdk-dev] [PATCH 0/4][PMD][GENERIC_FILTER] ***NIC filters support of generic feature*** Jingjing Wu
2014-05-20 3:53 ` [dpdk-dev] [PATCH 1/4][PMD][GENERIC_FILTER]add ethdev APIs for NIC filters of generic filter feature Jingjing Wu
@ 2014-05-20 3:53 ` Jingjing Wu
2014-05-20 3:53 ` [dpdk-dev] [PATCH 3/4][PMD][GENERIC_FILTER]add ixgbe " Jingjing Wu
2014-05-20 3:53 ` [dpdk-dev] [PATCH 4/4][PMD][GENERIC_FILTER] add commands in testpmd for NIC filters Jingjing Wu
3 siblings, 0 replies; 5+ messages in thread
From: Jingjing Wu @ 2014-05-20 3:53 UTC (permalink / raw)
To: dev
This patch adds following igb NIC filters implement for intel NIC 82580 and i350
syn filter, ethertype filter, 2tuple filter, flex filter
Signed-off-by: jingjing.wu <jingjing.wu@intel.com>
---
lib/librte_pmd_e1000/e1000_ethdev.h | 38 +++
lib/librte_pmd_e1000/igb_ethdev.c | 512 ++++++++++++++++++++++++++++++++++++
2 files changed, 550 insertions(+)
diff --git a/lib/librte_pmd_e1000/e1000_ethdev.h b/lib/librte_pmd_e1000/e1000_ethdev.h
index d09064e..6b11289 100644
--- a/lib/librte_pmd_e1000/e1000_ethdev.h
+++ b/lib/librte_pmd_e1000/e1000_ethdev.h
@@ -52,6 +52,44 @@
#define E1000_CTRL_EXT_EXTEND_VLAN (1<<26) /* EXTENDED VLAN */
#define IGB_VFTA_SIZE 128
+#define IGB_MAX_RX_QUEUE_NUM 8
+
+#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 IXGBE_WUFC_FLEX_HQ 0x00004000
+
/* 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 673b4de..478688f 100644
--- a/lib/librte_pmd_e1000/igb_ethdev.c
+++ b/lib/librte_pmd_e1000/igb_ethdev.c
@@ -123,6 +123,28 @@ 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_set_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_t rx_queue);
+static int eth_igb_get_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_t *rx_queue);
+static int eth_igb_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_ethertype_filter *filter, uint8_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, uint8_t *rx_queue);
+static int eth_igb_add_2tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_2tuple_filter *filter, uint8_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, uint8_t *rx_queue);
+static int eth_igb_add_flex_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_flex_filter *filter, uint8_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, uint8_t *rx_queue);
+
/*
* Define VF Stats MACRO for Non "cleared on read" register
*/
@@ -193,6 +215,17 @@ static struct eth_dev_ops eth_igb_ops = {
.mac_addr_remove = eth_igb_rar_clear,
.reta_update = eth_igb_rss_reta_update,
.reta_query = eth_igb_rss_reta_query,
+ .set_syn_filter = eth_igb_set_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,
};
/*
@@ -2182,3 +2215,482 @@ 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) \
+ return -ENOSYS;\
+}while(0)
+
+/*
+ *set the syn filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * syn: 1 means enable, 0 means disable.
+ * rx_queue: the queue id the filter assigned to
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+eth_igb_set_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_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));
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+
+ if (filter->enable){
+ 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);
+ }else
+ synqf = 0;
+
+ 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;
+}
+
+/*
+ *get the syn filter's info
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * *syn: pointer to syn value (1 means enable, 0 means disable).
+ * *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, uint8_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));
+ rfctl = E1000_READ_REG(hw, E1000_RFCTL);
+ filter->enable = (synqf & E1000_SYN_FILTER_ENABLE)? 1 : 0;
+ 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;
+}
+
+/*
+ *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, uint8_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, uint8_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);
+}
+
+/*
+ *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, uint8_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(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(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, uint8_t *rx_queue)
+{
+ struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t imir, ttqf;
+
+ MAC_TYPE_FILTER_SUP(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;
+ 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, uint8_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(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 = IXGBE_WUFC_FLEX_HQ | (E1000_WUFC_FLX0 << index);
+ if ((wufc & en_bits) == en_bits)
+ return (-EINVAL); /**the filter is enabled*/
+
+ E1000_WRITE_REG(hw, E1000_WUFC, wufc | IXGBE_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(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, uint8_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(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 = IXGBE_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);
+}
--
1.8.1.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [PATCH 3/4][PMD][GENERIC_FILTER]add ixgbe NIC filters of generic filter feature
2014-05-20 3:53 [dpdk-dev] [PATCH 0/4][PMD][GENERIC_FILTER] ***NIC filters support of generic feature*** Jingjing Wu
2014-05-20 3:53 ` [dpdk-dev] [PATCH 1/4][PMD][GENERIC_FILTER]add ethdev APIs for NIC filters of generic filter feature Jingjing Wu
2014-05-20 3:53 ` [dpdk-dev] [PATCH 2/4][PMD][GENERIC_FILTER]add igb " Jingjing Wu
@ 2014-05-20 3:53 ` Jingjing Wu
2014-05-20 3:53 ` [dpdk-dev] [PATCH 4/4][PMD][GENERIC_FILTER] add commands in testpmd for NIC filters Jingjing Wu
3 siblings, 0 replies; 5+ messages in thread
From: Jingjing Wu @ 2014-05-20 3:53 UTC (permalink / raw)
To: dev
This patch adds following ixgbe NIC filters implement for intel NIC 82599
syn filter, ethertype filter, 5tuple filter
Signed-off-by: jingjing.wu <jingjing.wu@intel.com>
---
lib/librte_pmd_ixgbe/ixgbe_ethdev.c | 365 ++++++++++++++++++++++++++++++++++++
lib/librte_pmd_ixgbe/ixgbe_ethdev.h | 33 ++++
2 files changed, 398 insertions(+)
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
index 89ab4aa..49ff0d1 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.c
@@ -181,6 +181,22 @@ static int ixgbe_mirror_rule_set(struct rte_eth_dev *dev,
static int ixgbe_mirror_rule_reset(struct rte_eth_dev *dev,
uint8_t rule_id);
+static int ixgbe_set_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_t rx_queue);
+static int ixgbe_get_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_t *rx_queue);
+static int ixgbe_add_ethertype_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_ethertype_filter *filter, uint8_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, uint8_t *rx_queue);
+static int ixgbe_add_5tuple_filter(struct rte_eth_dev *dev, uint16_t index,
+ struct rte_5tuple_filter *filter, uint8_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, uint8_t *rx_queue);
+
/*
* Define VF Stats MACRO for Non "cleared on read" register
*/
@@ -300,6 +316,14 @@ static struct eth_dev_ops ixgbe_eth_dev_ops = {
.bypass_ver_show = ixgbe_bypass_ver_show,
.bypass_wd_reset = ixgbe_bypass_wd_reset,
#endif /* RTE_NIC_BYPASS */
+ .set_syn_filter = ixgbe_set_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,
};
/*
@@ -3060,3 +3084,344 @@ ixgbe_mirror_rule_reset(struct rte_eth_dev *dev, uint8_t rule_id)
return 0;
}
+
+/*
+ * set the syn filter
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * syn: 1 means enable, 0 means disable.
+ * rx_queue: the queue id the filter assigned to
+ *
+ * @return
+ * - On success, zero.
+ * - On failure, a negative value.
+ */
+static int
+ixgbe_set_syn_filter(struct rte_eth_dev *dev,
+ struct rte_syn_filter *filter, uint8_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 (filter->enable)
+ synqf = (uint32_t)(((rx_queue << IXGBE_SYN_FILTER_QUEUE_SHIFT) &
+ IXGBE_SYN_FILTER_QUEUE) | IXGBE_SYN_FILTER_ENABLE);
+ else
+ synqf &= ~(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;
+}
+
+/*
+ * get the syn filter's info
+ *
+ * @param
+ * dev: Pointer to struct rte_eth_dev.
+ * *syn: pointer to syn value (1 means enable, 0 means disable).
+ * *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, uint8_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);
+ filter->enable = (synqf & IXGBE_SYN_FILTER_ENABLE) ? 1 : 0;
+ filter->hig_pri = (synqf & IXGBE_SYN_FILTER_SYNQFP) ? 1 : 0;
+ *rx_queue = (uint8_t)((synqf & IXGBE_SYN_FILTER_QUEUE)>> 1);
+
+ return 0;
+}
+
+/*
+ * 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,
+ uint8_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,
+ uint8_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);
+}
+
+/*
+ * 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, uint8_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;
+
+ 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*/
+
+ ftqf = IXGBE_READ_REG(hw, IXGBE_FTQF(index));
+ if (ftqf & IXGBR_FTQF_ENABLE)
+ return (-EINVAL); /** filter index is in use*/
+ ftqf = 0;
+
+ sdpqf = (uint32_t)(filter->dst_port << IXGBE_SDQPF_DSTPORT_SHIFT);
+ sdpqf = sdpqf |(filter->src_port & IXGBE_SDQPF_SRCPORT);
+
+ ftqf |= (uint32_t)(filter->l4type & IXGBR_FTQF_PROTOCOL);
+ ftqf |= (uint32_t)((filter->priority << IXGBR_FTQF_PRIORITY_SHIFT) & IXGBR_FTQF_PRIORITY);
+ if (filter->src_ip_mask == 1) /** 1b means not compare*/
+ ftqf |= IXGBR_FTQF_SRCIP_MASK;
+ if (filter->dst_ip_mask == 1)
+ ftqf |= IXGBR_FTQF_DSTIP_MASK;
+ if (filter->src_port_mask == 1)
+ ftqf |= IXGBR_FTQF_SRCPORT_MASK;
+ if (filter->dst_port_mask == 1)
+ ftqf |= IXGBR_FTQF_DSTPORT_MASK;
+ if (filter->l4type_mask == 1)
+ ftqf |= IXGBR_FTQF_L4TYPE_MASK;
+ ftqf |= IXGBR_FTQF_POOL_MASK;
+ ftqf |= IXGBR_FTQF_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_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, uint8_t *rx_queue)
+{
+ struct ixgbe_hw *hw= IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ uint32_t sdpqf, ftqf, l34timir;
+
+ 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 & IXGBR_FTQF_ENABLE){
+ filter->l4type = (enum rte_filter_l4type)(ftqf & IXGBR_FTQF_PROTOCOL);
+ filter->priority = (ftqf & IXGBR_FTQF_PRIORITY) >> IXGBR_FTQF_PRIORITY_SHIFT;
+ filter->src_ip_mask = (ftqf & IXGBR_FTQF_SRCIP_MASK) ? 1 : 0;
+ filter->dst_ip_mask = (ftqf & IXGBR_FTQF_DSTIP_MASK) ? 1 : 0;
+ filter->src_port_mask = (ftqf & IXGBR_FTQF_SRCPORT_MASK) ? 1 : 0;
+ filter->dst_port_mask = (ftqf & IXGBR_FTQF_DSTPORT_MASK) ? 1 : 0;
+ filter->l4type_mask = (ftqf & IXGBR_FTQF_L4TYPE_MASK) ? 1 : 0;
+
+ sdpqf = IXGBE_READ_REG(hw, IXGBE_SDPQF(index));
+ filter->dst_port = (sdpqf & IXGBE_SDQPF_DSTPORT) >> IXGBE_SDQPF_DSTPORT_SHIFT;
+ filter->src_port = sdpqf & IXGBE_SDQPF_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);
+}
diff --git a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
index 9d7e93f..7c6139b 100644
--- a/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
+++ b/lib/librte_pmd_ixgbe/ixgbe_ethdev.h
@@ -67,6 +67,39 @@
#define IXGBE_LPBK_82599_NONE 0x0 /* Default value. Loopback is disabled. */
#define IXGBE_LPBK_82599_TX_RX 0x1 /* Tx->Rx loopback operation is enabled. */
+#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_SDQPF_DSTPORT 0xFFFF0000 /** dst port field */
+#define IXGBE_SDQPF_DSTPORT_SHIFT 16 /** dst port field shift*/
+#define IXGBE_SDQPF_SRCPORT 0x0000FFFF /** src port field */
+#define IXGBR_FTQF_PROTOCOL 0x00000003 /** protocol */
+#define IXGBR_FTQF_PRIORITY 0x0000001C /** priority */
+#define IXGBR_FTQF_PRIORITY_SHIFT 2
+#define IXGBR_FTQF_SRCIP_MASK 0x02000000 /** src IP mask */
+#define IXGBR_FTQF_DSTIP_MASK 0x04000000 /** dst IP mask */
+#define IXGBR_FTQF_SRCPORT_MASK 0x08000000 /** src port mask */
+#define IXGBR_FTQF_DSTPORT_MASK 0x10000000 /** dst port mask */
+#define IXGBR_FTQF_L4TYPE_MASK 0x20000000 /** protocol mask */
+#define IXGBR_FTQF_POOL_MASK 0x40000000 /** pool mask */
+#define IXGBR_FTQF_ENABLE 0x80000000 /** enable bit */
+#define IXGBR_FTQF_PRIORITY_DEFAULT 0x00000004
+#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.
*/
--
1.8.1.4
^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [PATCH 4/4][PMD][GENERIC_FILTER] add commands in testpmd for NIC filters
2014-05-20 3:53 [dpdk-dev] [PATCH 0/4][PMD][GENERIC_FILTER] ***NIC filters support of generic feature*** Jingjing Wu
` (2 preceding siblings ...)
2014-05-20 3:53 ` [dpdk-dev] [PATCH 3/4][PMD][GENERIC_FILTER]add ixgbe " Jingjing Wu
@ 2014-05-20 3:53 ` Jingjing Wu
3 siblings, 0 replies; 5+ messages in thread
From: Jingjing Wu @ 2014-05-20 3:53 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 | 905 ++++++++++++++++++++++++++++++++++++++++++++++++-
app/test-pmd/config.c | 143 ++++++++
app/test-pmd/testpmd.h | 6 +
3 files changed, 1053 insertions(+), 1 deletion(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 7becedc..fadfe32 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"
);
@@ -550,6 +551,68 @@ 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 (tcp|udp|sctp|none)"
+ " mask (mask_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 =
@@ -558,7 +621,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,
@@ -5107,6 +5170,831 @@ 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;
+ uint8_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, UINT8);
+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;
+ uint8_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;
+ if (!strcmp(res->filter, "add_syn_filter")){
+ if(!strcmp(res->high, "high"))
+ ret = rte_eth_dev_add_syn_filter(res->port_id, 1, res->queue_id);
+ else
+ ret = rte_eth_dev_add_syn_filter(res->port_id, 0, 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, UINT8);
+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;
+ uint8_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, UINT8);
+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;
+ cmdline_fixed_string_t protocol_value;
+ cmdline_fixed_string_t mask;
+ uint8_t mask_value;
+ cmdline_fixed_string_t priority;
+ uint8_t priority_value;
+ cmdline_fixed_string_t queue;
+ uint8_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.l4type_mask = (res->mask_value & 0x01) ? 0 : 1;
+ filter.priority = res->priority_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 invovle 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 invovle 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);
+
+ if (!strcmp(res->protocol_value, "udp"))
+ filter.l4type = RTE_FILTER_L4TYPE_UDP;
+ else if (!strcmp(res->protocol_value, "tcp"))
+ filter.l4type = RTE_FILTER_L4TYPE_TCP;
+ else if (!strcmp(res->protocol_value, "sctp"))
+ filter.l4type = RTE_FILTER_L4TYPE_SCTP;
+ else
+ filter.l4type = RTE_FILTER_L4TYPE_NONE;
+
+ 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_STRING_INITIALIZER(struct cmd_5tuple_filter_result,
+ protocol_value, "tcp#udp#sctp#none");
+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_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, UINT8);
+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_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;
+ uint8_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, UINT8);
+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 */
@@ -5189,6 +6077,21 @@ cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
(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 134bf07..5d8b92f 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1641,3 +1641,146 @@ set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on)
"diag=%d\n", port_id, diag);
}
+void
+get_ethertype_filter(uint8_t port_id, uint16_t index)
+{
+ struct rte_ethertype_filter filter;
+ int ret = 0;
+ uint8_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;
+ uint8_t rx_queue;
+
+ memset(&filter, 0, sizeof(filter));
+ ret = rte_eth_dev_get_syn_filter(port_id, &filter, &rx_queue);
+
+ if (ret < 0){
+ printf("get syn filter fails(%s)\n", strerror(-ret));
+ return;
+ }
+ printf("syn filter: %s, priority: %s, queue: %d\n",
+ filter.enable? "on" : "off",
+ 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;
+ uint8_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",
+ filter.protocol, filter.protocol_mask ? 0 : 1);
+ 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;
+ uint8_t rx_queue;
+ const char *protocol_type[] = {"tcp", "udp", "sctp", "none"};
+
+ 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_type: %s mask: %d \n",
+ protocol_type[filter.l4type],
+ filter.l4type_mask ? 0 : 1);
+ printf(" priority: %d queue: %d \n", filter.priority, rx_queue);
+ }
+}
+void
+get_flex_filter(uint8_t port_id, uint16_t index)
+
+{
+ struct rte_flex_filter filter;
+ int ret = 0;
+ uint8_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 5b4ee6f..1b50898 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -521,6 +521,12 @@ void set_vf_traffic(portid_t port_id, uint8_t is_rx, uint16_t vf, uint8_t on);
void set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id,
uint64_t vf_mask, uint8_t on);
+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
* rte_be_to_cpu_16() function.
--
1.8.1.4
^ permalink raw reply [flat|nested] 5+ messages in thread