All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] Add API to get packet type info
@ 2015-12-31  6:53 Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 01/12] ethdev: add API to query what/if packet type is set Jianfeng Tan
                   ` (21 more replies)
  0 siblings, 22 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

HAPPRY NEW YEAR!

A new ether API rte_eth_dev_get_ptype_info() is added to query what
packet type information will be provided by current pmd driver of the
specifed port.

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it will not provide any ptype info.

Jianfeng Tan (12):
  ethdev: add API to query what/if packet type is set
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation
  examples/l3fwd: add option to parse ptype

 drivers/net/cxgbe/cxgbe_ethdev.c     | 17 +++++++
 drivers/net/e1000/igb_ethdev.c       | 48 ++++++++++++++++++++
 drivers/net/enic/enic_ethdev.c       | 20 +++++++++
 drivers/net/fm10k/fm10k_ethdev.c     | 60 +++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c       |  5 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c   |  5 +++
 drivers/net/i40e/i40e_ethdev.c       |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c    |  1 +
 drivers/net/i40e/i40e_rxtx.c         | 69 ++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h         |  2 +
 drivers/net/ixgbe/ixgbe_ethdev.c     | 50 +++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h     |  2 +
 drivers/net/ixgbe/ixgbe_rxtx.c       |  5 ++-
 drivers/net/mlx4/mlx4.c              | 27 +++++++++++
 drivers/net/mlx5/mlx5.c              |  1 +
 drivers/net/mlx5/mlx5.h              |  2 +
 drivers/net/mlx5/mlx5_ethdev.c       | 25 +++++++++++
 drivers/net/mlx5/mlx5_rxtx.c         |  2 +
 drivers/net/nfp/nfp_net.c            | 18 ++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 20 +++++++++
 examples/l3fwd/main.c                | 86 ++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.c        | 12 +++++
 lib/librte_ether/rte_ethdev.h        | 22 +++++++++
 lib/librte_mbuf/rte_mbuf.h           | 13 ++++++
 24 files changed, 511 insertions(+), 2 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2016-01-04 11:38   ` Adrien Mazarguil
  2015-12-31  6:53 ` [PATCH 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
                   ` (20 subsequent siblings)
  21 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query what/if packet type will
be set by current rx burst function.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 12 ++++++++++++
 lib/librte_ether/rte_ethdev.h | 22 ++++++++++++++++++++++
 lib/librte_mbuf/rte_mbuf.h    | 13 +++++++++++++
 3 files changed, 47 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ed971b4..1885374 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1614,6 +1614,18 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	struct rte_eth_dev *dev;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	return (*dev->dev_ops->dev_ptype_info_get)(dev, ptype_mask, ptypes);
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index bada8ad..e97b632 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
+		uint32_t ptype_mask, uint32_t ptypes[]);
+/**< @internal Get ptype info of eth_rx_burst_t. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1351,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2273,6 +2278,23 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
 				 struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the contextual information of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in
+ * @param ptypes
+ *   An array of packet types to be filled with
+ * @return
+ *   - (>=0) if successful. Indicate number of valid values in ptypes array.
+ *   - (-ENOTSUP) if hardware-assisted VLAN stripping not configured.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
+				 uint32_t ptype_mask, uint32_t ptypes[]);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index f234ac9..21d4aa2 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -282,6 +282,8 @@ extern "C" {
  * It is used for outer packet for tunneling cases.
  */
 #define RTE_PTYPE_L2_MASK                   0x0000000f
+
+#define RTE_PTYPE_L2_MAX_NUM				4
 /**
  * IP (Internet Protocol) version 4 packet type.
  * It is used for outer packet for tunneling cases, and does not contain any
@@ -349,6 +351,8 @@ extern "C" {
  * It is used for outer packet for tunneling cases.
  */
 #define RTE_PTYPE_L3_MASK                   0x000000f0
+
+#define RTE_PTYPE_L3_MAX_NUM				6
 /**
  * TCP (Transmission Control Protocol) packet type.
  * It is used for outer packet for tunneling cases.
@@ -435,6 +439,8 @@ extern "C" {
  * It is used for outer packet for tunneling cases.
  */
 #define RTE_PTYPE_L4_MASK                   0x00000f00
+
+#define RTE_PTYPE_L4_MAX_NUM				6
 /**
  * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
  *
@@ -508,6 +514,8 @@ extern "C" {
  * Mask of tunneling packet types.
  */
 #define RTE_PTYPE_TUNNEL_MASK               0x0000f000
+
+#define RTE_PTYPE_TUNNEL_MAX_NUM			6
 /**
  * Ethernet packet type.
  * It is used for inner packet type only.
@@ -527,6 +535,8 @@ extern "C" {
  * Mask of inner layer 2 packet types.
  */
 #define RTE_PTYPE_INNER_L2_MASK             0x000f0000
+
+#define RTE_PTYPE_INNER_L2_MAX_NUM			2
 /**
  * IP (Internet Protocol) version 4 packet type.
  * It is used for inner packet only, and does not contain any header option.
@@ -588,6 +598,8 @@ extern "C" {
  * Mask of inner layer 3 packet types.
  */
 #define RTE_PTYPE_INNER_L3_MASK             0x00f00000
+
+#define RTE_PTYPE_INNER_L3_MAX_NUM			6
 /**
  * TCP (Transmission Control Protocol) packet type.
  * It is used for inner packet only.
@@ -666,6 +678,7 @@ extern "C" {
  */
 #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
 
+#define RTE_PTYPE_INNER_L4_MAX_NUM			6
 /**
  * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
  * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 02/12] pmd/cxgbe: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 01/12] ethdev: add API to query what/if packet type is set Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2016-01-06  7:11   ` Rahul Lakkireddy
  2015-12-31  6:53 ` [PATCH 03/12] pmd/e1000: " Jianfeng Tan
                   ` (19 subsequent siblings)
  21 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..f17d5d5 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,22 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static int cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev __rte_unused,
+		uint32_t ptype_mask, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts) {
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +793,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_ptype_info_get		= cxgbe_dev_ptype_info_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 03/12] pmd/e1000: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 01/12] ethdev: add API to query what/if packet type is set Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 04/12] pmd/enic: " Jianfeng Tan
                   ` (18 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 48 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index d1bbcda..0a9abd6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -103,6 +103,8 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static int eth_igb_ptype_info_get(struct rte_eth_dev *dev,
+		uint32_t ptype_mask, uint32_t ptypes[]);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -319,6 +321,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -376,6 +379,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1910,6 +1914,50 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static int
+eth_igb_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+			dev->rx_pkt_burst == eth_igb_recv_scattered_pkts) {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+
+		if ((ptype_mask & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_MASK)
+			ptypes[num++] = RTE_PTYPE_L2_ETHER;
+
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_L4_UDP;
+			ptypes[num++] = RTE_PTYPE_L4_SCTP;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_MASK)
+			ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L4_MASK) == RTE_PTYPE_INNER_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 04/12] pmd/enic: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (2 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 03/12] pmd/e1000: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 05/12] pmd/fm10k: " Jianfeng Tan
                   ` (17 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/enic/enic_ethdev.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2a88043..112480e 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -54,6 +54,9 @@
 #define ENICPMD_FUNC_TRACE() (void)0
 #endif
 
+static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+	uint16_t nb_pkts);
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -431,6 +434,22 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
+static int enicpmd_dev_ptype_info_get(struct rte_eth_dev *dev,
+		uint32_t ptype_mask, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == enicpmd_recv_pkts) {
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -566,6 +585,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_ptype_info_get   = enicpmd_dev_ptype_info_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 05/12] pmd/fm10k: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (3 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 04/12] pmd/enic: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 06/12] pmd/i40e: " Jianfeng Tan
                   ` (16 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 60 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  5 ++++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  5 ++++
 3 files changed, 70 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index e4aed94..51e4fe0 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,65 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static int
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	int num = 0;
+	if ((dev->rx_pkt_burst == fm10k_recv_pkts) ||
+			(dev->rx_pkt_burst == fm10k_recv_scattered_pkts)) {
+		/* refers to rx_desc_to_ol_flags() */
+		if ((ptype_mask & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_MASK)
+			ptypes[num++] = RTE_PTYPE_L2_ETHER;
+
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_L4_UDP;
+		}
+	} else if ((dev->rx_pkt_burst == fm10k_recv_pkts_vec) ||
+			(dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec)) {
+		/* refers to fm10k_desc_to_pktype_v() */
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_L4_UDP;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_MASK) {
+			ptypes[num++] = RTE_PTYPE_TUNNEL_GENEVE;
+			ptypes[num++] = RTE_PTYPE_TUNNEL_NVGRE;
+			ptypes[num++] = RTE_PTYPE_TUNNEL_VXLAN;
+			ptypes[num++] = RTE_PTYPE_TUNNEL_GRE;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+#else
+static int
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev __rte_unused,
+		uint32_t ptype_mask __rte_unused,
+		uint32_t ptypes[] __rte_unused)
+{
+	return -ENOTSUP;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2423,6 +2482,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_ptype_info_get	= fm10k_dev_ptype_info_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index e958865..9b2d6f2 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,11 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/*
+ * @note
+ * When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 2a57eef..6fc22fc 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -109,6 +109,11 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/*
+ * @note
+ * When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 06/12] pmd/i40e: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (4 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 05/12] pmd/fm10k: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 07/12] pmd/ixgbe: " Jianfeng Tan
                   ` (15 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 69 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  2 ++
 4 files changed, 72 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bf6220d..1f5251b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -439,6 +439,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_ptype_info_get           = i40e_dev_ptype_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 14d2a50..5d924de 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -196,6 +196,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_ptype_info_get   = i40e_dev_ptype_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 39d94ec..bf4f504 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -194,7 +194,11 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/*
+ * For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2094,6 +2098,69 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 }
 
 int
+i40e_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	int num = 0;
+
+	if ((dev->rx_pkt_burst == i40e_recv_pkts)
+			|| (dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+			|| (dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc)
+#endif
+	   ) {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		if ((ptype_mask & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_MASK) {
+			ptypes[num++] = RTE_PTYPE_L2_ETHER;
+			ptypes[num++] = RTE_PTYPE_L2_ETHER_TIMESYNC;
+			ptypes[num++] = RTE_PTYPE_L2_ETHER_LLDP;
+			ptypes[num++] = RTE_PTYPE_L2_ETHER_ARP;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_L4_FRAG;
+			ptypes[num++] = RTE_PTYPE_L4_ICMP;
+			ptypes[num++] = RTE_PTYPE_L4_NONFRAG;
+			ptypes[num++] = RTE_PTYPE_L4_SCTP;
+			ptypes[num++] = RTE_PTYPE_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_L4_UDP;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_MASK) {
+			ptypes[num++] = RTE_PTYPE_TUNNEL_GRENAT;
+			ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L2_MASK) == RTE_PTYPE_INNER_L2_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L2_ETHER;
+			ptypes[num++] = RTE_PTYPE_INNER_L2_ETHER_VLAN;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L4_MASK) == RTE_PTYPE_INNER_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L4_FRAG;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_ICMP;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_NONFRAG;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_SCTP;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+
+int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..5350b61 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,8 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+int i40e_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[]);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (5 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 06/12] pmd/i40e: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2016-01-04 18:12   ` Ananyev, Konstantin
  2015-12-31  6:53 ` [PATCH 08/12] pmd/mlx4: " Jianfeng Tan
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 50 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  5 +++-
 3 files changed, 56 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4c4c6df..de5c3a9 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -166,6 +166,8 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static int ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev,
+		uint32_t ptype_mask, uint32_t ptypes[]);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -428,6 +430,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -512,6 +515,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2829,6 +2833,52 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static int
+ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	int num = 0;
+
+	if ((dev->rx_pkt_burst == ixgbe_recv_pkts)
+			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc)
+			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc)
+			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc)
+	   ) {
+		/* refers to ixgbe_rxd_pkt_info_to_pkt_type() */
+		if ((ptype_mask & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_MASK)
+			ptypes[num++] = RTE_PTYPE_L2_ETHER;
+
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_L4_SCTP;
+			ptypes[num++] = RTE_PTYPE_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_L4_UDP;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_MASK)
+			ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L4_MASK) == RTE_PTYPE_INNER_L4_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index d26771a..2479830 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+			   uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 52a263c..d324099 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -899,6 +899,9 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+/*
+ * @note: fix ixgbe_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1247,7 +1250,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (6 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 07/12] pmd/ixgbe: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2016-01-04 11:11   ` Adrien Mazarguil
  2015-12-31  6:53 ` [PATCH 09/12] pmd/mlx5: " Jianfeng Tan
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 207bfe2..85afa32 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2836,6 +2836,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4268,6 +4270,30 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static int
+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	int num = 0;
+
+	if ((dev->rx_pkt_burst == mlx4_rx_burst)
+			|| (dev->rx_pkt_burst == mlx4_rx_burst_sp)) {
+		/* refers to rxq_cq_to_pkt_type() */
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -4989,6 +5015,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 09/12] pmd/mlx5: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (7 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 08/12] pmd/mlx4: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 10/12] pmd/nfp: " Jianfeng Tan
                   ` (12 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  2 ++
 drivers/net/mlx5/mlx5_ethdev.c | 25 +++++++++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 4 files changed, 30 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..e18b1e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -153,6 +153,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_ptype_info_get = mlx5_dev_ptype_info_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b84d31d..928193d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -156,6 +156,8 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+int mlx5_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[]);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..aab7e06 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -526,6 +526,31 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+int
+mlx5_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	int num = 0;
+
+	if ((dev->rx_pkt_burst == mlx5_rx_burst)
+			|| (dev->rx_pkt_burst == mlx5_rx_burst_sp)) {
+		/* refers to rxq_cq_to_pkt_type() */
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		}
+
+		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index fa5e648..79bdf8d 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -603,6 +603,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 10/12] pmd/nfp: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (8 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 09/12] pmd/mlx5: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 11/12] pmd/vmxnet3: " Jianfeng Tan
                   ` (11 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/nfp/nfp_net.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index bc2089f..c121d7b 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1075,6 +1075,23 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 #endif
 }
 
+static int
+nfp_net_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
+		uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts) {
+		/* refers to nfp_net_set_hash() */
+		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
+			ptypes[num++] = RTE_PTYPE_INNER_L4_MASK;
+		}
+	}
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2294,6 +2311,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_ptype_info_get	= nfp_net_ptype_info_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 11/12] pmd/vmxnet3: add dev_ptype_info_get implementation
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (9 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 10/12] pmd/nfp: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2015-12-31  6:53 ` [PATCH 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
                   ` (10 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..6bc8d9a 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,8 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static int vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev,
+		uint32_t ptype_mask, uint32_t ptypes[]);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -118,6 +120,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.link_update          = vmxnet3_dev_link_update,
 	.stats_get            = vmxnet3_dev_stats_get,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_ptype_info_get   = vmxnet3_dev_ptype_info_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -718,6 +721,23 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, struct rte_
 	};
 }
 
+static int
+vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev,
+		uint32_t ptype_mask, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts) {
+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
+			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		}
+	} else
+		num = -ENOTSUP;
+
+	return num;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 12/12] examples/l3fwd: add option to parse ptype
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (10 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 11/12] pmd/vmxnet3: " Jianfeng Tan
@ 2015-12-31  6:53 ` Jianfeng Tan
  2016-01-04 18:32   ` Ananyev, Konstantin
  2016-01-13  1:52 ` [PATCH 00/12] Add API to get packet type info Qiu, Michael
                   ` (9 subsequent siblings)
  21 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2015-12-31  6:53 UTC (permalink / raw)
  To: dev

Firstly, use rte_eth_dev_get_ptype_info() API to check if device will
parse needed packet type. If not, specifying the newly added option,
--parse-ptype to do it in the callback softly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/l3fwd/main.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 86 insertions(+)

diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 5b0c2dd..ccbdce3 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -174,6 +174,7 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
 static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by default. */
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype = 0; /**< parse packet type using rx callback */
 
 #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
 static int ipv6 = 0; /**< ipv6 is false by default. */
@@ -2022,6 +2023,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /* Parse the argument given in the command line of the application */
 static int
@@ -2038,6 +2040,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -2125,6 +2128,12 @@ parse_args(int argc, char **argv)
 				}
 			}
 #endif
+			if (!strncmp(lgopts[option_index].name, CMD_LINE_OPT_PARSE_PTYPE,
+				sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled \n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -2559,6 +2568,75 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 	}
 }
 
+static int
+check_packet_type_ok(int portid)
+{
+	int i;
+	int ret;
+	uint32_t ptypes[RTE_PTYPE_L3_MAX_NUM];
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, ptypes);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 || ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+}
+static inline void
+parse_packet_type(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	struct vlan_hdr *vlan_hdr;
+	uint32_t packet_type = 0;
+	uint16_t ethertype;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	if (ethertype == ETHER_TYPE_VLAN) {
+		vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
+		ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
+	}
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+		break;
+	case ETHER_TYPE_IPv6:
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		break;
+	default:
+		break;
+	}
+
+	m->packet_type = packet_type;
+}
+
+static uint16_t
+cb_parse_packet_type(uint8_t port __rte_unused,
+		uint16_t queue __rte_unused,
+		struct rte_mbuf *pkts[],
+		uint16_t nb_pkts,
+		uint16_t max_pkts __rte_unused,
+		void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_packet_type(pkts[i]);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -2672,6 +2750,11 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d, "
 					"port=%d\n", ret, portid);
 
+			if (!check_packet_type_ok(portid) && !parse_ptype)
+				rte_exit(EXIT_FAILURE,
+						"port %d cannot parse packet type, please add --%s\n",
+						portid, CMD_LINE_OPT_PARSE_PTYPE);
+
 			qconf = &lcore_conf[lcore_id];
 			qconf->tx_queue_id[portid] = queueid;
 			queueid++;
@@ -2705,6 +2788,9 @@ main(int argc, char **argv)
 			if (ret < 0)
 				rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
 						"port=%d\n", ret, portid);
+			if (parse_ptype)
+				rte_eth_add_rx_callback(portid, queueid,
+						cb_parse_packet_type, NULL);
 		}
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2015-12-31  6:53 ` [PATCH 08/12] pmd/mlx4: " Jianfeng Tan
@ 2016-01-04 11:11   ` Adrien Mazarguil
  2016-01-05  3:08     ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-04 11:11 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

Hi Jianfeng,

I'm only commenting the mlx4/mlx5 bits in this message, see below.

On Thu, Dec 31, 2015 at 02:53:15PM +0800, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/mlx4/mlx4.c | 27 +++++++++++++++++++++++++++
>  1 file changed, 27 insertions(+)
> 
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index 207bfe2..85afa32 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -2836,6 +2836,8 @@ rxq_cleanup(struct rxq *rxq)
>   * @param flags
>   *   RX completion flags returned by poll_length_flags().
>   *
> + * @note: fix mlx4_dev_ptype_info_get() if any change here.
> + *
>   * @return
>   *   Packet type for struct rte_mbuf.
>   */
> @@ -4268,6 +4270,30 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>  	priv_unlock(priv);
>  }
>  
> +static int
> +mlx4_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
> +		uint32_t ptypes[])
> +{
> +	int num = 0;
> +
> +	if ((dev->rx_pkt_burst == mlx4_rx_burst)
> +			|| (dev->rx_pkt_burst == mlx4_rx_burst_sp)) {
> +		/* refers to rxq_cq_to_pkt_type() */
> +		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
> +			ptypes[num++] = RTE_PTYPE_L3_IPV4;
> +			ptypes[num++] = RTE_PTYPE_L3_IPV6;
> +		}
> +
> +		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
> +		}
> +	} else
> +		num = -ENOTSUP;
> +
> +	return num;
> +}

I think checking for mlx4_rx_burst and mlx4_rx_burst_sp is unnecessary at
the moment, all RX burst functions do update the packet_type field, no need
for extra complexity.

Same comment for mlx5. 

> +
>  /**
>   * DPDK callback to get device statistics.
>   *
> @@ -4989,6 +5015,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
>  	.stats_reset = mlx4_stats_reset,
>  	.queue_stats_mapping_set = NULL,
>  	.dev_infos_get = mlx4_dev_infos_get,
> +	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
>  	.vlan_filter_set = mlx4_vlan_filter_set,
>  	.vlan_tpid_set = NULL,
>  	.vlan_strip_queue_set = NULL,
> -- 
> 2.1.4
> 

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2015-12-31  6:53 ` [PATCH 01/12] ethdev: add API to query what/if packet type is set Jianfeng Tan
@ 2016-01-04 11:38   ` Adrien Mazarguil
  2016-01-04 14:36     ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-04 11:38 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

I'm not sure about the usefulness of this new callback, but one issue I see
with rte_eth_dev_get_ptype_info() is that determining the proper size for
ptypes[] according to a mask is awkward. For instance suppose
RTE_PTYPE_L4_MASK is redefined to a different size at some point, the caller
must dynamically adjust its ptypes[] array size to avoid a possible
overflow, just in case.

I suggest one of these solutions:

- A callback to query for a single type at once instead (easiest method in
  my opinion).

- An additional argument with the number of entries in ptypes[], in which
  case rte_eth_dev_get_ptype_info() should return the number of entries that
  would have been filled regardless, a bit like snprintf().

On Thu, Dec 31, 2015 at 02:53:08PM +0800, Jianfeng Tan wrote:
> Add a new API rte_eth_dev_get_ptype_info to query what/if packet type will
> be set by current rx burst function.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 12 ++++++++++++
>  lib/librte_ether/rte_ethdev.h | 22 ++++++++++++++++++++++
>  lib/librte_mbuf/rte_mbuf.h    | 13 +++++++++++++
>  3 files changed, 47 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index ed971b4..1885374 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1614,6 +1614,18 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>  	dev_info->driver_name = dev->data->drv_name;
>  }
>  
> +int
> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> +		uint32_t ptypes[])
> +{
> +	struct rte_eth_dev *dev;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +	dev = &rte_eth_devices[port_id];
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> +	return (*dev->dev_ops->dev_ptype_info_get)(dev, ptype_mask, ptypes);
> +}
> +
>  void
>  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
>  {
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index bada8ad..e97b632 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
>  				    struct rte_eth_dev_info *dev_info);
>  /**< @internal Get specific informations of an Ethernet device. */
>  
> +typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
> +		uint32_t ptype_mask, uint32_t ptypes[]);
> +/**< @internal Get ptype info of eth_rx_burst_t. */
> +
>  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
>  				    uint16_t queue_id);
>  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> @@ -1347,6 +1351,7 @@ struct eth_dev_ops {
>  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
>  	/**< Configure per queue stat counter mapping. */
>  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
>  	mtu_set_t                  mtu_set; /**< Set MTU. */
>  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
>  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> @@ -2273,6 +2278,23 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
>  				 struct rte_eth_dev_info *dev_info);
>  
>  /**
> + * Retrieve the contextual information of an Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param ptype_mask
> + *   A hint of what kind of packet type which the caller is interested in
> + * @param ptypes
> + *   An array of packet types to be filled with
> + * @return
> + *   - (>=0) if successful. Indicate number of valid values in ptypes array.
> + *   - (-ENOTSUP) if hardware-assisted VLAN stripping not configured.
> + *   - (-ENODEV) if *port_id* invalid.
> + */
> +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> +				 uint32_t ptype_mask, uint32_t ptypes[]);
> +
> +/**
>   * Retrieve the MTU of an Ethernet device.
>   *
>   * @param port_id
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index f234ac9..21d4aa2 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -282,6 +282,8 @@ extern "C" {
>   * It is used for outer packet for tunneling cases.
>   */
>  #define RTE_PTYPE_L2_MASK                   0x0000000f
> +
> +#define RTE_PTYPE_L2_MAX_NUM				4
>  /**
>   * IP (Internet Protocol) version 4 packet type.
>   * It is used for outer packet for tunneling cases, and does not contain any
> @@ -349,6 +351,8 @@ extern "C" {
>   * It is used for outer packet for tunneling cases.
>   */
>  #define RTE_PTYPE_L3_MASK                   0x000000f0
> +
> +#define RTE_PTYPE_L3_MAX_NUM				6
>  /**
>   * TCP (Transmission Control Protocol) packet type.
>   * It is used for outer packet for tunneling cases.
> @@ -435,6 +439,8 @@ extern "C" {
>   * It is used for outer packet for tunneling cases.
>   */
>  #define RTE_PTYPE_L4_MASK                   0x00000f00
> +
> +#define RTE_PTYPE_L4_MAX_NUM				6
>  /**
>   * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
>   *
> @@ -508,6 +514,8 @@ extern "C" {
>   * Mask of tunneling packet types.
>   */
>  #define RTE_PTYPE_TUNNEL_MASK               0x0000f000
> +
> +#define RTE_PTYPE_TUNNEL_MAX_NUM			6
>  /**
>   * Ethernet packet type.
>   * It is used for inner packet type only.
> @@ -527,6 +535,8 @@ extern "C" {
>   * Mask of inner layer 2 packet types.
>   */
>  #define RTE_PTYPE_INNER_L2_MASK             0x000f0000
> +
> +#define RTE_PTYPE_INNER_L2_MAX_NUM			2
>  /**
>   * IP (Internet Protocol) version 4 packet type.
>   * It is used for inner packet only, and does not contain any header option.
> @@ -588,6 +598,8 @@ extern "C" {
>   * Mask of inner layer 3 packet types.
>   */
>  #define RTE_PTYPE_INNER_L3_MASK             0x00f00000
> +
> +#define RTE_PTYPE_INNER_L3_MAX_NUM			6
>  /**
>   * TCP (Transmission Control Protocol) packet type.
>   * It is used for inner packet only.
> @@ -666,6 +678,7 @@ extern "C" {
>   */
>  #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
>  
> +#define RTE_PTYPE_INNER_L4_MAX_NUM			6
>  /**
>   * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
>   * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
> -- 
> 2.1.4
> 

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-04 11:38   ` Adrien Mazarguil
@ 2016-01-04 14:36     ` Ananyev, Konstantin
  2016-01-05 16:14       ` Nélio Laranjeiro
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-04 14:36 UTC (permalink / raw)
  To: Adrien Mazarguil, Tan, Jianfeng; +Cc: dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Monday, January 04, 2016 11:38 AM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> 
> I'm not sure about the usefulness of this new callback, but one issue I see
> with rte_eth_dev_get_ptype_info() is that determining the proper size for
> ptypes[] according to a mask is awkward. For instance suppose
> RTE_PTYPE_L4_MASK is redefined to a different size at some point, the caller
> must dynamically adjust its ptypes[] array size to avoid a possible
> overflow, just in case.
> 
> I suggest one of these solutions:
> 
> - A callback to query for a single type at once instead (easiest method in
>   my opinion).
> 
> - An additional argument with the number of entries in ptypes[], in which
>   case rte_eth_dev_get_ptype_info() should return the number of entries that
>   would have been filled regardless, a bit like snprintf().

+1 for the second option.
Also not sure you really need: RTE_PTYPE_*_MAX_NUM macros.
Konstantin

> 
> On Thu, Dec 31, 2015 at 02:53:08PM +0800, Jianfeng Tan wrote:
> > Add a new API rte_eth_dev_get_ptype_info to query what/if packet type will
> > be set by current rx burst function.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  lib/librte_ether/rte_ethdev.c | 12 ++++++++++++
> >  lib/librte_ether/rte_ethdev.h | 22 ++++++++++++++++++++++
> >  lib/librte_mbuf/rte_mbuf.h    | 13 +++++++++++++
> >  3 files changed, 47 insertions(+)
> >
> > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > index ed971b4..1885374 100644
> > --- a/lib/librte_ether/rte_ethdev.c
> > +++ b/lib/librte_ether/rte_ethdev.c
> > @@ -1614,6 +1614,18 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> >  	dev_info->driver_name = dev->data->drv_name;
> >  }
> >
> > +int
> > +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> > +		uint32_t ptypes[])
> > +{
> > +	struct rte_eth_dev *dev;
> > +
> > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > +	dev = &rte_eth_devices[port_id];
> > +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> > +	return (*dev->dev_ops->dev_ptype_info_get)(dev, ptype_mask, ptypes);
> > +}
> > +
> >  void
> >  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
> >  {
> > diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > index bada8ad..e97b632 100644
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
> >  				    struct rte_eth_dev_info *dev_info);
> >  /**< @internal Get specific informations of an Ethernet device. */
> >
> > +typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
> > +		uint32_t ptype_mask, uint32_t ptypes[]);
> > +/**< @internal Get ptype info of eth_rx_burst_t. */
> > +
> >  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
> >  				    uint16_t queue_id);
> >  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> > @@ -1347,6 +1351,7 @@ struct eth_dev_ops {
> >  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
> >  	/**< Configure per queue stat counter mapping. */
> >  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> > +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
> >  	mtu_set_t                  mtu_set; /**< Set MTU. */
> >  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
> >  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> > @@ -2273,6 +2278,23 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
> >  				 struct rte_eth_dev_info *dev_info);
> >
> >  /**
> > + * Retrieve the contextual information of an Ethernet device.
> > + *
> > + * @param port_id
> > + *   The port identifier of the Ethernet device.
> > + * @param ptype_mask
> > + *   A hint of what kind of packet type which the caller is interested in
> > + * @param ptypes
> > + *   An array of packet types to be filled with
> > + * @return
> > + *   - (>=0) if successful. Indicate number of valid values in ptypes array.
> > + *   - (-ENOTSUP) if hardware-assisted VLAN stripping not configured.
> > + *   - (-ENODEV) if *port_id* invalid.
> > + */
> > +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> > +				 uint32_t ptype_mask, uint32_t ptypes[]);
> > +
> > +/**
> >   * Retrieve the MTU of an Ethernet device.
> >   *
> >   * @param port_id
> > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > index f234ac9..21d4aa2 100644
> > --- a/lib/librte_mbuf/rte_mbuf.h
> > +++ b/lib/librte_mbuf/rte_mbuf.h
> > @@ -282,6 +282,8 @@ extern "C" {
> >   * It is used for outer packet for tunneling cases.
> >   */
> >  #define RTE_PTYPE_L2_MASK                   0x0000000f
> > +
> > +#define RTE_PTYPE_L2_MAX_NUM				4
> >  /**
> >   * IP (Internet Protocol) version 4 packet type.
> >   * It is used for outer packet for tunneling cases, and does not contain any
> > @@ -349,6 +351,8 @@ extern "C" {
> >   * It is used for outer packet for tunneling cases.
> >   */
> >  #define RTE_PTYPE_L3_MASK                   0x000000f0
> > +
> > +#define RTE_PTYPE_L3_MAX_NUM				6
> >  /**
> >   * TCP (Transmission Control Protocol) packet type.
> >   * It is used for outer packet for tunneling cases.
> > @@ -435,6 +439,8 @@ extern "C" {
> >   * It is used for outer packet for tunneling cases.
> >   */
> >  #define RTE_PTYPE_L4_MASK                   0x00000f00
> > +
> > +#define RTE_PTYPE_L4_MAX_NUM				6
> >  /**
> >   * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
> >   *
> > @@ -508,6 +514,8 @@ extern "C" {
> >   * Mask of tunneling packet types.
> >   */
> >  #define RTE_PTYPE_TUNNEL_MASK               0x0000f000
> > +
> > +#define RTE_PTYPE_TUNNEL_MAX_NUM			6
> >  /**
> >   * Ethernet packet type.
> >   * It is used for inner packet type only.
> > @@ -527,6 +535,8 @@ extern "C" {
> >   * Mask of inner layer 2 packet types.
> >   */
> >  #define RTE_PTYPE_INNER_L2_MASK             0x000f0000
> > +
> > +#define RTE_PTYPE_INNER_L2_MAX_NUM			2
> >  /**
> >   * IP (Internet Protocol) version 4 packet type.
> >   * It is used for inner packet only, and does not contain any header option.
> > @@ -588,6 +598,8 @@ extern "C" {
> >   * Mask of inner layer 3 packet types.
> >   */
> >  #define RTE_PTYPE_INNER_L3_MASK             0x00f00000
> > +
> > +#define RTE_PTYPE_INNER_L3_MAX_NUM			6
> >  /**
> >   * TCP (Transmission Control Protocol) packet type.
> >   * It is used for inner packet only.
> > @@ -666,6 +678,7 @@ extern "C" {
> >   */
> >  #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
> >
> > +#define RTE_PTYPE_INNER_L4_MAX_NUM			6
> >  /**
> >   * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
> >   * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
> > --
> > 2.1.4
> >
> 
> --
> Adrien Mazarguil
> 6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2015-12-31  6:53 ` [PATCH 07/12] pmd/ixgbe: " Jianfeng Tan
@ 2016-01-04 18:12   ` Ananyev, Konstantin
  2016-01-05  1:25     ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-04 18:12 UTC (permalink / raw)
  To: Tan, Jianfeng, dev



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Thursday, December 31, 2015 6:53 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> Subject: [PATCH 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c | 50 ++++++++++++++++++++++++++++++++++++++++
>  drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
>  drivers/net/ixgbe/ixgbe_rxtx.c   |  5 +++-
>  3 files changed, 56 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 4c4c6df..de5c3a9 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -166,6 +166,8 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
>  					     uint8_t is_rx);
>  static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
>  			       struct rte_eth_dev_info *dev_info);
> +static int ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev,
> +		uint32_t ptype_mask, uint32_t ptypes[]);
>  static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
>  				 struct rte_eth_dev_info *dev_info);
>  static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
> @@ -428,6 +430,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
>  	.xstats_reset         = ixgbe_dev_xstats_reset,
>  	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
>  	.dev_infos_get        = ixgbe_dev_info_get,
> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>  	.mtu_set              = ixgbe_dev_mtu_set,
>  	.vlan_filter_set      = ixgbe_vlan_filter_set,
>  	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
> @@ -512,6 +515,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
>  	.xstats_reset         = ixgbevf_dev_stats_reset,
>  	.dev_close            = ixgbevf_dev_close,
>  	.dev_infos_get        = ixgbevf_dev_info_get,
> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>  	.mtu_set              = ixgbevf_dev_set_mtu,
>  	.vlan_filter_set      = ixgbevf_vlan_filter_set,
>  	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
> @@ -2829,6 +2833,52 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
>  }
> 
> +static int
> +ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
> +		uint32_t ptypes[])
> +{
> +	int num = 0;
> +
> +	if ((dev->rx_pkt_burst == ixgbe_recv_pkts)
> +			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc)
> +			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc)
> +			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc)
> +	   ) {


As I remember vector RX for ixgbe sets up packet_type properly too.

> +		/* refers to ixgbe_rxd_pkt_info_to_pkt_type() */
> +		if ((ptype_mask & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_MASK)
> +			ptypes[num++] = RTE_PTYPE_L2_ETHER;
> +
> +		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
> +			ptypes[num++] = RTE_PTYPE_L3_IPV4;
> +			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
> +			ptypes[num++] = RTE_PTYPE_L3_IPV6;
> +			ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
> +		}
> +
> +		if ((ptype_mask & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_MASK) {
> +			ptypes[num++] = RTE_PTYPE_L4_SCTP;
> +			ptypes[num++] = RTE_PTYPE_L4_TCP;
> +			ptypes[num++] = RTE_PTYPE_L4_UDP;
> +		}
> +
> +		if ((ptype_mask & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_MASK)
> +			ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
> +
> +		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
> +		}
> +
> +		if ((ptype_mask & RTE_PTYPE_INNER_L4_MASK) == RTE_PTYPE_INNER_L4_MASK) {
> +			ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
> +			ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
> +		}
> +	} else
> +		num = -ENOTSUP;
> +
> +	return num;
> +}
> +
>  static void
>  ixgbevf_dev_info_get(struct rte_eth_dev *dev,
>  		     struct rte_eth_dev_info *dev_info)
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
> index d26771a..2479830 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.h
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
> @@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
>  uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>  		uint16_t nb_pkts);
> 
> +uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
> +			   uint16_t nb_pkts);
>  uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
>  		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
>  uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index 52a263c..d324099 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -899,6 +899,9 @@ end_of_tx:
>  #define IXGBE_PACKET_TYPE_MAX               0X80
>  #define IXGBE_PACKET_TYPE_MASK              0X7F
>  #define IXGBE_PACKET_TYPE_SHIFT             0X04
> +/*
> + * @note: fix ixgbe_dev_ptype_info_get() if any change here.
> + */
>  static inline uint32_t
>  ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
>  {
> @@ -1247,7 +1250,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>  }
> 
>  /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
> -static uint16_t
> +uint16_t
>  ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
>  			   uint16_t nb_pkts)
>  {
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 12/12] examples/l3fwd: add option to parse ptype
  2015-12-31  6:53 ` [PATCH 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
@ 2016-01-04 18:32   ` Ananyev, Konstantin
  2016-01-05  2:44     ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-04 18:32 UTC (permalink / raw)
  To: Tan, Jianfeng, dev


Hi Jianfeng,
> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Thursday, December 31, 2015 6:53 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> Subject: [PATCH 12/12] examples/l3fwd: add option to parse ptype
> 
> Firstly, use rte_eth_dev_get_ptype_info() API to check if device will
> parse needed packet type. If not, specifying the newly added option,
> --parse-ptype to do it in the callback softly.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  examples/l3fwd/main.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 86 insertions(+)
> 
> diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> index 5b0c2dd..ccbdce3 100644
> --- a/examples/l3fwd/main.c
> +++ b/examples/l3fwd/main.c
> @@ -174,6 +174,7 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
>  static uint32_t enabled_port_mask = 0;
>  static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by default. */
>  static int numa_on = 1; /**< NUMA is enabled by default. */
> +static int parse_ptype = 0; /**< parse packet type using rx callback */
> 
>  #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
>  static int ipv6 = 0; /**< ipv6 is false by default. */
> @@ -2022,6 +2023,7 @@ parse_eth_dest(const char *optarg)
>  #define CMD_LINE_OPT_IPV6 "ipv6"
>  #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
>  #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
> +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
> 
>  /* Parse the argument given in the command line of the application */
>  static int
> @@ -2038,6 +2040,7 @@ parse_args(int argc, char **argv)
>  		{CMD_LINE_OPT_IPV6, 0, 0, 0},
>  		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
>  		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
> +		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
>  		{NULL, 0, 0, 0}
>  	};
> 
> @@ -2125,6 +2128,12 @@ parse_args(int argc, char **argv)
>  				}
>  			}
>  #endif
> +			if (!strncmp(lgopts[option_index].name, CMD_LINE_OPT_PARSE_PTYPE,
> +				sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
> +				printf("soft parse-ptype is enabled \n");
> +				parse_ptype = 1;
> +			}
> +
>  			break;
> 
>  		default:
> @@ -2559,6 +2568,75 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
>  	}
>  }
> 
> +static int
> +check_packet_type_ok(int portid)
> +{
> +	int i;
> +	int ret;
> +	uint32_t ptypes[RTE_PTYPE_L3_MAX_NUM];
> +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> +
> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, ptypes);
> +	for (i = 0; i < ret; ++i) {
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> +			ptype_l3_ipv4 = 1;
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> +			ptype_l3_ipv6 = 1;
> +	}
> +
> +	if (ptype_l3_ipv4 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> +
> +	if (ptype_l3_ipv6 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> +
> +	if (ptype_l3_ipv4 || ptype_l3_ipv6)
> +		return 1;
> +
> +	return 0;
> +}
> +static inline void
> +parse_packet_type(struct rte_mbuf *m)
> +{
> +	struct ether_hdr *eth_hdr;
> +	struct vlan_hdr *vlan_hdr;
> +	uint32_t packet_type = 0;
> +	uint16_t ethertype;
> +
> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> +	if (ethertype == ETHER_TYPE_VLAN) {

I don't think either LPM or EM support packets with VLAN right now.
So, probably there is no need to support it here.

> +		vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
> +		ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
> +	}
> +	switch (ethertype) {
> +	case ETHER_TYPE_IPv4:
> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> +		break;
> +	case ETHER_TYPE_IPv6:
> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	m->packet_type = packet_type;

Probably:
m->packet_type |= packet_type;
in case HW supports some other packet types.

> +}
> +
> +static uint16_t
> +cb_parse_packet_type(uint8_t port __rte_unused,
> +		uint16_t queue __rte_unused,
> +		struct rte_mbuf *pkts[],
> +		uint16_t nb_pkts,
> +		uint16_t max_pkts __rte_unused,
> +		void *user_param __rte_unused)
> +{
> +	unsigned i;
> +
> +	for (i = 0; i < nb_pkts; ++i)
> +		parse_packet_type(pkts[i]);
> +}
> +
>  int
>  main(int argc, char **argv)
>  {
> @@ -2672,6 +2750,11 @@ main(int argc, char **argv)
>  				rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d, "
>  					"port=%d\n", ret, portid);
> 
> +			if (!check_packet_type_ok(portid) && !parse_ptype)
> +				rte_exit(EXIT_FAILURE,
> +						"port %d cannot parse packet type, please add --%s\n",
> +						portid, CMD_LINE_OPT_PARSE_PTYPE);
> +
>  			qconf = &lcore_conf[lcore_id];
>  			qconf->tx_queue_id[portid] = queueid;
>  			queueid++;
> @@ -2705,6 +2788,9 @@ main(int argc, char **argv)
>  			if (ret < 0)
>  				rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
>  						"port=%d\n", ret, portid);
> +			if (parse_ptype)
> +				rte_eth_add_rx_callback(portid, queueid,
> +						cb_parse_packet_type, NULL);

Need to check return value.
Konstantin

>  		}
>  	}
> 
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-01-04 18:12   ` Ananyev, Konstantin
@ 2016-01-05  1:25     ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-01-05  1:25 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev



On 1/5/2016 2:12 AM, Ananyev, Konstantin wrote:
>
>> -----Original Message-----
>> From: Tan, Jianfeng
>> Sent: Thursday, December 31, 2015 6:53 AM
>> To: dev@dpdk.org
>> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
>> Subject: [PATCH 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   drivers/net/ixgbe/ixgbe_ethdev.c | 50 ++++++++++++++++++++++++++++++++++++++++
>>   drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
>>   drivers/net/ixgbe/ixgbe_rxtx.c   |  5 +++-
>>   3 files changed, 56 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
>> index 4c4c6df..de5c3a9 100644
>> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
>> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
>> @@ -166,6 +166,8 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
>>   					     uint8_t is_rx);
>>   static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
>>   			       struct rte_eth_dev_info *dev_info);
>> +static int ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev,
>> +		uint32_t ptype_mask, uint32_t ptypes[]);
>>   static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
>>   				 struct rte_eth_dev_info *dev_info);
>>   static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
>> @@ -428,6 +430,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
>>   	.xstats_reset         = ixgbe_dev_xstats_reset,
>>   	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
>>   	.dev_infos_get        = ixgbe_dev_info_get,
>> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>>   	.mtu_set              = ixgbe_dev_mtu_set,
>>   	.vlan_filter_set      = ixgbe_vlan_filter_set,
>>   	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
>> @@ -512,6 +515,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
>>   	.xstats_reset         = ixgbevf_dev_stats_reset,
>>   	.dev_close            = ixgbevf_dev_close,
>>   	.dev_infos_get        = ixgbevf_dev_info_get,
>> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>>   	.mtu_set              = ixgbevf_dev_set_mtu,
>>   	.vlan_filter_set      = ixgbevf_vlan_filter_set,
>>   	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
>> @@ -2829,6 +2833,52 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>>   	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
>>   }
>>
>> +static int
>> +ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
>> +		uint32_t ptypes[])
>> +{
>> +	int num = 0;
>> +
>> +	if ((dev->rx_pkt_burst == ixgbe_recv_pkts)
>> +			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc)
>> +			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc)
>> +			|| (dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc)
>> +	   ) {
>
> As I remember vector RX for ixgbe sets up packet_type properly too.

Hi Konstantin,

Yes, Helin also reminds me about that. Going to add it in next version.

Thanks,
Jianfeng

>
>> +		/* refers to ixgbe_rxd_pkt_info_to_pkt_type() */
>> +		if ((ptype_mask & RTE_PTYPE_L2_MASK) == RTE_PTYPE_L2_MASK)
>> +			ptypes[num++] = RTE_PTYPE_L2_ETHER;
>> +
>> +		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
>> +			ptypes[num++] = RTE_PTYPE_L3_IPV4;
>> +			ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
>> +			ptypes[num++] = RTE_PTYPE_L3_IPV6;
>> +			ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
>> +		}
>> +
>> +		if ((ptype_mask & RTE_PTYPE_L4_MASK) == RTE_PTYPE_L4_MASK) {
>> +			ptypes[num++] = RTE_PTYPE_L4_SCTP;
>> +			ptypes[num++] = RTE_PTYPE_L4_TCP;
>> +			ptypes[num++] = RTE_PTYPE_L4_UDP;
>> +		}
>> +
>> +		if ((ptype_mask & RTE_PTYPE_TUNNEL_MASK) == RTE_PTYPE_TUNNEL_MASK)
>> +			ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
>> +
>> +		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
>> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
>> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
>> +		}
>> +
>> +		if ((ptype_mask & RTE_PTYPE_INNER_L4_MASK) == RTE_PTYPE_INNER_L4_MASK) {
>> +			ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
>> +			ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
>> +		}
>> +	} else
>> +		num = -ENOTSUP;
>> +
>> +	return num;
>> +}
>> +
>>   static void
>>   ixgbevf_dev_info_get(struct rte_eth_dev *dev,
>>   		     struct rte_eth_dev_info *dev_info)
>> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
>> index d26771a..2479830 100644
>> --- a/drivers/net/ixgbe/ixgbe_ethdev.h
>> +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
>> @@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
>>   uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>>   		uint16_t nb_pkts);
>>
>> +uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
>> +			   uint16_t nb_pkts);
>>   uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
>>   		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
>>   uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
>> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
>> index 52a263c..d324099 100644
>> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
>> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
>> @@ -899,6 +899,9 @@ end_of_tx:
>>   #define IXGBE_PACKET_TYPE_MAX               0X80
>>   #define IXGBE_PACKET_TYPE_MASK              0X7F
>>   #define IXGBE_PACKET_TYPE_SHIFT             0X04
>> +/*
>> + * @note: fix ixgbe_dev_ptype_info_get() if any change here.
>> + */
>>   static inline uint32_t
>>   ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
>>   {
>> @@ -1247,7 +1250,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>>   }
>>
>>   /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
>> -static uint16_t
>> +uint16_t
>>   ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
>>   			   uint16_t nb_pkts)
>>   {
>> --
>> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 12/12] examples/l3fwd: add option to parse ptype
  2016-01-04 18:32   ` Ananyev, Konstantin
@ 2016-01-05  2:44     ` Tan, Jianfeng
  2016-01-05 16:49       ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-01-05  2:44 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev



> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Tuesday, January 5, 2016 2:32 AM
> To: Tan, Jianfeng; dev@dpdk.org
> Cc: Zhang, Helin
> Subject: RE: [PATCH 12/12] examples/l3fwd: add option to parse ptype
> 
> 
> Hi Jianfeng,
> > -----Original Message-----
> > From: Tan, Jianfeng
> > Sent: Thursday, December 31, 2015 6:53 AM
> > To: dev@dpdk.org
> > Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> > Subject: [PATCH 12/12] examples/l3fwd: add option to parse ptype
> >
> > Firstly, use rte_eth_dev_get_ptype_info() API to check if device will
> > parse needed packet type. If not, specifying the newly added option,
> > --parse-ptype to do it in the callback softly.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  examples/l3fwd/main.c | 86
> +++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 86 insertions(+)
> >
> > diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> > index 5b0c2dd..ccbdce3 100644
> > --- a/examples/l3fwd/main.c
> > +++ b/examples/l3fwd/main.c
> > @@ -174,6 +174,7 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
> >  static uint32_t enabled_port_mask = 0;
> >  static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by
> default. */
> >  static int numa_on = 1; /**< NUMA is enabled by default. */
> > +static int parse_ptype = 0; /**< parse packet type using rx callback */
> >
> >  #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
> >  static int ipv6 = 0; /**< ipv6 is false by default. */
> > @@ -2022,6 +2023,7 @@ parse_eth_dest(const char *optarg)
> >  #define CMD_LINE_OPT_IPV6 "ipv6"
> >  #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
> >  #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
> > +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
> >
> >  /* Parse the argument given in the command line of the application */
> >  static int
> > @@ -2038,6 +2040,7 @@ parse_args(int argc, char **argv)
> >  		{CMD_LINE_OPT_IPV6, 0, 0, 0},
> >  		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
> >  		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
> > +		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
> >  		{NULL, 0, 0, 0}
> >  	};
> >
> > @@ -2125,6 +2128,12 @@ parse_args(int argc, char **argv)
> >  				}
> >  			}
> >  #endif
> > +			if (!strncmp(lgopts[option_index].name,
> CMD_LINE_OPT_PARSE_PTYPE,
> > +				sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
> > +				printf("soft parse-ptype is enabled \n");
> > +				parse_ptype = 1;
> > +			}
> > +
> >  			break;
> >
> >  		default:
> > @@ -2559,6 +2568,75 @@ check_all_ports_link_status(uint8_t port_num,
> uint32_t port_mask)
> >  	}
> >  }
> >
> > +static int
> > +check_packet_type_ok(int portid)
> > +{
> > +	int i;
> > +	int ret;
> > +	uint32_t ptypes[RTE_PTYPE_L3_MAX_NUM];
> > +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> > +
> > +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
> ptypes);
> > +	for (i = 0; i < ret; ++i) {
> > +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> > +			ptype_l3_ipv4 = 1;
> > +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> > +			ptype_l3_ipv6 = 1;
> > +	}
> > +
> > +	if (ptype_l3_ipv4 == 0)
> > +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> > +
> > +	if (ptype_l3_ipv6 == 0)
> > +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> > +
> > +	if (ptype_l3_ipv4 || ptype_l3_ipv6)
> > +		return 1;
> > +
> > +	return 0;
> > +}
> > +static inline void
> > +parse_packet_type(struct rte_mbuf *m)
> > +{
> > +	struct ether_hdr *eth_hdr;
> > +	struct vlan_hdr *vlan_hdr;
> > +	uint32_t packet_type = 0;
> > +	uint16_t ethertype;
> > +
> > +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> > +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> > +	if (ethertype == ETHER_TYPE_VLAN) {
> 
> I don't think either LPM or EM support packets with VLAN right now.
> So, probably there is no need to support it here.

Good to know. Will remove it.

> 
> > +		vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
> > +		ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto);
> > +	}
> > +	switch (ethertype) {
> > +	case ETHER_TYPE_IPv4:
> > +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> > +		break;
> > +	case ETHER_TYPE_IPv6:
> > +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> > +		break;
> > +	default:
> > +		break;
> > +	}
> > +
> > +	m->packet_type = packet_type;
> 
> Probably:
> m->packet_type |= packet_type;
> in case HW supports some other packet types.

I agree. Will fix it.

> 
> > +}
> > +
> > +static uint16_t
> > +cb_parse_packet_type(uint8_t port __rte_unused,
> > +		uint16_t queue __rte_unused,
> > +		struct rte_mbuf *pkts[],
> > +		uint16_t nb_pkts,
> > +		uint16_t max_pkts __rte_unused,
> > +		void *user_param __rte_unused)
> > +{
> > +	unsigned i;
> > +
> > +	for (i = 0; i < nb_pkts; ++i)
> > +		parse_packet_type(pkts[i]);
> > +}
> > +
> >  int
> >  main(int argc, char **argv)
> >  {
> > @@ -2672,6 +2750,11 @@ main(int argc, char **argv)
> >  				rte_exit(EXIT_FAILURE,
> "rte_eth_tx_queue_setup: err=%d, "
> >  					"port=%d\n", ret, portid);
> >
> > +			if (!check_packet_type_ok(portid) && !parse_ptype)
> > +				rte_exit(EXIT_FAILURE,
> > +						"port %d cannot parse packet
> type, please add --%s\n",
> > +						portid,
> CMD_LINE_OPT_PARSE_PTYPE);
> > +
> >  			qconf = &lcore_conf[lcore_id];
> >  			qconf->tx_queue_id[portid] = queueid;
> >  			queueid++;
> > @@ -2705,6 +2788,9 @@ main(int argc, char **argv)
> >  			if (ret < 0)
> >  				rte_exit(EXIT_FAILURE,
> "rte_eth_rx_queue_setup: err=%d,"
> >  						"port=%d\n", ret, portid);
> > +			if (parse_ptype)
> > +				rte_eth_add_rx_callback(portid, queueid,
> > +						cb_parse_packet_type,
> NULL);
> 
> Need to check return value.
> Konstantin

Oops, good catch!

> 
> >  		}
> >  	}
> >
> > --
> > 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2016-01-04 11:11   ` Adrien Mazarguil
@ 2016-01-05  3:08     ` Tan, Jianfeng
  2016-01-05 16:18       ` Adrien Mazarguil
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-01-05  3:08 UTC (permalink / raw)
  To: dev



On 1/4/2016 7:11 PM, Adrien Mazarguil wrote:
> Hi Jianfeng,
>
> I'm only commenting the mlx4/mlx5 bits in this message, see below.
>
> On Thu, Dec 31, 2015 at 02:53:15PM +0800, Jianfeng Tan wrote:
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   drivers/net/mlx4/mlx4.c | 27 +++++++++++++++++++++++++++
>>   1 file changed, 27 insertions(+)
>>
>> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
>> index 207bfe2..85afa32 100644
>> --- a/drivers/net/mlx4/mlx4.c
>> +++ b/drivers/net/mlx4/mlx4.c
>> @@ -2836,6 +2836,8 @@ rxq_cleanup(struct rxq *rxq)
>>    * @param flags
>>    *   RX completion flags returned by poll_length_flags().
>>    *
>> + * @note: fix mlx4_dev_ptype_info_get() if any change here.
>> + *
>>    * @return
>>    *   Packet type for struct rte_mbuf.
>>    */
>> @@ -4268,6 +4270,30 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>>   	priv_unlock(priv);
>>   }
>>   
>> +static int
>> +mlx4_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
>> +		uint32_t ptypes[])
>> +{
>> +	int num = 0;
>> +
>> +	if ((dev->rx_pkt_burst == mlx4_rx_burst)
>> +			|| (dev->rx_pkt_burst == mlx4_rx_burst_sp)) {
>> +		/* refers to rxq_cq_to_pkt_type() */
>> +		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
>> +			ptypes[num++] = RTE_PTYPE_L3_IPV4;
>> +			ptypes[num++] = RTE_PTYPE_L3_IPV6;
>> +		}
>> +
>> +		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
>> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
>> +			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
>> +		}
>> +	} else
>> +		num = -ENOTSUP;
>> +
>> +	return num;
>> +}
> I think checking for mlx4_rx_burst and mlx4_rx_burst_sp is unnecessary at
> the moment, all RX burst functions do update the packet_type field, no need
> for extra complexity.
>
> Same comment for mlx5.

Hi Mazarguil,

My original thought is that rx_pkt_burst could be also set as 
removed_rx_burst, which does not make sense indeed
because it's only possible when the device is closed.

Another consideration is to keep same style with other devices. Each 
kind of device could have several rx burst functions.
So current implementation can keep extensibility to add new rx burst 
functions. How do you think of it?

Thanks,
Jianfeng

>
>> +
>>   /**
>>    * DPDK callback to get device statistics.
>>    *
>> @@ -4989,6 +5015,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
>>   	.stats_reset = mlx4_stats_reset,
>>   	.queue_stats_mapping_set = NULL,
>>   	.dev_infos_get = mlx4_dev_infos_get,
>> +	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
>>   	.vlan_filter_set = mlx4_vlan_filter_set,
>>   	.vlan_tpid_set = NULL,
>>   	.vlan_strip_queue_set = NULL,
>> -- 
>> 2.1.4
>>

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-04 14:36     ` Ananyev, Konstantin
@ 2016-01-05 16:14       ` Nélio Laranjeiro
  2016-01-05 16:50         ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Nélio Laranjeiro @ 2016-01-05 16:14 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev

On Mon, Jan 04, 2016 at 02:36:14PM +0000, Ananyev, Konstantin wrote:
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> > Sent: Monday, January 04, 2016 11:38 AM
> > To: Tan, Jianfeng
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > 
> > I'm not sure about the usefulness of this new callback, but one issue I see
> > with rte_eth_dev_get_ptype_info() is that determining the proper size for
> > ptypes[] according to a mask is awkward. For instance suppose
> > RTE_PTYPE_L4_MASK is redefined to a different size at some point, the caller
> > must dynamically adjust its ptypes[] array size to avoid a possible
> > overflow, just in case.
> > 
> > I suggest one of these solutions:
> > 
> > - A callback to query for a single type at once instead (easiest method in
> >   my opinion).
> > 
> > - An additional argument with the number of entries in ptypes[], in which
> >   case rte_eth_dev_get_ptype_info() should return the number of entries that
> >   would have been filled regardless, a bit like snprintf().
> 
> +1 for the second option.
> Also not sure you really need: RTE_PTYPE_*_MAX_NUM macros.
> Konstantin

+1 for the second option.  But see below.

> > 
> > On Thu, Dec 31, 2015 at 02:53:08PM +0800, Jianfeng Tan wrote:
> > > Add a new API rte_eth_dev_get_ptype_info to query what/if packet type will
> > > be set by current rx burst function.
> > >
> > > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > > ---
> > >  lib/librte_ether/rte_ethdev.c | 12 ++++++++++++
> > >  lib/librte_ether/rte_ethdev.h | 22 ++++++++++++++++++++++
> > >  lib/librte_mbuf/rte_mbuf.h    | 13 +++++++++++++
> > >  3 files changed, 47 insertions(+)
> > >
> > > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > > index ed971b4..1885374 100644
> > > --- a/lib/librte_ether/rte_ethdev.c
> > > +++ b/lib/librte_ether/rte_ethdev.c
> > > @@ -1614,6 +1614,18 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> > >  	dev_info->driver_name = dev->data->drv_name;
> > >  }
> > >
> > > +int
> > > +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> > > +		uint32_t ptypes[])
> > > +{
> > > +	struct rte_eth_dev *dev;
> > > +
> > > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > > +	dev = &rte_eth_devices[port_id];
> > > +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> > > +	return (*dev->dev_ops->dev_ptype_info_get)(dev, ptype_mask, ptypes);
> > > +}
> > > +
> > >  void
> > >  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
> > >  {
> > > diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > > index bada8ad..e97b632 100644
> > > --- a/lib/librte_ether/rte_ethdev.h
> > > +++ b/lib/librte_ether/rte_ethdev.h
> > > @@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
> > >  				    struct rte_eth_dev_info *dev_info);
> > >  /**< @internal Get specific informations of an Ethernet device. */
> > >
> > > +typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
> > > +		uint32_t ptype_mask, uint32_t ptypes[]);
> > > +/**< @internal Get ptype info of eth_rx_burst_t. */
> > > +
> > >  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
> > >  				    uint16_t queue_id);
> > >  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> > > @@ -1347,6 +1351,7 @@ struct eth_dev_ops {
> > >  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
> > >  	/**< Configure per queue stat counter mapping. */
> > >  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> > > +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
> > >  	mtu_set_t                  mtu_set; /**< Set MTU. */
> > >  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
> > >  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> > > @@ -2273,6 +2278,23 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
> > >  				 struct rte_eth_dev_info *dev_info);
> > >
> > >  /**
> > > + * Retrieve the contextual information of an Ethernet device.
> > > + *
> > > + * @param port_id
> > > + *   The port identifier of the Ethernet device.
> > > + * @param ptype_mask
> > > + *   A hint of what kind of packet type which the caller is interested in
> > > + * @param ptypes
> > > + *   An array of packet types to be filled with
> > > + * @return
> > > + *   - (>=0) if successful. Indicate number of valid values in ptypes array.
> > > + *   - (-ENOTSUP) if hardware-assisted VLAN stripping not configured.
> > > + *   - (-ENODEV) if *port_id* invalid.
> > > + */
> > > +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> > > +				 uint32_t ptype_mask, uint32_t ptypes[]);
> > > +
> > > +/**
> > >   * Retrieve the MTU of an Ethernet device.
> > >   *
> > >   * @param port_id
> > > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > > index f234ac9..21d4aa2 100644
> > > --- a/lib/librte_mbuf/rte_mbuf.h
> > > +++ b/lib/librte_mbuf/rte_mbuf.h
> > > @@ -282,6 +282,8 @@ extern "C" {
> > >   * It is used for outer packet for tunneling cases.
> > >   */
> > >  #define RTE_PTYPE_L2_MASK                   0x0000000f
> > > +
> > > +#define RTE_PTYPE_L2_MAX_NUM				4
> > >  /**
> > >   * IP (Internet Protocol) version 4 packet type.
> > >   * It is used for outer packet for tunneling cases, and does not contain any
> > > @@ -349,6 +351,8 @@ extern "C" {
> > >   * It is used for outer packet for tunneling cases.
> > >   */
> > >  #define RTE_PTYPE_L3_MASK                   0x000000f0
> > > +
> > > +#define RTE_PTYPE_L3_MAX_NUM				6
> > >  /**
> > >   * TCP (Transmission Control Protocol) packet type.
> > >   * It is used for outer packet for tunneling cases.
> > > @@ -435,6 +439,8 @@ extern "C" {
> > >   * It is used for outer packet for tunneling cases.
> > >   */
> > >  #define RTE_PTYPE_L4_MASK                   0x00000f00
> > > +
> > > +#define RTE_PTYPE_L4_MAX_NUM				6
> > >  /**
> > >   * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
> > >   *
> > > @@ -508,6 +514,8 @@ extern "C" {
> > >   * Mask of tunneling packet types.
> > >   */
> > >  #define RTE_PTYPE_TUNNEL_MASK               0x0000f000
> > > +
> > > +#define RTE_PTYPE_TUNNEL_MAX_NUM			6
> > >  /**
> > >   * Ethernet packet type.
> > >   * It is used for inner packet type only.
> > > @@ -527,6 +535,8 @@ extern "C" {
> > >   * Mask of inner layer 2 packet types.
> > >   */
> > >  #define RTE_PTYPE_INNER_L2_MASK             0x000f0000
> > > +
> > > +#define RTE_PTYPE_INNER_L2_MAX_NUM			2
> > >  /**
> > >   * IP (Internet Protocol) version 4 packet type.
> > >   * It is used for inner packet only, and does not contain any header option.
> > > @@ -588,6 +598,8 @@ extern "C" {
> > >   * Mask of inner layer 3 packet types.
> > >   */
> > >  #define RTE_PTYPE_INNER_L3_MASK             0x00f00000
> > > +
> > > +#define RTE_PTYPE_INNER_L3_MAX_NUM			6
> > >  /**
> > >   * TCP (Transmission Control Protocol) packet type.
> > >   * It is used for inner packet only.
> > > @@ -666,6 +678,7 @@ extern "C" {
> > >   */
> > >  #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
> > >
> > > +#define RTE_PTYPE_INNER_L4_MAX_NUM			6
> > >  /**
> > >   * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
> > >   * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can

I think we miss a comment here in how those 2/6/4 values are chosen
because, according to the mask, I expect 16 possibilities but I get
less.  It will help a lot anyone who needs to add a new type.

Extending the snprintf behavior above, it is best to remove the mask
argument altogether and have rte_eth_dev_get_ptype_info() return the
entire list every time.  Applications need to iterate on the result in
any case.

  rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptypes[],
                             size_t max_entries)



Another point, I have read the example patch (l3fwd) but I don't
understand why the PMD is not responsible for filling the packet type in
the MBUF (packet parsing is done by parse_packet_type()).  Why the extra
computation?

I see it more like an offload request (as checksum, etc...) and if the
NIC does not support it then the application does the necessary overload.

Best regards,

-- 
Nélio Laranjeiro
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2016-01-05  3:08     ` Tan, Jianfeng
@ 2016-01-05 16:18       ` Adrien Mazarguil
  2016-01-11  5:07         ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-05 16:18 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev

On Tue, Jan 05, 2016 at 11:08:04AM +0800, Tan, Jianfeng wrote:
> 
> 
> On 1/4/2016 7:11 PM, Adrien Mazarguil wrote:
> >Hi Jianfeng,
> >
> >I'm only commenting the mlx4/mlx5 bits in this message, see below.
> >
> >On Thu, Dec 31, 2015 at 02:53:15PM +0800, Jianfeng Tan wrote:
> >>Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> >>---
> >>  drivers/net/mlx4/mlx4.c | 27 +++++++++++++++++++++++++++
> >>  1 file changed, 27 insertions(+)
> >>
> >>diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> >>index 207bfe2..85afa32 100644
> >>--- a/drivers/net/mlx4/mlx4.c
> >>+++ b/drivers/net/mlx4/mlx4.c
> >>@@ -2836,6 +2836,8 @@ rxq_cleanup(struct rxq *rxq)
> >>   * @param flags
> >>   *   RX completion flags returned by poll_length_flags().
> >>   *
> >>+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
> >>+ *
> >>   * @return
> >>   *   Packet type for struct rte_mbuf.
> >>   */
> >>@@ -4268,6 +4270,30 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
> >>  	priv_unlock(priv);
> >>  }
> >>+static int
> >>+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptype_mask,
> >>+		uint32_t ptypes[])

Note this line is not properly indented (uint32_t should be aligned like the
rest of the file).

> >>+{
> >>+	int num = 0;
> >>+
> >>+	if ((dev->rx_pkt_burst == mlx4_rx_burst)
> >>+			|| (dev->rx_pkt_burst == mlx4_rx_burst_sp)) {

I prefer operators/separators at the end of the previous line, indentation
should be fixed as well.

> >>+		/* refers to rxq_cq_to_pkt_type() */
> >>+		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
> >>+			ptypes[num++] = RTE_PTYPE_L3_IPV4;
> >>+			ptypes[num++] = RTE_PTYPE_L3_IPV6;
> >>+		}
> >>+
> >>+		if ((ptype_mask & RTE_PTYPE_INNER_L3_MASK) == RTE_PTYPE_INNER_L3_MASK) {
> >>+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
> >>+			ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
> >>+		}
> >>+	} else
> >>+		num = -ENOTSUP;
> >>+
> >>+	return num;
> >>+}
> >I think checking for mlx4_rx_burst and mlx4_rx_burst_sp is unnecessary at
> >the moment, all RX burst functions do update the packet_type field, no need
> >for extra complexity.
> >
> >Same comment for mlx5.
> 
> Hi Mazarguil,
> 
> My original thought is that rx_pkt_burst could be also set as
> removed_rx_burst, which does not make sense indeed
> because it's only possible when the device is closed.

Yes, indeed.

> Another consideration is to keep same style with other devices. Each
> kind of device could have several rx burst functions.
> So current implementation can keep extensibility to add new rx burst
> functions. How do you think of it?

OK, that makes sense. Please check my above comments about coding
style/indents (I know I'm annoying).

> >>+
> >>  /**
> >>   * DPDK callback to get device statistics.
> >>   *
> >>@@ -4989,6 +5015,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
> >>  	.stats_reset = mlx4_stats_reset,
> >>  	.queue_stats_mapping_set = NULL,
> >>  	.dev_infos_get = mlx4_dev_infos_get,
> >>+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
> >>  	.vlan_filter_set = mlx4_vlan_filter_set,
> >>  	.vlan_tpid_set = NULL,
> >>  	.vlan_strip_queue_set = NULL,
> >>-- 
> >>2.1.4
> >>
> 

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 12/12] examples/l3fwd: add option to parse ptype
  2016-01-05  2:44     ` Tan, Jianfeng
@ 2016-01-05 16:49       ` Ananyev, Konstantin
  2016-01-07  1:20         ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-05 16:49 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi Jianfeng,

> > >
> > > +static int
> > > +check_packet_type_ok(int portid)
> > > +{
> > > +	int i;
> > > +	int ret;
> > > +	uint32_t ptypes[RTE_PTYPE_L3_MAX_NUM];
> > > +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> > > +
> > > +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
> > ptypes);
> > > +	for (i = 0; i < ret; ++i) {
> > > +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> > > +			ptype_l3_ipv4 = 1;
> > > +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> > > +			ptype_l3_ipv6 = 1;
> > > +	}
> > > +
> > > +	if (ptype_l3_ipv4 == 0)
> > > +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> > > +
> > > +	if (ptype_l3_ipv6 == 0)
> > > +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> > > +
> > > +	if (ptype_l3_ipv4 || ptype_l3_ipv6)
> > > +		return 1;


Forgot one thing: I think it should be:

if (ptype_l3_ipv4 && ptype_l3_ipv6)
  return 1;
return 0;

or just:

return ptype_l3_ipv4 && ptype_l3_ipv6;

Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-05 16:14       ` Nélio Laranjeiro
@ 2016-01-05 16:50         ` Ananyev, Konstantin
  2016-01-06 10:00           ` Adrien Mazarguil
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-05 16:50 UTC (permalink / raw)
  To: Nélio Laranjeiro, Tan, Jianfeng; +Cc: dev

Hi Neilo,

> -----Original Message-----
> From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> Sent: Tuesday, January 05, 2016 4:14 PM
> To: Tan, Jianfeng
> Cc: Adrien Mazarguil; Ananyev, Konstantin; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> 
> On Mon, Jan 04, 2016 at 02:36:14PM +0000, Ananyev, Konstantin wrote:
> >
> >
> > > -----Original Message-----
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> > > Sent: Monday, January 04, 2016 11:38 AM
> > > To: Tan, Jianfeng
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > >
> > > I'm not sure about the usefulness of this new callback, but one issue I see
> > > with rte_eth_dev_get_ptype_info() is that determining the proper size for
> > > ptypes[] according to a mask is awkward. For instance suppose
> > > RTE_PTYPE_L4_MASK is redefined to a different size at some point, the caller
> > > must dynamically adjust its ptypes[] array size to avoid a possible
> > > overflow, just in case.
> > >
> > > I suggest one of these solutions:
> > >
> > > - A callback to query for a single type at once instead (easiest method in
> > >   my opinion).
> > >
> > > - An additional argument with the number of entries in ptypes[], in which
> > >   case rte_eth_dev_get_ptype_info() should return the number of entries that
> > >   would have been filled regardless, a bit like snprintf().
> >
> > +1 for the second option.
> > Also not sure you really need: RTE_PTYPE_*_MAX_NUM macros.
> > Konstantin
> 
> +1 for the second option.  But see below.
> 
> > >
> > > On Thu, Dec 31, 2015 at 02:53:08PM +0800, Jianfeng Tan wrote:
> > > > Add a new API rte_eth_dev_get_ptype_info to query what/if packet type will
> > > > be set by current rx burst function.
> > > >
> > > > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > > > ---
> > > >  lib/librte_ether/rte_ethdev.c | 12 ++++++++++++
> > > >  lib/librte_ether/rte_ethdev.h | 22 ++++++++++++++++++++++
> > > >  lib/librte_mbuf/rte_mbuf.h    | 13 +++++++++++++
> > > >  3 files changed, 47 insertions(+)
> > > >
> > > > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > > > index ed971b4..1885374 100644
> > > > --- a/lib/librte_ether/rte_ethdev.c
> > > > +++ b/lib/librte_ether/rte_ethdev.c
> > > > @@ -1614,6 +1614,18 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> > > >  	dev_info->driver_name = dev->data->drv_name;
> > > >  }
> > > >
> > > > +int
> > > > +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> > > > +		uint32_t ptypes[])
> > > > +{
> > > > +	struct rte_eth_dev *dev;
> > > > +
> > > > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > > > +	dev = &rte_eth_devices[port_id];
> > > > +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> > > > +	return (*dev->dev_ops->dev_ptype_info_get)(dev, ptype_mask, ptypes);
> > > > +}
> > > > +
> > > >  void
> > > >  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
> > > >  {
> > > > diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > > > index bada8ad..e97b632 100644
> > > > --- a/lib/librte_ether/rte_ethdev.h
> > > > +++ b/lib/librte_ether/rte_ethdev.h
> > > > @@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
> > > >  				    struct rte_eth_dev_info *dev_info);
> > > >  /**< @internal Get specific informations of an Ethernet device. */
> > > >
> > > > +typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
> > > > +		uint32_t ptype_mask, uint32_t ptypes[]);
> > > > +/**< @internal Get ptype info of eth_rx_burst_t. */
> > > > +
> > > >  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
> > > >  				    uint16_t queue_id);
> > > >  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> > > > @@ -1347,6 +1351,7 @@ struct eth_dev_ops {
> > > >  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
> > > >  	/**< Configure per queue stat counter mapping. */
> > > >  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> > > > +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
> > > >  	mtu_set_t                  mtu_set; /**< Set MTU. */
> > > >  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
> > > >  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> > > > @@ -2273,6 +2278,23 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
> > > >  				 struct rte_eth_dev_info *dev_info);
> > > >
> > > >  /**
> > > > + * Retrieve the contextual information of an Ethernet device.
> > > > + *
> > > > + * @param port_id
> > > > + *   The port identifier of the Ethernet device.
> > > > + * @param ptype_mask
> > > > + *   A hint of what kind of packet type which the caller is interested in
> > > > + * @param ptypes
> > > > + *   An array of packet types to be filled with
> > > > + * @return
> > > > + *   - (>=0) if successful. Indicate number of valid values in ptypes array.
> > > > + *   - (-ENOTSUP) if hardware-assisted VLAN stripping not configured.
> > > > + *   - (-ENODEV) if *port_id* invalid.
> > > > + */
> > > > +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> > > > +				 uint32_t ptype_mask, uint32_t ptypes[]);
> > > > +
> > > > +/**
> > > >   * Retrieve the MTU of an Ethernet device.
> > > >   *
> > > >   * @param port_id
> > > > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > > > index f234ac9..21d4aa2 100644
> > > > --- a/lib/librte_mbuf/rte_mbuf.h
> > > > +++ b/lib/librte_mbuf/rte_mbuf.h
> > > > @@ -282,6 +282,8 @@ extern "C" {
> > > >   * It is used for outer packet for tunneling cases.
> > > >   */
> > > >  #define RTE_PTYPE_L2_MASK                   0x0000000f
> > > > +
> > > > +#define RTE_PTYPE_L2_MAX_NUM				4
> > > >  /**
> > > >   * IP (Internet Protocol) version 4 packet type.
> > > >   * It is used for outer packet for tunneling cases, and does not contain any
> > > > @@ -349,6 +351,8 @@ extern "C" {
> > > >   * It is used for outer packet for tunneling cases.
> > > >   */
> > > >  #define RTE_PTYPE_L3_MASK                   0x000000f0
> > > > +
> > > > +#define RTE_PTYPE_L3_MAX_NUM				6
> > > >  /**
> > > >   * TCP (Transmission Control Protocol) packet type.
> > > >   * It is used for outer packet for tunneling cases.
> > > > @@ -435,6 +439,8 @@ extern "C" {
> > > >   * It is used for outer packet for tunneling cases.
> > > >   */
> > > >  #define RTE_PTYPE_L4_MASK                   0x00000f00
> > > > +
> > > > +#define RTE_PTYPE_L4_MAX_NUM				6
> > > >  /**
> > > >   * IP (Internet Protocol) in IP (Internet Protocol) tunneling packet type.
> > > >   *
> > > > @@ -508,6 +514,8 @@ extern "C" {
> > > >   * Mask of tunneling packet types.
> > > >   */
> > > >  #define RTE_PTYPE_TUNNEL_MASK               0x0000f000
> > > > +
> > > > +#define RTE_PTYPE_TUNNEL_MAX_NUM			6
> > > >  /**
> > > >   * Ethernet packet type.
> > > >   * It is used for inner packet type only.
> > > > @@ -527,6 +535,8 @@ extern "C" {
> > > >   * Mask of inner layer 2 packet types.
> > > >   */
> > > >  #define RTE_PTYPE_INNER_L2_MASK             0x000f0000
> > > > +
> > > > +#define RTE_PTYPE_INNER_L2_MAX_NUM			2
> > > >  /**
> > > >   * IP (Internet Protocol) version 4 packet type.
> > > >   * It is used for inner packet only, and does not contain any header option.
> > > > @@ -588,6 +598,8 @@ extern "C" {
> > > >   * Mask of inner layer 3 packet types.
> > > >   */
> > > >  #define RTE_PTYPE_INNER_L3_MASK             0x00f00000
> > > > +
> > > > +#define RTE_PTYPE_INNER_L3_MAX_NUM			6
> > > >  /**
> > > >   * TCP (Transmission Control Protocol) packet type.
> > > >   * It is used for inner packet only.
> > > > @@ -666,6 +678,7 @@ extern "C" {
> > > >   */
> > > >  #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
> > > >
> > > > +#define RTE_PTYPE_INNER_L4_MAX_NUM			6
> > > >  /**
> > > >   * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
> > > >   * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
> 
> I think we miss a comment here in how those 2/6/4 values are chosen
> because, according to the mask, I expect 16 possibilities but I get
> less.  It will help a lot anyone who needs to add a new type.
> 
> Extending the snprintf behavior above, it is best to remove the mask
> argument altogether and have rte_eth_dev_get_ptype_info() return the
> entire list every time.  Applications need to iterate on the result in
> any case.

I think we'd better keep mask argument.
In many cases upper layer only interested in some particular  subset of
all packet types that HW can recognise.
Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
tunnelling packet types, etc.
If caller needs to know all recognised ptypes, he can set mask==-1,
In that case all supported packet types will be returned.

> 
>   rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptypes[],
>                              size_t max_entries)
> 
> 
> 
> Another point, I have read the example patch (l3fwd) but I don't
> understand why the PMD is not responsible for filling the packet type in
> the MBUF (packet parsing is done by parse_packet_type()).  Why the extra
> computation?

As I understand there are 3 possibilities now:
1. HW supports ptype recognition and SW ptype parsing is never done
(--parse-ptype is not specified).
2. HW supports ptype recognition, but and SW ptype parsing is done anyway
(--parse-ptype is specified).
3. HW doesn't support and ptype recognition, and and SW ptype parsing is done
(--parse-ptype is specified).

I suppose the question is what for introduce '--parse-ptype' at all?
My thought because of #2, so people can easily check what will be the performance impact of SW parsing. 

Konstantin

> 
> I see it more like an offload request (as checksum, etc...) and if the
> NIC does not support it then the application does the necessary overload.
> 
> Best regards,
> 
> --
> Nélio Laranjeiro
> 6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 02/12] pmd/cxgbe: add dev_ptype_info_get implementation
  2015-12-31  6:53 ` [PATCH 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2016-01-06  7:11   ` Rahul Lakkireddy
  2016-01-06  8:23     ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Rahul Lakkireddy @ 2016-01-06  7:11 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, Kumar Sanghvi, Nirranjan Kirubaharan

Hi Jianfeng,

On Thursday, December 12/31/15, 2015 at 14:53:09 +0800, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/cxgbe/cxgbe_ethdev.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
> index 97ef152..f17d5d5 100644
> --- a/drivers/net/cxgbe/cxgbe_ethdev.c
> +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
> @@ -767,6 +767,22 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
>  			     &pi->link_cfg);
>  }
>  
> +static int cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev __rte_unused,
> +		uint32_t ptype_mask, uint32_t ptypes[])
> +{

No need for the __rte_unused for eth_dev above since it's being used for
if conditional below.

> +	int num = 0;
> +
> +	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts) {
> +		if ((ptype_mask & RTE_PTYPE_L3_MASK) == RTE_PTYPE_L3_MASK) {
> +			ptypes[num++] = RTE_PTYPE_L3_IPV4;
> +			ptypes[num++] = RTE_PTYPE_L3_IPV6;
> +		}
> +	} else
> +		num = -ENOTSUP;
> +
> +	return num;
> +}
> +
>  static struct eth_dev_ops cxgbe_eth_dev_ops = {
>  	.dev_start		= cxgbe_dev_start,
>  	.dev_stop		= cxgbe_dev_stop,
> @@ -777,6 +793,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
>  	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
>  	.dev_configure		= cxgbe_dev_configure,
>  	.dev_infos_get		= cxgbe_dev_info_get,
> +	.dev_ptype_info_get		= cxgbe_dev_ptype_info_get,
>  	.link_update		= cxgbe_dev_link_update,
>  	.mtu_set		= cxgbe_dev_mtu_set,
>  	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
> -- 
> 2.1.4
> 

Thanks,
Rahul

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 02/12] pmd/cxgbe: add dev_ptype_info_get implementation
  2016-01-06  7:11   ` Rahul Lakkireddy
@ 2016-01-06  8:23     ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-01-06  8:23 UTC (permalink / raw)
  To: Rahul Lakkireddy; +Cc: dev, Kumar Sanghvi, Nirranjan Kirubaharan



On 1/6/2016 3:11 PM, Rahul Lakkireddy wrote:
> Hi Jianfeng,
>
> On Thursday, December 12/31/15, 2015 at 14:53:09 +0800, Jianfeng Tan wrote:
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   drivers/net/cxgbe/cxgbe_ethdev.c | 17 +++++++++++++++++
>>   1 file changed, 17 insertions(+)
>>
>> diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
>> index 97ef152..f17d5d5 100644
>> --- a/drivers/net/cxgbe/cxgbe_ethdev.c
>> +++ b/drivers/net/cxgbe/cxgbe_ethdev.c
>> @@ -767,6 +767,22 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
>>   			     &pi->link_cfg);
>>   }
>>   
>> +static int cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev __rte_unused,
>> +		uint32_t ptype_mask, uint32_t ptypes[])
>> +{
> No need for the __rte_unused for eth_dev above since it's being used for
> if conditional below.
Hi Rahul,

Thanks! Will fix it in next version.

Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-05 16:50         ` Ananyev, Konstantin
@ 2016-01-06 10:00           ` Adrien Mazarguil
  2016-01-06 14:29             ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-06 10:00 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On Tue, Jan 05, 2016 at 04:50:31PM +0000, Ananyev, Konstantin wrote:
[...]
> > -----Original Message-----
> > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
[...]
> > I think we miss a comment here in how those 2/6/4 values are chosen
> > because, according to the mask, I expect 16 possibilities but I get
> > less.  It will help a lot anyone who needs to add a new type.
> > 
> > Extending the snprintf behavior above, it is best to remove the mask
> > argument altogether and have rte_eth_dev_get_ptype_info() return the
> > entire list every time.  Applications need to iterate on the result in
> > any case.
> 
> I think we'd better keep mask argument.
> In many cases upper layer only interested in some particular  subset of
> all packet types that HW can recognise.
> Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
> tunnelling packet types, etc.
> If caller needs to know all recognised ptypes, he can set mask==-1,
> In that case all supported packet types will be returned.

There are other drawbacks to the mask argument in my opinion. The API will
have to be updated again as soon as 32 bits aren't enough to represent all
possible masks. We can't predict it will be large enough forever but on the
other hand, using uint64_t seems overkill at this point.

I think this use for masks should be avoided when performance does not
matter much, as in this case, user application cannot know the number of
entries in advance and must rely on the returned value to iterate.

A helper function can be added to convert a RTE_PTYPE_* value to the layer
it belongs to (using enum to define possible values).

If we absolutely want a mean to filter returned values, I suggest we use
this enum instead of the mask argument. Since it won't be a mask, it won't
have to be updated every time a new protocol requires extending one.

> >   rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptypes[],
> >                              size_t max_entries)
> > 
> > 
> > 
> > Another point, I have read the example patch (l3fwd) but I don't
> > understand why the PMD is not responsible for filling the packet type in
> > the MBUF (packet parsing is done by parse_packet_type()).  Why the extra
> > computation?
> 
> As I understand there are 3 possibilities now:
> 1. HW supports ptype recognition and SW ptype parsing is never done
> (--parse-ptype is not specified).
> 2. HW supports ptype recognition, but and SW ptype parsing is done anyway
> (--parse-ptype is specified).
> 3. HW doesn't support and ptype recognition, and and SW ptype parsing is done
> (--parse-ptype is specified).
> 
> I suppose the question is what for introduce '--parse-ptype' at all?
> My thought because of #2, so people can easily check what will be the performance impact of SW parsing. 
> 
> Konstantin
> 
> > 
> > I see it more like an offload request (as checksum, etc...) and if the
> > NIC does not support it then the application does the necessary overload.
> > 
> > Best regards,
> > 
> > --
> > Nélio Laranjeiro
> > 6WIND

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-06 10:00           ` Adrien Mazarguil
@ 2016-01-06 14:29             ` Ananyev, Konstantin
  2016-01-06 15:44               ` Adrien Mazarguil
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-06 14:29 UTC (permalink / raw)
  To: Adrien Mazarguil; +Cc: dev



> -----Original Message-----
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> Sent: Wednesday, January 06, 2016 10:01 AM
> To: Ananyev, Konstantin
> Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> 
> On Tue, Jan 05, 2016 at 04:50:31PM +0000, Ananyev, Konstantin wrote:
> [...]
> > > -----Original Message-----
> > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> [...]
> > > I think we miss a comment here in how those 2/6/4 values are chosen
> > > because, according to the mask, I expect 16 possibilities but I get
> > > less.  It will help a lot anyone who needs to add a new type.
> > >
> > > Extending the snprintf behavior above, it is best to remove the mask
> > > argument altogether and have rte_eth_dev_get_ptype_info() return the
> > > entire list every time.  Applications need to iterate on the result in
> > > any case.
> >
> > I think we'd better keep mask argument.
> > In many cases upper layer only interested in some particular  subset of
> > all packet types that HW can recognise.
> > Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
> > tunnelling packet types, etc.
> > If caller needs to know all recognised ptypes, he can set mask==-1,
> > In that case all supported packet types will be returned.
> 
> There are other drawbacks to the mask argument in my opinion. The API will
> have to be updated again as soon as 32 bits aren't enough to represent all
> possible masks. We can't predict it will be large enough forever but on the
> other hand, using uint64_t seems overkill at this point.

Inside rte_mbuf packet_type itself is a 32 bit value.
These 32 bits are divided into several fields to mark packet types,
i.e: bits [0-3] are for all possible L2 types, bits [4-7] for L3 types, etc.
As long as packet_type itself is 32bits, 32bit mask is sufficient. 
If we'll ever run out of 32 bits in packet_type itself, it will be ABI change anyway.

> 
> I think this use for masks should be avoided when performance does not
> matter much, as in this case, user application cannot know the number of
> entries in advance and must rely on the returned value to iterate.

User doesn't know numbers of entries in advance anyway (with and without the mask).
That's why this function was introduced at first place.
With mask it just a bit more handy, in case user cares only about particular subset of supported
packet types (only L2 let say). 

> 
> A helper function can be added to convert a RTE_PTYPE_* value to the layer
> it belongs to (using enum to define possible values).

Not sure what for?

> 
> If we absolutely want a mean to filter returned values, I suggest we use
> this enum instead of the mask argument.
> Since it won't be a mask, it won't
> have to be updated every time a new protocol requires extending one.

Number of bits PTYPE_L2/L3/L4,... layers are already defined.
So let say RTE_PTYPE_L2_MASK shouldn't change if you'll add new L2 ptype -
there are few reserved values right now.  
if one day we'll run out bits in let say RTE_PTYPE_L2_MASK  and will have to increase its size -
it would mean change of the packet_type layout and possible ABI breakage anyway. 
Konstantin

> 
> > >   rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptypes[],
> > >                              size_t max_entries)
> > >
> > >
> > >
> > > Another point, I have read the example patch (l3fwd) but I don't
> > > understand why the PMD is not responsible for filling the packet type in
> > > the MBUF (packet parsing is done by parse_packet_type()).  Why the extra
> > > computation?
> >
> > As I understand there are 3 possibilities now:
> > 1. HW supports ptype recognition and SW ptype parsing is never done
> > (--parse-ptype is not specified).
> > 2. HW supports ptype recognition, but and SW ptype parsing is done anyway
> > (--parse-ptype is specified).
> > 3. HW doesn't support and ptype recognition, and and SW ptype parsing is done
> > (--parse-ptype is specified).
> >
> > I suppose the question is what for introduce '--parse-ptype' at all?
> > My thought because of #2, so people can easily check what will be the performance impact of SW parsing.
> >
> > Konstantin
> >
> > >
> > > I see it more like an offload request (as checksum, etc...) and if the
> > > NIC does not support it then the application does the necessary overload.
> > >
> > > Best regards,
> > >
> > > --
> > > Nélio Laranjeiro
> > > 6WIND
> 
> --
> Adrien Mazarguil
> 6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-06 14:29             ` Ananyev, Konstantin
@ 2016-01-06 15:44               ` Adrien Mazarguil
  2016-01-06 16:44                 ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-06 15:44 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On Wed, Jan 06, 2016 at 02:29:07PM +0000, Ananyev, Konstantin wrote:
> 
> 
> > -----Original Message-----
> > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > Sent: Wednesday, January 06, 2016 10:01 AM
> > To: Ananyev, Konstantin
> > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > 
> > On Tue, Jan 05, 2016 at 04:50:31PM +0000, Ananyev, Konstantin wrote:
> > [...]
> > > > -----Original Message-----
> > > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > [...]
> > > > I think we miss a comment here in how those 2/6/4 values are chosen
> > > > because, according to the mask, I expect 16 possibilities but I get
> > > > less.  It will help a lot anyone who needs to add a new type.
> > > >
> > > > Extending the snprintf behavior above, it is best to remove the mask
> > > > argument altogether and have rte_eth_dev_get_ptype_info() return the
> > > > entire list every time.  Applications need to iterate on the result in
> > > > any case.
> > >
> > > I think we'd better keep mask argument.
> > > In many cases upper layer only interested in some particular  subset of
> > > all packet types that HW can recognise.
> > > Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
> > > tunnelling packet types, etc.
> > > If caller needs to know all recognised ptypes, he can set mask==-1,
> > > In that case all supported packet types will be returned.
> > 
> > There are other drawbacks to the mask argument in my opinion. The API will
> > have to be updated again as soon as 32 bits aren't enough to represent all
> > possible masks. We can't predict it will be large enough forever but on the
> > other hand, using uint64_t seems overkill at this point.
> 
> Inside rte_mbuf packet_type itself is a 32 bit value.
> These 32 bits are divided into several fields to mark packet types,
> i.e: bits [0-3] are for all possible L2 types, bits [4-7] for L3 types, etc.
> As long as packet_type itself is 32bits, 32bit mask is sufficient. 
> If we'll ever run out of 32 bits in packet_type itself, it will be ABI change anyway.

Sure, however why not do it now this issue has been raised so this function
doesn't need updating the day it breaks? I know there's a million other
places with a similar problem but I'm all for making new code future proof.

Perhaps in this particular case there is no way to hit the limit (although
there are only four unused bits left to extend RTE_PTYPE masks) but we've
seen this happen too many times with subsequent ABI breakage.

> > I think this use for masks should be avoided when performance does not
> > matter much, as in this case, user application cannot know the number of
> > entries in advance and must rely on the returned value to iterate.
> 
> User doesn't know numbers of entries in advance anyway (with and without the mask).
> That's why this function was introduced at first place.
> 
> With mask it just a bit more handy, in case user cares only about particular subset of supported
> packet types (only L2 let say). 

OK, so we definitely need something to let applications know the layer a
given packet type belongs to, I'm sure it can be done in a convenient way
that won't be limited to the underlying type of the mask.

> > A helper function can be added to convert a RTE_PTYPE_* value to the layer
> > it belongs to (using enum to define possible values).
> 
> Not sure what for?

This is assuming rte_eth_dev_get_ptype_info() doesn't filter anything (no
"mask" argument). In that case a separate function must be added to convert
RTE_PTYPE_* values to a layer, so applications can look for interesting
packet types while parsing plist[] on their own.

This layer information could be defined as an enum, i.e.:

 enum rte_ptype_info {
     RTE_PTYPE_UNKNOWN,
     RTE_PTYPE_L2,
     RTE_PTYPE_L3,
    ...
 };

Or even an int value (2 standing for for "layer 2" etc. Tunnel encapsulation
wouldn't be described easily that way though). It's just an idea.

> > If we absolutely want a mean to filter returned values, I suggest we use
> > this enum instead of the mask argument.
> > Since it won't be a mask, it won't
> > have to be updated every time a new protocol requires extending one.
> 
> Number of bits PTYPE_L2/L3/L4,... layers are already defined.
> So let say RTE_PTYPE_L2_MASK shouldn't change if you'll add new L2 ptype -
> there are few reserved values right now.  
> if one day we'll run out bits in let say RTE_PTYPE_L2_MASK  and will have to increase its size -
> it would mean change of the packet_type layout and possible ABI breakage anyway. 

I'm aware of this, only pointing out we tend to rely on masks and type
boundaries a bit too much when there are other methods that are as (if not
more) convenient.

Perhaps some sort of tunneled packet types beyond inner L4 consuming the
four remaining bits will be added? That could happen soon.

> Konstantin
> 
> > 
> > > >   rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptypes[],
> > > >                              size_t max_entries)
> > > >
> > > >
> > > >
> > > > Another point, I have read the example patch (l3fwd) but I don't
> > > > understand why the PMD is not responsible for filling the packet type in
> > > > the MBUF (packet parsing is done by parse_packet_type()).  Why the extra
> > > > computation?
> > >
> > > As I understand there are 3 possibilities now:
> > > 1. HW supports ptype recognition and SW ptype parsing is never done
> > > (--parse-ptype is not specified).
> > > 2. HW supports ptype recognition, but and SW ptype parsing is done anyway
> > > (--parse-ptype is specified).
> > > 3. HW doesn't support and ptype recognition, and and SW ptype parsing is done
> > > (--parse-ptype is specified).
> > >
> > > I suppose the question is what for introduce '--parse-ptype' at all?
> > > My thought because of #2, so people can easily check what will be the performance impact of SW parsing.
> > >
> > > Konstantin
> > >
> > > >
> > > > I see it more like an offload request (as checksum, etc...) and if the
> > > > NIC does not support it then the application does the necessary overload.
> > > >
> > > > Best regards,
> > > >
> > > > --
> > > > Nélio Laranjeiro
> > > > 6WIND
> > 
> > --
> > Adrien Mazarguil
> > 6WIND

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-06 15:44               ` Adrien Mazarguil
@ 2016-01-06 16:44                 ` Ananyev, Konstantin
  2016-01-06 17:22                   ` Adrien Mazarguil
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-06 16:44 UTC (permalink / raw)
  To: Adrien Mazarguil; +Cc: dev



> -----Original Message-----
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> Sent: Wednesday, January 06, 2016 3:45 PM
> To: Ananyev, Konstantin
> Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> 
> On Wed, Jan 06, 2016 at 02:29:07PM +0000, Ananyev, Konstantin wrote:
> >
> >
> > > -----Original Message-----
> > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > Sent: Wednesday, January 06, 2016 10:01 AM
> > > To: Ananyev, Konstantin
> > > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > >
> > > On Tue, Jan 05, 2016 at 04:50:31PM +0000, Ananyev, Konstantin wrote:
> > > [...]
> > > > > -----Original Message-----
> > > > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > > [...]
> > > > > I think we miss a comment here in how those 2/6/4 values are chosen
> > > > > because, according to the mask, I expect 16 possibilities but I get
> > > > > less.  It will help a lot anyone who needs to add a new type.
> > > > >
> > > > > Extending the snprintf behavior above, it is best to remove the mask
> > > > > argument altogether and have rte_eth_dev_get_ptype_info() return the
> > > > > entire list every time.  Applications need to iterate on the result in
> > > > > any case.
> > > >
> > > > I think we'd better keep mask argument.
> > > > In many cases upper layer only interested in some particular  subset of
> > > > all packet types that HW can recognise.
> > > > Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
> > > > tunnelling packet types, etc.
> > > > If caller needs to know all recognised ptypes, he can set mask==-1,
> > > > In that case all supported packet types will be returned.
> > >
> > > There are other drawbacks to the mask argument in my opinion. The API will
> > > have to be updated again as soon as 32 bits aren't enough to represent all
> > > possible masks. We can't predict it will be large enough forever but on the
> > > other hand, using uint64_t seems overkill at this point.
> >
> > Inside rte_mbuf packet_type itself is a 32 bit value.
> > These 32 bits are divided into several fields to mark packet types,
> > i.e: bits [0-3] are for all possible L2 types, bits [4-7] for L3 types, etc.
> > As long as packet_type itself is 32bits, 32bit mask is sufficient.
> > If we'll ever run out of 32 bits in packet_type itself, it will be ABI change anyway.
> 
> Sure, however why not do it now this issue has been raised so this function
> doesn't need updating the day it breaks? I know there's a million other
> places with a similar problem but I'm all for making new code future proof.

If rte_mbuf packet_type will have to be increased to 64bit long, then
this function will have to change anyway (with or without mask parameter).
It will have to become:

rte_eth_dev_get_ptype_info(uint8_t portid, uint64_t ptypes[], ...)

So I think we don't have to worry about mask parameter itself.

> 
> Perhaps in this particular case there is no way to hit the limit (although
> there are only four unused bits left to extend RTE_PTYPE masks) but we've
> seen this happen too many times with subsequent ABI breakage.

When ptype was introduced we tried to reserve some free space for each layer (L2/L3/L4/...),
so it wouldn't be overrun immediately.
But of course if there would be a new HW that can recognise dozen new packet types - it is possible.
Do you have any particular use-case in mind? 

> 
> > > I think this use for masks should be avoided when performance does not
> > > matter much, as in this case, user application cannot know the number of
> > > entries in advance and must rely on the returned value to iterate.
> >
> > User doesn't know numbers of entries in advance anyway (with and without the mask).
> > That's why this function was introduced at first place.
> >
> > With mask it just a bit more handy, in case user cares only about particular subset of supported
> > packet types (only L2 let say).
> 
> OK, so we definitely need something to let applications know the layer a
> given packet type belongs to, I'm sure it can be done in a convenient way
> that won't be limited to the underlying type of the mask.
> 
> > > A helper function can be added to convert a RTE_PTYPE_* value to the layer
> > > it belongs to (using enum to define possible values).
> >
> > Not sure what for?
> 
> This is assuming rte_eth_dev_get_ptype_info() doesn't filter anything (no
> "mask" argument). In that case a separate function must be added to convert
> RTE_PTYPE_* values to a layer, so applications can look for interesting
> packet types while parsing plist[] on their own.

Honestly, I don't see why do you need that.
You already do know that  let say RTE_PTYPE_L3_IPV4 belongs to L3.
Why do you need some extra enum here?
From my thought - the only purpose of mask parameter was to limit number of elements in the ptypes[] at return.
So let say user would need to iterate over 10 elements, instead of 100 to find
the ones he is interested in.

> 
> This layer information could be defined as an enum, i.e.:
> 
>  enum rte_ptype_info {
>      RTE_PTYPE_UNKNOWN,
>      RTE_PTYPE_L2,
>      RTE_PTYPE_L3,
>     ...
>  };
> 
> Or even an int value (2 standing for for "layer 2" etc. Tunnel encapsulation
> wouldn't be described easily that way though). It's just an idea.
> 
> > > If we absolutely want a mean to filter returned values, I suggest we use
> > > this enum instead of the mask argument.
> > > Since it won't be a mask, it won't
> > > have to be updated every time a new protocol requires extending one.
> >
> > Number of bits PTYPE_L2/L3/L4,... layers are already defined.
> > So let say RTE_PTYPE_L2_MASK shouldn't change if you'll add new L2 ptype -
> > there are few reserved values right now.
> > if one day we'll run out bits in let say RTE_PTYPE_L2_MASK  and will have to increase its size -
> > it would mean change of the packet_type layout and possible ABI breakage anyway.
> 
> I'm aware of this, only pointing out we tend to rely on masks and type
> boundaries a bit too much when there are other methods that are as (if not
> more) convenient.

Yes, we do rely on masks in ptype.
That's how ptype was defined.
Let say to check that incoming packet is Ether/IPv4(no extentions)/UDP,
you probably would do:

if (mbuf->packet_type & (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK) ==
(RTE_PTYPE_L2_ETHER  | RTE_PTYPE_L3_IPV4 |  RTE_PTYPE_L4_UDP)) {...}

> 
> Perhaps some sort of tunneled packet types beyond inner L4 consuming the
> four remaining bits will be added? That could happen soon.

As I said above: do you have particular scenario in mind when 32bits for packet_type
might be not enough?
If yes, then it is probably a good idea to submit an RFC for extending it to 64 bit,
or introduce packet_type2, or whatever would be your preferred way to deal with it.

Konstantin


^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-06 16:44                 ` Ananyev, Konstantin
@ 2016-01-06 17:22                   ` Adrien Mazarguil
  2016-01-07 10:24                     ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-06 17:22 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On Wed, Jan 06, 2016 at 04:44:43PM +0000, Ananyev, Konstantin wrote:
> 
> 
> > -----Original Message-----
> > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > Sent: Wednesday, January 06, 2016 3:45 PM
> > To: Ananyev, Konstantin
> > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > 
> > On Wed, Jan 06, 2016 at 02:29:07PM +0000, Ananyev, Konstantin wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > > Sent: Wednesday, January 06, 2016 10:01 AM
> > > > To: Ananyev, Konstantin
> > > > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > > > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > > >
> > > > On Tue, Jan 05, 2016 at 04:50:31PM +0000, Ananyev, Konstantin wrote:
> > > > [...]
> > > > > > -----Original Message-----
> > > > > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > > > [...]
> > > > > > I think we miss a comment here in how those 2/6/4 values are chosen
> > > > > > because, according to the mask, I expect 16 possibilities but I get
> > > > > > less.  It will help a lot anyone who needs to add a new type.
> > > > > >
> > > > > > Extending the snprintf behavior above, it is best to remove the mask
> > > > > > argument altogether and have rte_eth_dev_get_ptype_info() return the
> > > > > > entire list every time.  Applications need to iterate on the result in
> > > > > > any case.
> > > > >
> > > > > I think we'd better keep mask argument.
> > > > > In many cases upper layer only interested in some particular  subset of
> > > > > all packet types that HW can recognise.
> > > > > Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
> > > > > tunnelling packet types, etc.
> > > > > If caller needs to know all recognised ptypes, he can set mask==-1,
> > > > > In that case all supported packet types will be returned.
> > > >
> > > > There are other drawbacks to the mask argument in my opinion. The API will
> > > > have to be updated again as soon as 32 bits aren't enough to represent all
> > > > possible masks. We can't predict it will be large enough forever but on the
> > > > other hand, using uint64_t seems overkill at this point.
> > >
> > > Inside rte_mbuf packet_type itself is a 32 bit value.
> > > These 32 bits are divided into several fields to mark packet types,
> > > i.e: bits [0-3] are for all possible L2 types, bits [4-7] for L3 types, etc.
> > > As long as packet_type itself is 32bits, 32bit mask is sufficient.
> > > If we'll ever run out of 32 bits in packet_type itself, it will be ABI change anyway.
> > 
> > Sure, however why not do it now this issue has been raised so this function
> > doesn't need updating the day it breaks? I know there's a million other
> > places with a similar problem but I'm all for making new code future proof.
> 
> If rte_mbuf packet_type will have to be increased to 64bit long, then
> this function will have to change anyway (with or without mask parameter).
> It will have to become:
> 
> rte_eth_dev_get_ptype_info(uint8_t portid, uint64_t ptypes[], ...)
> 
> So I think we don't have to worry about mask parameter itself.

Well, yes, besides I overlooked ptypes[] itself is 32 bit, working around
the type width of the mask wouldn't help much.

> > Perhaps in this particular case there is no way to hit the limit (although
> > there are only four unused bits left to extend RTE_PTYPE masks) but we've
> > seen this happen too many times with subsequent ABI breakage.
> 
> When ptype was introduced we tried to reserve some free space for each layer (L2/L3/L4/...),
> so it wouldn't be overrun immediately.
> But of course if there would be a new HW that can recognise dozen new packet types - it is possible.
> Do you have any particular use-case in mind? 

No, that was just to illustrate my point.

> > > > I think this use for masks should be avoided when performance does not
> > > > matter much, as in this case, user application cannot know the number of
> > > > entries in advance and must rely on the returned value to iterate.
> > >
> > > User doesn't know numbers of entries in advance anyway (with and without the mask).
> > > That's why this function was introduced at first place.
> > >
> > > With mask it just a bit more handy, in case user cares only about particular subset of supported
> > > packet types (only L2 let say).
> > 
> > OK, so we definitely need something to let applications know the layer a
> > given packet type belongs to, I'm sure it can be done in a convenient way
> > that won't be limited to the underlying type of the mask.
> > 
> > > > A helper function can be added to convert a RTE_PTYPE_* value to the layer
> > > > it belongs to (using enum to define possible values).
> > >
> > > Not sure what for?
> > 
> > This is assuming rte_eth_dev_get_ptype_info() doesn't filter anything (no
> > "mask" argument). In that case a separate function must be added to convert
> > RTE_PTYPE_* values to a layer, so applications can look for interesting
> > packet types while parsing plist[] on their own.
> 
> Honestly, I don't see why do you need that.
> You already do know that  let say RTE_PTYPE_L3_IPV4 belongs to L3.
> Why do you need some extra enum here?
> From my thought - the only purpose of mask parameter was to limit number of elements in the ptypes[] at return.
> So let say user would need to iterate over 10 elements, instead of 100 to find
> the ones he is interested in.

Since this is already a slow manner for retrieving types, 10 or 100 doesn't
make much difference. Such a function shouldn't be used in the data path
directly.

My point is, since we're dealing with a slow function, let's keep its API as
simple as possible. By having a mask to match, a large number of checks are
added in all PMDs while they could just fill the array without
bothering. The filtering logic is an application requirement that could be
useful in its own function as well (converting any random value to its
related layer or mask).

> > This layer information could be defined as an enum, i.e.:
> > 
> >  enum rte_ptype_info {
> >      RTE_PTYPE_UNKNOWN,
> >      RTE_PTYPE_L2,
> >      RTE_PTYPE_L3,
> >     ...
> >  };
> > 
> > Or even an int value (2 standing for for "layer 2" etc. Tunnel encapsulation
> > wouldn't be described easily that way though). It's just an idea.
> > 
> > > > If we absolutely want a mean to filter returned values, I suggest we use
> > > > this enum instead of the mask argument.
> > > > Since it won't be a mask, it won't
> > > > have to be updated every time a new protocol requires extending one.
> > >
> > > Number of bits PTYPE_L2/L3/L4,... layers are already defined.
> > > So let say RTE_PTYPE_L2_MASK shouldn't change if you'll add new L2 ptype -
> > > there are few reserved values right now.
> > > if one day we'll run out bits in let say RTE_PTYPE_L2_MASK  and will have to increase its size -
> > > it would mean change of the packet_type layout and possible ABI breakage anyway.
> > 
> > I'm aware of this, only pointing out we tend to rely on masks and type
> > boundaries a bit too much when there are other methods that are as (if not
> > more) convenient.
> 
> Yes, we do rely on masks in ptype.
> That's how ptype was defined.
> Let say to check that incoming packet is Ether/IPv4(no extentions)/UDP,
> you probably would do:
> 
> if (mbuf->packet_type & (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK) ==
> (RTE_PTYPE_L2_ETHER  | RTE_PTYPE_L3_IPV4 |  RTE_PTYPE_L4_UDP)) {...}

All right, let's not use a different method to filter packet types.

> > Perhaps some sort of tunneled packet types beyond inner L4 consuming the
> > four remaining bits will be added? That could happen soon.
> 
> As I said above: do you have particular scenario in mind when 32bits for packet_type
> might be not enough?
> If yes, then it is probably a good idea to submit an RFC for extending it to 64 bit,
> or introduce packet_type2, or whatever would be your preferred way to deal with it.

No, really, I guess we'll extend ptype to 64 bit when necessary. My point on
filtering separately still stands.

> Konstantin
> 

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 12/12] examples/l3fwd: add option to parse ptype
  2016-01-05 16:49       ` Ananyev, Konstantin
@ 2016-01-07  1:20         ` Tan, Jianfeng
  2016-01-07  9:44           ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-01-07  1:20 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev


Hi Konstantin,

On 1/6/2016 12:49 AM, Ananyev, Konstantin wrote:
> Hi Jianfeng,
>
>>>> +static int
>>>> +check_packet_type_ok(int portid)
>>>> +{
>>>> +	int i;
>>>> +	int ret;
>>>> +	uint32_t ptypes[RTE_PTYPE_L3_MAX_NUM];
>>>> +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
>>>> +
>>>> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
>>> ptypes);
>>>> +	for (i = 0; i < ret; ++i) {
>>>> +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
>>>> +			ptype_l3_ipv4 = 1;
>>>> +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
>>>> +			ptype_l3_ipv6 = 1;
>>>> +	}
>>>> +
>>>> +	if (ptype_l3_ipv4 == 0)
>>>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
>>>> +
>>>> +	if (ptype_l3_ipv6 == 0)
>>>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
>>>> +
>>>> +	if (ptype_l3_ipv4 || ptype_l3_ipv6)
>>>> +		return 1;
>
> Forgot one thing: I think it should be:
>
> if (ptype_l3_ipv4 && ptype_l3_ipv6)
>    return 1;
> return 0;
>
> or just:
>
> return ptype_l3_ipv4 && ptype_l3_ipv6;

My original thought is: PMDs, like vmxnet3, fills ptype_l3_ipv4, but not 
ptype_l3_ipv6.
If we use "&&", then it would add rx callback to parse ptype whether 
ipv4 or ipv6 traffic is comming.

Thanks,
Jianfeng

>
> Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 12/12] examples/l3fwd: add option to parse ptype
  2016-01-07  1:20         ` Tan, Jianfeng
@ 2016-01-07  9:44           ` Ananyev, Konstantin
  0 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-07  9:44 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Thursday, January 07, 2016 1:20 AM
> To: Ananyev, Konstantin; dev@dpdk.org
> Cc: Zhang, Helin
> Subject: Re: [PATCH 12/12] examples/l3fwd: add option to parse ptype
> 
> 
> Hi Konstantin,
> 
> On 1/6/2016 12:49 AM, Ananyev, Konstantin wrote:
> > Hi Jianfeng,
> >
> >>>> +static int
> >>>> +check_packet_type_ok(int portid)
> >>>> +{
> >>>> +	int i;
> >>>> +	int ret;
> >>>> +	uint32_t ptypes[RTE_PTYPE_L3_MAX_NUM];
> >>>> +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> >>>> +
> >>>> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
> >>> ptypes);
> >>>> +	for (i = 0; i < ret; ++i) {
> >>>> +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> >>>> +			ptype_l3_ipv4 = 1;
> >>>> +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> >>>> +			ptype_l3_ipv6 = 1;
> >>>> +	}
> >>>> +
> >>>> +	if (ptype_l3_ipv4 == 0)
> >>>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> >>>> +
> >>>> +	if (ptype_l3_ipv6 == 0)
> >>>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> >>>> +
> >>>> +	if (ptype_l3_ipv4 || ptype_l3_ipv6)
> >>>> +		return 1;
> >
> > Forgot one thing: I think it should be:
> >
> > if (ptype_l3_ipv4 && ptype_l3_ipv6)
> >    return 1;
> > return 0;
> >
> > or just:
> >
> > return ptype_l3_ipv4 && ptype_l3_ipv6;
> 
> My original thought is: PMDs, like vmxnet3, fills ptype_l3_ipv4, but not
> ptype_l3_ipv6.
> If we use "&&", then it would add rx callback to parse ptype whether
> ipv4 or ipv6 traffic is comming.

Yes, I think that's how it should be:
If HW can't recognise either IPV4 or IPV6 packets, then SW parsing needs to be done.
l3fwd relies on PMD to recognise both IPV4 and IPV6 packets properly.
If it can recognise only IPV4, then IPV6 traffic will not be forwarded correctly,
and visa-versa.  
Konstantin

> 
> Thanks,
> Jianfeng
> 
> >
> > Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-06 17:22                   ` Adrien Mazarguil
@ 2016-01-07 10:24                     ` Ananyev, Konstantin
  2016-01-07 13:32                       ` Adrien Mazarguil
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-07 10:24 UTC (permalink / raw)
  To: Adrien Mazarguil; +Cc: dev



> -----Original Message-----
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> Sent: Wednesday, January 06, 2016 5:23 PM
> To: Ananyev, Konstantin
> Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> 
> On Wed, Jan 06, 2016 at 04:44:43PM +0000, Ananyev, Konstantin wrote:
> >
> >
> > > -----Original Message-----
> > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > Sent: Wednesday, January 06, 2016 3:45 PM
> > > To: Ananyev, Konstantin
> > > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > >
> > > On Wed, Jan 06, 2016 at 02:29:07PM +0000, Ananyev, Konstantin wrote:
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > > > Sent: Wednesday, January 06, 2016 10:01 AM
> > > > > To: Ananyev, Konstantin
> > > > > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > > > > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > > > >
> > > > > On Tue, Jan 05, 2016 at 04:50:31PM +0000, Ananyev, Konstantin wrote:
> > > > > [...]
> > > > > > > -----Original Message-----
> > > > > > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > > > > [...]
> > > > > > > I think we miss a comment here in how those 2/6/4 values are chosen
> > > > > > > because, according to the mask, I expect 16 possibilities but I get
> > > > > > > less.  It will help a lot anyone who needs to add a new type.
> > > > > > >
> > > > > > > Extending the snprintf behavior above, it is best to remove the mask
> > > > > > > argument altogether and have rte_eth_dev_get_ptype_info() return the
> > > > > > > entire list every time.  Applications need to iterate on the result in
> > > > > > > any case.
> > > > > >
> > > > > > I think we'd better keep mask argument.
> > > > > > In many cases upper layer only interested in some particular  subset of
> > > > > > all packet types that HW can recognise.
> > > > > > Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
> > > > > > tunnelling packet types, etc.
> > > > > > If caller needs to know all recognised ptypes, he can set mask==-1,
> > > > > > In that case all supported packet types will be returned.
> > > > >
> > > > > There are other drawbacks to the mask argument in my opinion. The API will
> > > > > have to be updated again as soon as 32 bits aren't enough to represent all
> > > > > possible masks. We can't predict it will be large enough forever but on the
> > > > > other hand, using uint64_t seems overkill at this point.
> > > >
> > > > Inside rte_mbuf packet_type itself is a 32 bit value.
> > > > These 32 bits are divided into several fields to mark packet types,
> > > > i.e: bits [0-3] are for all possible L2 types, bits [4-7] for L3 types, etc.
> > > > As long as packet_type itself is 32bits, 32bit mask is sufficient.
> > > > If we'll ever run out of 32 bits in packet_type itself, it will be ABI change anyway.
> > >
> > > Sure, however why not do it now this issue has been raised so this function
> > > doesn't need updating the day it breaks? I know there's a million other
> > > places with a similar problem but I'm all for making new code future proof.
> >
> > If rte_mbuf packet_type will have to be increased to 64bit long, then
> > this function will have to change anyway (with or without mask parameter).
> > It will have to become:
> >
> > rte_eth_dev_get_ptype_info(uint8_t portid, uint64_t ptypes[], ...)
> >
> > So I think we don't have to worry about mask parameter itself.
> 
> Well, yes, besides I overlooked ptypes[] itself is 32 bit, working around
> the type width of the mask wouldn't help much.
> 
> > > Perhaps in this particular case there is no way to hit the limit (although
> > > there are only four unused bits left to extend RTE_PTYPE masks) but we've
> > > seen this happen too many times with subsequent ABI breakage.
> >
> > When ptype was introduced we tried to reserve some free space for each layer (L2/L3/L4/...),
> > so it wouldn't be overrun immediately.
> > But of course if there would be a new HW that can recognise dozen new packet types - it is possible.
> > Do you have any particular use-case in mind?
> 
> No, that was just to illustrate my point.
> 
> > > > > I think this use for masks should be avoided when performance does not
> > > > > matter much, as in this case, user application cannot know the number of
> > > > > entries in advance and must rely on the returned value to iterate.
> > > >
> > > > User doesn't know numbers of entries in advance anyway (with and without the mask).
> > > > That's why this function was introduced at first place.
> > > >
> > > > With mask it just a bit more handy, in case user cares only about particular subset of supported
> > > > packet types (only L2 let say).
> > >
> > > OK, so we definitely need something to let applications know the layer a
> > > given packet type belongs to, I'm sure it can be done in a convenient way
> > > that won't be limited to the underlying type of the mask.
> > >
> > > > > A helper function can be added to convert a RTE_PTYPE_* value to the layer
> > > > > it belongs to (using enum to define possible values).
> > > >
> > > > Not sure what for?
> > >
> > > This is assuming rte_eth_dev_get_ptype_info() doesn't filter anything (no
> > > "mask" argument). In that case a separate function must be added to convert
> > > RTE_PTYPE_* values to a layer, so applications can look for interesting
> > > packet types while parsing plist[] on their own.
> >
> > Honestly, I don't see why do you need that.
> > You already do know that  let say RTE_PTYPE_L3_IPV4 belongs to L3.
> > Why do you need some extra enum here?
> > From my thought - the only purpose of mask parameter was to limit number of elements in the ptypes[] at return.
> > So let say user would need to iterate over 10 elements, instead of 100 to find
> > the ones he is interested in.
> 
> Since this is already a slow manner for retrieving types, 10 or 100 doesn't
> make much difference. Such a function shouldn't be used in the data path
> directly.
 
Yes, it is not supposed to be called from data-path.

> My point is, since we're dealing with a slow function, let's keep its API as
> simple as possible. 

Well, API should be simple, but from other side it has to be flexible and convenient
for the user.
As I user, I would prefer to have an ability to select the layers here - that's
why I suggested to add the mask parameter. 

>By having a mask to match, a large number of checks are
> added in all PMDs while they could just fill the array without
> bothering. 

That's a valid point.
We could move filter point into rte_ethdev layer.
So PMD would always return an array of all supported ptypes, and
then rte_ethdev layer will filter it based on mask parameter.
Does it sound reasonable to you?

Konstantin 

>The filtering logic is an application requirement that could be
> useful in its own function as well (converting any random value to its
> related layer or mask).
> 
> > > This layer information could be defined as an enum, i.e.:
> > >
> > >  enum rte_ptype_info {
> > >      RTE_PTYPE_UNKNOWN,
> > >      RTE_PTYPE_L2,
> > >      RTE_PTYPE_L3,
> > >     ...
> > >  };
> > >
> > > Or even an int value (2 standing for for "layer 2" etc. Tunnel encapsulation
> > > wouldn't be described easily that way though). It's just an idea.
> > >
> > > > > If we absolutely want a mean to filter returned values, I suggest we use
> > > > > this enum instead of the mask argument.
> > > > > Since it won't be a mask, it won't
> > > > > have to be updated every time a new protocol requires extending one.
> > > >
> > > > Number of bits PTYPE_L2/L3/L4,... layers are already defined.
> > > > So let say RTE_PTYPE_L2_MASK shouldn't change if you'll add new L2 ptype -
> > > > there are few reserved values right now.
> > > > if one day we'll run out bits in let say RTE_PTYPE_L2_MASK  and will have to increase its size -
> > > > it would mean change of the packet_type layout and possible ABI breakage anyway.
> > >
> > > I'm aware of this, only pointing out we tend to rely on masks and type
> > > boundaries a bit too much when there are other methods that are as (if not
> > > more) convenient.
> >
> > Yes, we do rely on masks in ptype.
> > That's how ptype was defined.
> > Let say to check that incoming packet is Ether/IPv4(no extentions)/UDP,
> > you probably would do:
> >
> > if (mbuf->packet_type & (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK) ==
> > (RTE_PTYPE_L2_ETHER  | RTE_PTYPE_L3_IPV4 |  RTE_PTYPE_L4_UDP)) {...}
> 
> All right, let's not use a different method to filter packet types.
> 
> > > Perhaps some sort of tunneled packet types beyond inner L4 consuming the
> > > four remaining bits will be added? That could happen soon.
> >
> > As I said above: do you have particular scenario in mind when 32bits for packet_type
> > might be not enough?
> > If yes, then it is probably a good idea to submit an RFC for extending it to 64 bit,
> > or introduce packet_type2, or whatever would be your preferred way to deal with it.
> 
> No, really, I guess we'll extend ptype to 64 bit when necessary. My point on
> filtering separately still stands.
> 
> > Konstantin
> >
> 
> --
> Adrien Mazarguil
> 6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-07 10:24                     ` Ananyev, Konstantin
@ 2016-01-07 13:32                       ` Adrien Mazarguil
  2016-01-11  7:39                         ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-07 13:32 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On Thu, Jan 07, 2016 at 10:24:19AM +0000, Ananyev, Konstantin wrote:
> 
> 
> > -----Original Message-----
> > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > Sent: Wednesday, January 06, 2016 5:23 PM
> > To: Ananyev, Konstantin
> > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > 
> > On Wed, Jan 06, 2016 at 04:44:43PM +0000, Ananyev, Konstantin wrote:
> > >
> > >
> > > > -----Original Message-----
> > > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > > Sent: Wednesday, January 06, 2016 3:45 PM
> > > > To: Ananyev, Konstantin
> > > > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > > > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > > >
> > > > On Wed, Jan 06, 2016 at 02:29:07PM +0000, Ananyev, Konstantin wrote:
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > > > > Sent: Wednesday, January 06, 2016 10:01 AM
> > > > > > To: Ananyev, Konstantin
> > > > > > Cc: Nélio Laranjeiro; Tan, Jianfeng; dev@dpdk.org
> > > > > > Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> > > > > >
> > > > > > On Tue, Jan 05, 2016 at 04:50:31PM +0000, Ananyev, Konstantin wrote:
> > > > > > [...]
> > > > > > > > -----Original Message-----
> > > > > > > > From: Nélio Laranjeiro [mailto:nelio.laranjeiro@6wind.com]
> > > > > > [...]
> > > > > > > > I think we miss a comment here in how those 2/6/4 values are chosen
> > > > > > > > because, according to the mask, I expect 16 possibilities but I get
> > > > > > > > less.  It will help a lot anyone who needs to add a new type.
> > > > > > > >
> > > > > > > > Extending the snprintf behavior above, it is best to remove the mask
> > > > > > > > argument altogether and have rte_eth_dev_get_ptype_info() return the
> > > > > > > > entire list every time.  Applications need to iterate on the result in
> > > > > > > > any case.
> > > > > > >
> > > > > > > I think we'd better keep mask argument.
> > > > > > > In many cases upper layer only interested in some particular  subset of
> > > > > > > all packet types that HW can recognise.
> > > > > > > Let say l3fwd only cares about  RTE_PTYPE_L3_MASK, it is not interested in L4,
> > > > > > > tunnelling packet types, etc.
> > > > > > > If caller needs to know all recognised ptypes, he can set mask==-1,
> > > > > > > In that case all supported packet types will be returned.
> > > > > >
> > > > > > There are other drawbacks to the mask argument in my opinion. The API will
> > > > > > have to be updated again as soon as 32 bits aren't enough to represent all
> > > > > > possible masks. We can't predict it will be large enough forever but on the
> > > > > > other hand, using uint64_t seems overkill at this point.
> > > > >
> > > > > Inside rte_mbuf packet_type itself is a 32 bit value.
> > > > > These 32 bits are divided into several fields to mark packet types,
> > > > > i.e: bits [0-3] are for all possible L2 types, bits [4-7] for L3 types, etc.
> > > > > As long as packet_type itself is 32bits, 32bit mask is sufficient.
> > > > > If we'll ever run out of 32 bits in packet_type itself, it will be ABI change anyway.
> > > >
> > > > Sure, however why not do it now this issue has been raised so this function
> > > > doesn't need updating the day it breaks? I know there's a million other
> > > > places with a similar problem but I'm all for making new code future proof.
> > >
> > > If rte_mbuf packet_type will have to be increased to 64bit long, then
> > > this function will have to change anyway (with or without mask parameter).
> > > It will have to become:
> > >
> > > rte_eth_dev_get_ptype_info(uint8_t portid, uint64_t ptypes[], ...)
> > >
> > > So I think we don't have to worry about mask parameter itself.
> > 
> > Well, yes, besides I overlooked ptypes[] itself is 32 bit, working around
> > the type width of the mask wouldn't help much.
> > 
> > > > Perhaps in this particular case there is no way to hit the limit (although
> > > > there are only four unused bits left to extend RTE_PTYPE masks) but we've
> > > > seen this happen too many times with subsequent ABI breakage.
> > >
> > > When ptype was introduced we tried to reserve some free space for each layer (L2/L3/L4/...),
> > > so it wouldn't be overrun immediately.
> > > But of course if there would be a new HW that can recognise dozen new packet types - it is possible.
> > > Do you have any particular use-case in mind?
> > 
> > No, that was just to illustrate my point.
> > 
> > > > > > I think this use for masks should be avoided when performance does not
> > > > > > matter much, as in this case, user application cannot know the number of
> > > > > > entries in advance and must rely on the returned value to iterate.
> > > > >
> > > > > User doesn't know numbers of entries in advance anyway (with and without the mask).
> > > > > That's why this function was introduced at first place.
> > > > >
> > > > > With mask it just a bit more handy, in case user cares only about particular subset of supported
> > > > > packet types (only L2 let say).
> > > >
> > > > OK, so we definitely need something to let applications know the layer a
> > > > given packet type belongs to, I'm sure it can be done in a convenient way
> > > > that won't be limited to the underlying type of the mask.
> > > >
> > > > > > A helper function can be added to convert a RTE_PTYPE_* value to the layer
> > > > > > it belongs to (using enum to define possible values).
> > > > >
> > > > > Not sure what for?
> > > >
> > > > This is assuming rte_eth_dev_get_ptype_info() doesn't filter anything (no
> > > > "mask" argument). In that case a separate function must be added to convert
> > > > RTE_PTYPE_* values to a layer, so applications can look for interesting
> > > > packet types while parsing plist[] on their own.
> > >
> > > Honestly, I don't see why do you need that.
> > > You already do know that  let say RTE_PTYPE_L3_IPV4 belongs to L3.
> > > Why do you need some extra enum here?
> > > From my thought - the only purpose of mask parameter was to limit number of elements in the ptypes[] at return.
> > > So let say user would need to iterate over 10 elements, instead of 100 to find
> > > the ones he is interested in.
> > 
> > Since this is already a slow manner for retrieving types, 10 or 100 doesn't
> > make much difference. Such a function shouldn't be used in the data path
> > directly.
>  
> Yes, it is not supposed to be called from data-path.
> 
> > My point is, since we're dealing with a slow function, let's keep its API as
> > simple as possible. 
> 
> Well, API should be simple, but from other side it has to be flexible and convenient
> for the user.
> As I user, I would prefer to have an ability to select the layers here - that's
> why I suggested to add the mask parameter. 
> 
> >By having a mask to match, a large number of checks are
> > added in all PMDs while they could just fill the array without
> > bothering. 
> 
> That's a valid point.
> We could move filter point into rte_ethdev layer.
> So PMD would always return an array of all supported ptypes, and
> then rte_ethdev layer will filter it based on mask parameter.
> Does it sound reasonable to you?

Yes, I think it's fine that way, thanks.

> >The filtering logic is an application requirement that could be
> > useful in its own function as well (converting any random value to its
> > related layer or mask).
> > 
> > > > This layer information could be defined as an enum, i.e.:
> > > >
> > > >  enum rte_ptype_info {
> > > >      RTE_PTYPE_UNKNOWN,
> > > >      RTE_PTYPE_L2,
> > > >      RTE_PTYPE_L3,
> > > >     ...
> > > >  };
> > > >
> > > > Or even an int value (2 standing for for "layer 2" etc. Tunnel encapsulation
> > > > wouldn't be described easily that way though). It's just an idea.
> > > >
> > > > > > If we absolutely want a mean to filter returned values, I suggest we use
> > > > > > this enum instead of the mask argument.
> > > > > > Since it won't be a mask, it won't
> > > > > > have to be updated every time a new protocol requires extending one.
> > > > >
> > > > > Number of bits PTYPE_L2/L3/L4,... layers are already defined.
> > > > > So let say RTE_PTYPE_L2_MASK shouldn't change if you'll add new L2 ptype -
> > > > > there are few reserved values right now.
> > > > > if one day we'll run out bits in let say RTE_PTYPE_L2_MASK  and will have to increase its size -
> > > > > it would mean change of the packet_type layout and possible ABI breakage anyway.
> > > >
> > > > I'm aware of this, only pointing out we tend to rely on masks and type
> > > > boundaries a bit too much when there are other methods that are as (if not
> > > > more) convenient.
> > >
> > > Yes, we do rely on masks in ptype.
> > > That's how ptype was defined.
> > > Let say to check that incoming packet is Ether/IPv4(no extentions)/UDP,
> > > you probably would do:
> > >
> > > if (mbuf->packet_type & (RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK) ==
> > > (RTE_PTYPE_L2_ETHER  | RTE_PTYPE_L3_IPV4 |  RTE_PTYPE_L4_UDP)) {...}
> > 
> > All right, let's not use a different method to filter packet types.
> > 
> > > > Perhaps some sort of tunneled packet types beyond inner L4 consuming the
> > > > four remaining bits will be added? That could happen soon.
> > >
> > > As I said above: do you have particular scenario in mind when 32bits for packet_type
> > > might be not enough?
> > > If yes, then it is probably a good idea to submit an RFC for extending it to 64 bit,
> > > or introduce packet_type2, or whatever would be your preferred way to deal with it.
> > 
> > No, really, I guess we'll extend ptype to 64 bit when necessary. My point on
> > filtering separately still stands.
> > 
> > > Konstantin
> > >
> > 
> > --
> > Adrien Mazarguil
> > 6WIND

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2016-01-05 16:18       ` Adrien Mazarguil
@ 2016-01-11  5:07         ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-01-11  5:07 UTC (permalink / raw)
  To: dev

> OK, that makes sense. Please check my above comments about coding
> style/indents (I know I'm annoying).

Thank you, Mazarguil. I'll fix it when sending out v2 patch.

Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-07 13:32                       ` Adrien Mazarguil
@ 2016-01-11  7:39                         ` Tan, Jianfeng
  2016-01-11 10:26                           ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-01-11  7:39 UTC (permalink / raw)
  To: Ananyev, Konstantin, Nélio Laranjeiro, dev

Hi,

According to the proposal, I'm going to fix the definition of this API 
as below:
/**
  * Retrieve the contextual information of an Ethernet device.
  *
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param ptype_mask
  *   A hint of what kind of packet type which the caller is interested in
  * @param ptypes
  *   An array of packet types to be filled with
  * @param num
  * Size of ptypes[]
  * @return
  *   - (>=0) if successful. Indicate number of valid values in ptypes 
array.
  *   - (-ENOTSUP) if hardware-assisted VLAN stripping not configured.
  *   - (-ENODEV) if *port_id* invalid.
  */
extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
                                 uint32_t ptype_mask, uint32_t ptypes[], 
uint32_t num);

Unresolved issues:
1) When num is exceeded, we just stop there and return num, or return 
-ENOMEM?
The first way has a bug when: what app is exactly asking for is not 
filled in ptypes[] because of
exceeding num, but app believes this API returns with success.

2) if RTE_PTYPE_*_MAX_NUM macros necessary? Without them, we could calculate
num through 2^(number of bit 1 in RTE_PTPE_*_MASK).

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 01/12] ethdev: add API to query what/if packet type is set
  2016-01-11  7:39                         ` Tan, Jianfeng
@ 2016-01-11 10:26                           ` Ananyev, Konstantin
  0 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-11 10:26 UTC (permalink / raw)
  To: Tan, Jianfeng, Nélio Laranjeiro, dev

Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Monday, January 11, 2016 7:39 AM
> To: Ananyev, Konstantin; Nélio Laranjeiro; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 01/12] ethdev: add API to query what/if packet type is set
> 
> Hi,
> 
> According to the proposal, I'm going to fix the definition of this API
> as below:
> /**
>   * Retrieve the contextual information of an Ethernet device.
>   *
>   * @param port_id
>   *   The port identifier of the Ethernet device.
>   * @param ptype_mask
>   *   A hint of what kind of packet type which the caller is interested in
>   * @param ptypes
>   *   An array of packet types to be filled with
>   * @param num
>   * Size of ptypes[]
>   * @return
>   *   - (>=0) if successful. Indicate number of valid values in ptypes
> array.
>   *   - (-ENOTSUP) if hardware-assisted VLAN stripping not configured.
>   *   - (-ENODEV) if *port_id* invalid.
>   */
> extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
>                                  uint32_t ptype_mask, uint32_t ptypes[],
> uint32_t num);
> 
> Unresolved issues:
> 1) When num is exceeded, we just stop there and return num, or return
> -ENOMEM?

I think when num is exceeded it should return number of entries enough to
return all requested packet types.
Same as snprintf() does when it has to truncate the output buffer.

> The first way has a bug when: what app is exactly asking for is not
> filled in ptypes[] because of
> exceeding num, but app believes this API returns with success.

It is a caller responsibility to check the return value and handle it properly.
When return value  exceeds num - caller can  resize ptypes[] and call get_ptype_info() again.

> 
> 2) if RTE_PTYPE_*_MAX_NUM macros necessary? Without them, we could calculate
> num through 2^(number of bit 1 in RTE_PTPE_*_MASK).

I don't think caller has to guess somehow what number of entries in ptypes[] he need .
He can retrieve that information from get_ptype_info() itself.
Something like that for example:

num = rte_eth_dev_get_ptype_info(port, UINT32_MAX, NULL, 0);
if (num < 0) return num;
ptypes = alloca(num * sizeof(ptypes[0]);
ret = rte_eth_dev_get_ptype_info(port, UINT32_MAX, ptypes, num);
if (ret != num) return -1;
....

Konstantin

> 
> Thanks,
> Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 00/12] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (11 preceding siblings ...)
  2015-12-31  6:53 ` [PATCH 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
@ 2016-01-13  1:52 ` Qiu, Michael
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 202+ messages in thread
From: Qiu, Michael @ 2016-01-13  1:52 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

On 12/31/2015 9:53 PM, Jianfeng Tan wrote:
> HAPPRY NEW YEAR!
>
> A new ether API rte_eth_dev_get_ptype_info() is added to query what
> packet type information will be provided by current pmd driver of the
> specifed port.
>
> To achieve this, a new function pointer, dev_ptype_info_get, is added
> into struct eth_dev_ops. For those devices who do not implement it, it
> means it will not provide any ptype info.

I haven't go through all the patches, but I have a question, what's the
usercase of this API?

Thanks,
Michael
> Jianfeng Tan (12):
>   ethdev: add API to query what/if packet type is set
>   pmd/cxgbe: add dev_ptype_info_get implementation
>   pmd/e1000: add dev_ptype_info_get implementation
>   pmd/enic: add dev_ptype_info_get implementation
>   pmd/fm10k: add dev_ptype_info_get implementation
>   pmd/i40e: add dev_ptype_info_get implementation
>   pmd/ixgbe: add dev_ptype_info_get implementation
>   pmd/mlx4: add dev_ptype_info_get implementation
>   pmd/mlx5: add dev_ptype_info_get implementation
>   pmd/nfp: add dev_ptype_info_get implementation
>   pmd/vmxnet3: add dev_ptype_info_get implementation
>   examples/l3fwd: add option to parse ptype
>
>  drivers/net/cxgbe/cxgbe_ethdev.c     | 17 +++++++
>  drivers/net/e1000/igb_ethdev.c       | 48 ++++++++++++++++++++
>  drivers/net/enic/enic_ethdev.c       | 20 +++++++++
>  drivers/net/fm10k/fm10k_ethdev.c     | 60 +++++++++++++++++++++++++
>  drivers/net/fm10k/fm10k_rxtx.c       |  5 +++
>  drivers/net/fm10k/fm10k_rxtx_vec.c   |  5 +++
>  drivers/net/i40e/i40e_ethdev.c       |  1 +
>  drivers/net/i40e/i40e_ethdev_vf.c    |  1 +
>  drivers/net/i40e/i40e_rxtx.c         | 69 ++++++++++++++++++++++++++++-
>  drivers/net/i40e/i40e_rxtx.h         |  2 +
>  drivers/net/ixgbe/ixgbe_ethdev.c     | 50 +++++++++++++++++++++
>  drivers/net/ixgbe/ixgbe_ethdev.h     |  2 +
>  drivers/net/ixgbe/ixgbe_rxtx.c       |  5 ++-
>  drivers/net/mlx4/mlx4.c              | 27 +++++++++++
>  drivers/net/mlx5/mlx5.c              |  1 +
>  drivers/net/mlx5/mlx5.h              |  2 +
>  drivers/net/mlx5/mlx5_ethdev.c       | 25 +++++++++++
>  drivers/net/mlx5/mlx5_rxtx.c         |  2 +
>  drivers/net/nfp/nfp_net.c            | 18 ++++++++
>  drivers/net/vmxnet3/vmxnet3_ethdev.c | 20 +++++++++
>  examples/l3fwd/main.c                | 86 ++++++++++++++++++++++++++++++++++++
>  lib/librte_ether/rte_ethdev.c        | 12 +++++
>  lib/librte_ether/rte_ethdev.h        | 22 +++++++++
>  lib/librte_mbuf/rte_mbuf.h           | 13 ++++++
>  24 files changed, 511 insertions(+), 2 deletions(-)
>


^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v2 00/12] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (12 preceding siblings ...)
  2016-01-13  1:52 ` [PATCH 00/12] Add API to get packet type info Qiu, Michael
@ 2016-01-15  5:45 ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
                     ` (12 more replies)
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                   ` (7 subsequent siblings)
  21 siblings, 13 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

A new ether API rte_eth_dev_get_ptype_info() is added to query what
packet type information will be provided by current pmd driver of the
specifed port.

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it will not provide any ptype info.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Jianfeng Tan (12):
  ethdev: add API to query packet type filling info
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation
  examples/l3fwd: add option to parse ptype

 drivers/net/cxgbe/cxgbe_ethdev.c     | 14 ++++++
 drivers/net/e1000/igb_ethdev.c       | 30 ++++++++++++
 drivers/net/enic/enic_ethdev.c       | 17 +++++++
 drivers/net/fm10k/fm10k_ethdev.c     | 43 +++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c       |  5 ++
 drivers/net/fm10k/fm10k_rxtx_vec.c   |  5 ++
 drivers/net/i40e/i40e_ethdev.c       |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c    |  1 +
 drivers/net/i40e/i40e_rxtx.c         | 46 +++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h         |  1 +
 drivers/net/ixgbe/ixgbe_ethdev.c     | 38 +++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h     |  2 +
 drivers/net/ixgbe/ixgbe_rxtx.c       |  5 +-
 drivers/net/mlx4/mlx4.c              | 20 ++++++++
 drivers/net/mlx5/mlx5.c              |  1 +
 drivers/net/mlx5/mlx5.h              |  1 +
 drivers/net/mlx5/mlx5_ethdev.c       | 18 +++++++
 drivers/net/mlx5/mlx5_rxtx.c         |  2 +
 drivers/net/nfp/nfp_net.c            | 17 +++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 +++++++
 examples/l3fwd/main.c                | 91 ++++++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.c        | 20 ++++++++
 lib/librte_ether/rte_ethdev.h        | 27 +++++++++++
 lib/librte_mbuf/rte_mbuf.h           |  6 +++
 24 files changed, 425 insertions(+), 2 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15 13:58     ` Adrien Mazarguil
  2016-01-15 15:03     ` Ananyev, Konstantin
  2016-01-15  5:45   ` [PATCH v2 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
                     ` (11 subsequent siblings)
  12 siblings, 2 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query wether/what packet type will
be filled by given pmd rx burst function.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 20 ++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++
 lib/librte_mbuf/rte_mbuf.h    |  6 ++++++
 3 files changed, 53 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index ed971b4..cd34f46 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1614,6 +1614,26 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t ptypes[], int num)
+{
+	int ret, i, j;
+	struct rte_eth_dev *dev;
+	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
+
+	for (i = 0, j = 0; i < ret && j < num; ++i)
+		if (all_ptypes[i] & ptype_mask)
+			ptypes[j++] = all_ptypes[i];
+
+	return ret;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index bada8ad..42f8188 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
+					uint32_t ptypes[]);
+/**< @internal Get ptype info of eth_rx_burst_t. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1351,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2273,6 +2278,28 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
 				 struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the contextual information of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array of packet types to be filled with.
+ * @param num
+ *   The size of ptypes array.
+ * @return
+ *   - (>0) Number of ptypes supported. May be greater than param num and
+ *	    caller needs to check that.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
+				      uint32_t ptype_mask,
+				      uint32_t ptypes[],
+				      int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index f234ac9..d116711 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -667,6 +667,12 @@ extern "C" {
 #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
 
 /**
+  * Total number of all kinds of RTE_PTYPE_*, except from *_MASK, is 37 for now
+  * and reserve some space for new ptypes
+  */
+#define RTE_PTYPE_MAX_NUM		    64
+
+/**
  * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
  * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
  * determine if it is an IPV4 packet.
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 02/12] pmd/cxgbe: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 03/12] pmd/e1000: " Jianfeng Tan
                     ` (10 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..1699d8e 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,19 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static int cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev,
+				    uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts) {
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+	} 
+
+	return num;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +790,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_ptype_info_get	= cxgbe_dev_ptype_info_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 03/12] pmd/e1000: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 04/12] pmd/enic: " Jianfeng Tan
                     ` (9 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index d1bbcda..1eb1091 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -103,6 +103,8 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static int eth_igb_ptype_info_get(struct rte_eth_dev *dev,
+				  uint32_t ptypes[]);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -319,6 +321,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -376,6 +379,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1910,6 +1914,32 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static int
+eth_igb_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+	    dev->rx_pkt_burst == eth_igb_recv_scattered_pkts) {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+		ptypes[num++] = RTE_PTYPE_L2_ETHER;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		ptypes[num++] = RTE_PTYPE_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_L4_UDP;
+		ptypes[num++] = RTE_PTYPE_L4_SCTP;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
+	}
+
+	return num;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 04/12] pmd/enic: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 03/12] pmd/e1000: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 05/12] pmd/fm10k: " Jianfeng Tan
                     ` (8 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2a88043..9d3659d 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -54,6 +54,9 @@
 #define ENICPMD_FUNC_TRACE() (void)0
 #endif
 
+static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+				  uint16_t nb_pkts);
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -431,6 +434,19 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
+static int enicpmd_dev_ptype_info_get(struct rte_eth_dev *dev,
+				      uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == enicpmd_recv_pkts) {
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+	}
+
+	return num;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -566,6 +582,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_ptype_info_get   = enicpmd_dev_ptype_info_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 05/12] pmd/fm10k: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 04/12] pmd/enic: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 06/12] pmd/i40e: " Jianfeng Tan
                     ` (7 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 43 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  5 +++++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  5 +++++
 3 files changed, 53 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index e4aed94..e155cb5 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,48 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static int
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		/* refers to rx_desc_to_ol_flags() */
+		ptypes[num++] = RTE_PTYPE_L2_ETHER;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		ptypes[num++] = RTE_PTYPE_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_L4_UDP;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		/* refers to fm10k_desc_to_pktype_v() */
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		ptypes[num++] = RTE_PTYPE_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_L4_UDP;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_GENEVE;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_NVGRE;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_VXLAN;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_GRE;
+	}
+
+	return num;
+}
+#else
+static int
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev __rte_unused,
+			 uint32_t ptypes[] __rte_unused)
+{
+	return -ENOTSUP;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2423,6 +2465,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_ptype_info_get	= fm10k_dev_ptype_info_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index e958865..9b2d6f2 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,11 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/*
+ * @note
+ * When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 2a57eef..6fc22fc 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -109,6 +109,11 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/*
+ * @note
+ * When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 06/12] pmd/i40e: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 05/12] pmd/fm10k: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 07/12] pmd/ixgbe: " Jianfeng Tan
                     ` (6 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 46 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index bf6220d..1f5251b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -439,6 +439,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_ptype_info_get           = i40e_dev_ptype_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 14d2a50..5d924de 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -196,6 +196,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_ptype_info_get   = i40e_dev_ptype_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 39d94ec..15916e2 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -194,7 +194,11 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/*
+ * For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2094,6 +2098,46 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 }
 
 int
+i40e_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+	    dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+	    dev->rx_pkt_burst == i40e_recv_scattered_pkts) {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		ptypes[num++] = RTE_PTYPE_L2_ETHER;
+		ptypes[num++] = RTE_PTYPE_L2_ETHER_TIMESYNC;
+		ptypes[num++] = RTE_PTYPE_L2_ETHER_LLDP;
+		ptypes[num++] = RTE_PTYPE_L2_ETHER_ARP;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		ptypes[num++] = RTE_PTYPE_L4_FRAG;
+		ptypes[num++] = RTE_PTYPE_L4_ICMP;
+		ptypes[num++] = RTE_PTYPE_L4_NONFRAG;
+		ptypes[num++] = RTE_PTYPE_L4_SCTP;
+		ptypes[num++] = RTE_PTYPE_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_L4_UDP;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_GRENAT;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
+		ptypes[num++] = RTE_PTYPE_INNER_L2_ETHER;
+		ptypes[num++] = RTE_PTYPE_INNER_L2_ETHER_VLAN;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_FRAG;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_ICMP;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_NONFRAG;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_SCTP;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
+	}
+
+	return num;
+}
+
+int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
 			uint16_t nb_desc,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..5bb34a5 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,7 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+int i40e_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[]);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 06/12] pmd/i40e: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15 14:50     ` Ananyev, Konstantin
  2016-01-15  5:45   ` [PATCH v2 08/12] pmd/mlx4: " Jianfeng Tan
                     ` (5 subsequent siblings)
  12 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  5 ++++-
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 4c4c6df..b3ae7b2 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static int ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[]);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static int
+ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
+	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec) {
+		/*
+		 * for non-vec functions,
+		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+		 * for vec functions,
+		 * refers to _recv_raw_pkts_vec().
+		 */
+		ptypes[num++] = RTE_PTYPE_L2_ETHER;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
+		ptypes[num++] = RTE_PTYPE_L4_SCTP;
+		ptypes[num++] = RTE_PTYPE_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_L4_UDP;
+		ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
+	}
+
+	return num;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index d26771a..2479830 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+			   uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 52a263c..d324099 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -899,6 +899,9 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+/*
+ * @note: fix ixgbe_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1247,7 +1250,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 07/12] pmd/ixgbe: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 09/12] pmd/mlx5: " Jianfeng Tan
                     ` (4 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 207bfe2..b906a14 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2836,6 +2836,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4268,6 +4270,23 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static int
+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == mlx4_rx_burst ||
+	    dev->rx_pkt_burst == mlx4_rx_burst_sp) {
+		/* refers to rxq_cq_to_pkt_type() */
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+	}
+
+	return num;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -4989,6 +5008,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 09/12] pmd/mlx5: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 08/12] pmd/mlx4: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 10/12] pmd/nfp: " Jianfeng Tan
                     ` (3 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  1 +
 drivers/net/mlx5/mlx5_ethdev.c | 18 ++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 4 files changed, 22 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..e18b1e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -153,6 +153,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_ptype_info_get = mlx5_dev_ptype_info_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b84d31d..761ee94 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -156,6 +156,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+int mlx5_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[]);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..b4423b0 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -526,6 +526,24 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+int
+mlx5_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == mlx5_rx_burst ||
+	    dev->rx_pkt_burst == mlx5_rx_burst_sp) {
+		/* refers to rxq_cq_to_pkt_type() */
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+	}
+
+	return num;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index fa5e648..79bdf8d 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -603,6 +603,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 10/12] pmd/nfp: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 09/12] pmd/mlx5: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 11/12] pmd/vmxnet3: " Jianfeng Tan
                     ` (2 subsequent siblings)
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/nfp/nfp_net.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index bc2089f..b8da71e 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1075,6 +1075,22 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 #endif
 }
 
+static int
+nfp_net_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts) {
+		/* refers to nfp_net_set_hash() */
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV4;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
+		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
+		ptypes[num++] = RTE_PTYPE_INNER_L4_MASK;
+	}
+
+	return num;
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2294,6 +2310,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_ptype_info_get	= nfp_net_ptype_info_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 11/12] pmd/vmxnet3: add dev_ptype_info_get implementation
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 10/12] pmd/nfp: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15  5:45   ` [PATCH v2 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
  2016-02-23 17:31   ` [PATCH v2 00/12] Add API to get packet type info Bruce Richardson
  12 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..ed9cd14 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,8 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static int vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev,
+				      uint32_t ptypes[]);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -118,6 +120,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.link_update          = vmxnet3_dev_link_update,
 	.stats_get            = vmxnet3_dev_stats_get,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_ptype_info_get   = vmxnet3_dev_ptype_info_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -718,6 +721,19 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, struct rte_
 	};
 }
 
+static int
+vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
+{
+	int num = 0;
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts) {
+		ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
+		ptypes[num++] = RTE_PTYPE_L3_IPV4;
+	}
+
+	return num;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (10 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 11/12] pmd/vmxnet3: " Jianfeng Tan
@ 2016-01-15  5:45   ` Jianfeng Tan
  2016-01-15 14:47     ` Ananyev, Konstantin
  2016-02-23 17:31   ` [PATCH v2 00/12] Add API to get packet type info Bruce Richardson
  12 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-01-15  5:45 UTC (permalink / raw)
  To: dev

As a example to use ptype info, l3fwd needs firstly to use
rte_eth_dev_get_ptype_info() API to check if device and/or PMD driver will
parse and fill the needed packet type. If not, use the newly added option,
--parse-ptype, to analyze it in the callback softly.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 examples/l3fwd/main.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 5b0c2dd..3c6e1b7 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -174,6 +174,7 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
 static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by default. */
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype = 0; /**< parse packet type using rx callback */
 
 #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
 static int ipv6 = 0; /**< ipv6 is false by default. */
@@ -2022,6 +2023,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /* Parse the argument given in the command line of the application */
 static int
@@ -2038,6 +2040,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -2125,6 +2128,13 @@ parse_args(int argc, char **argv)
 				}
 			}
 #endif
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled \n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -2559,6 +2569,74 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
 	}
 }
 
+static int
+check_packet_type_ok(int portid)
+{
+	int i, ret;
+	uint32_t *ptypes;
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
+	if (ret <= 0)
+		return 0;
+	ptypes = malloc(sizeof(uint32_t) * ret);
+	rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
+					 ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+}
+static inline void
+parse_packet_type(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = 0;
+	uint16_t ethertype;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+		break;
+	case ETHER_TYPE_IPv6:
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		break;
+	default:
+		break;
+	}
+
+	m->packet_type |= packet_type;
+}
+
+static uint16_t
+cb_parse_packet_type(uint8_t port __rte_unused,
+		     uint16_t queue __rte_unused,
+		     struct rte_mbuf *pkts[],
+		     uint16_t nb_pkts,
+		     uint16_t max_pkts __rte_unused,
+		     void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_packet_type(pkts[i]);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -2672,6 +2750,11 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d, "
 					"port=%d\n", ret, portid);
 
+			if (!check_packet_type_ok(portid) && !parse_ptype)
+				rte_exit(EXIT_FAILURE,
+					 "port %d cannot parse packet type, please add --%s\n",
+					 portid, CMD_LINE_OPT_PARSE_PTYPE);
+
 			qconf = &lcore_conf[lcore_id];
 			qconf->tx_queue_id[portid] = queueid;
 			queueid++;
@@ -2705,6 +2788,14 @@ main(int argc, char **argv)
 			if (ret < 0)
 				rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
 						"port=%d\n", ret, portid);
+			if (parse_ptype &&
+			    !rte_eth_add_rx_callback(portid, queueid,
+				    		     cb_parse_packet_type,
+						     NULL))
+				rte_exit(EXIT_FAILURE,
+					 "Failed to add rx callback: port=%d\n",
+					 portid);
+			    
 		}
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-01-15  5:45   ` [PATCH v2 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-01-15 13:58     ` Adrien Mazarguil
  2016-01-15 15:11       ` Ananyev, Konstantin
  2016-01-15 15:03     ` Ananyev, Konstantin
  1 sibling, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-15 13:58 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

Hi Jianfeng, a few comments below.

On Fri, Jan 15, 2016 at 01:45:48PM +0800, Jianfeng Tan wrote:
> Add a new API rte_eth_dev_get_ptype_info to query wether/what packet type will
> be filled by given pmd rx burst function.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 20 ++++++++++++++++++++
>  lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++
>  lib/librte_mbuf/rte_mbuf.h    |  6 ++++++
>  3 files changed, 53 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index ed971b4..cd34f46 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1614,6 +1614,26 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>  	dev_info->driver_name = dev->data->drv_name;
>  }
>  
> +int
> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> +			   uint32_t ptypes[], int num)
> +{
> +	int ret, i, j;
> +	struct rte_eth_dev *dev;
> +	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +	dev = &rte_eth_devices[port_id];
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> +	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
> +
> +	for (i = 0, j = 0; i < ret && j < num; ++i)
> +		if (all_ptypes[i] & ptype_mask)
> +			ptypes[j++] = all_ptypes[i];
> +
> +	return ret;
> +}

It's a good thing that the size of ptypes[] can be provided, but I think num
should be passed to the dev_ptype_info_get() callback as well.

If you really do not want to pass the size, you have to force the array type
size onto callbacks using a pointer to the array otherwise they look unsafe
(and are actually unsafe when not called from the rte_eth_dev wrapper),
something like this:

 int (*dev_ptype_info_get)(uint8_t port_id, uint32_t (*ptypes)[RTE_PTYPE_MAX_NUM]);

In which case you might as well drop the num argument from
rte_eth_dev_get_ptype_info() to use the same syntax. That way there is no
need to allocate a ptypes array on the stack twice.

But since people usually do not like this syntax, I think passing num and
letting callbacks check for overflow themselves on the user-provided ptypes
array directly is better. They have to return the total number of packet
types supported even when num is 0 (ptypes may be NULL in that case).

I understand the result needs to be temporarily stored somewhere for
filtering and for that purpose the entire size must be known in advance,
hence my previous suggestion for rte_eth_dev_get_ptype_info() to return
the total number of ptypes and providing a separate function for filtering
a ptypes array for applications that need it:

 /* Return remaining number entries in ptypes[] after filtering it
  * according to ptype_mask. */
 int rte_eth_dev_ptypes_filter(uint32_t ptype_mask, uint32_t ptypes[], int num);

Usage would be like:

 int ptypes_num = rte_eth_dev_get_ptype_info(42, NULL, 0);

 if (ptypes_num <= 0)
     goto err;

 uint32_t ptypes[ptypes_num];

 rte_eth_dev_get_ptype_info(42, ptypes, ptypes_num);
 ptypes_num = rte_eth_dev_ptypes_filter(RTE_PTYPE_INNER_L4_MASK, ptypes, ptypes_num);

 if (ptypes_num <= 0)
    goto err;

 /* process ptypes... */

What about this?

> +
>  void
>  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
>  {
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index bada8ad..42f8188 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
>  				    struct rte_eth_dev_info *dev_info);
>  /**< @internal Get specific informations of an Ethernet device. */
>  
> +typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
> +					uint32_t ptypes[]);
> +/**< @internal Get ptype info of eth_rx_burst_t. */
> +
>  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
>  				    uint16_t queue_id);
>  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> @@ -1347,6 +1351,7 @@ struct eth_dev_ops {
>  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
>  	/**< Configure per queue stat counter mapping. */
>  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
>  	mtu_set_t                  mtu_set; /**< Set MTU. */
>  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
>  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> @@ -2273,6 +2278,28 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
>  				 struct rte_eth_dev_info *dev_info);
>  
>  /**
> + * Retrieve the contextual information of an Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param ptype_mask
> + *   A hint of what kind of packet type which the caller is interested in.
> + * @param ptypes
> + *   An array of packet types to be filled with.
> + * @param num
> + *   The size of ptypes array.
> + * @return
> + *   - (>0) Number of ptypes supported. May be greater than param num and
> + *	    caller needs to check that.
> + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> + *   - (-ENODEV) if *port_id* invalid.
> + */
> +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> +				      uint32_t ptype_mask,
> +				      uint32_t ptypes[],
> +				      int num);
> +
> +/**
>   * Retrieve the MTU of an Ethernet device.
>   *
>   * @param port_id
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index f234ac9..d116711 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -667,6 +667,12 @@ extern "C" {
>  #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
>  
>  /**
> +  * Total number of all kinds of RTE_PTYPE_*, except from *_MASK, is 37 for now
> +  * and reserve some space for new ptypes
> +  */
> +#define RTE_PTYPE_MAX_NUM		    64

This macro should not be needed if the num argument is kept. Applications
should only rely on returned values.

> +
> +/**
>   * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
>   * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
>   * determine if it is an IPV4 packet.
> -- 
> 2.1.4
> 

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
  2016-01-15  5:45   ` [PATCH v2 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
@ 2016-01-15 14:47     ` Ananyev, Konstantin
  2016-02-25 10:41       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-15 14:47 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, January 15, 2016 5:46 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> Subject: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
> 
> As a example to use ptype info, l3fwd needs firstly to use
> rte_eth_dev_get_ptype_info() API to check if device and/or PMD driver will
> parse and fill the needed packet type. If not, use the newly added option,
> --parse-ptype, to analyze it in the callback softly.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  examples/l3fwd/main.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 91 insertions(+)
> 
> diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> index 5b0c2dd..3c6e1b7 100644
> --- a/examples/l3fwd/main.c
> +++ b/examples/l3fwd/main.c
> @@ -174,6 +174,7 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
>  static uint32_t enabled_port_mask = 0;
>  static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by default. */
>  static int numa_on = 1; /**< NUMA is enabled by default. */
> +static int parse_ptype = 0; /**< parse packet type using rx callback */
> 
>  #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
>  static int ipv6 = 0; /**< ipv6 is false by default. */
> @@ -2022,6 +2023,7 @@ parse_eth_dest(const char *optarg)
>  #define CMD_LINE_OPT_IPV6 "ipv6"
>  #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
>  #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
> +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
> 
>  /* Parse the argument given in the command line of the application */
>  static int
> @@ -2038,6 +2040,7 @@ parse_args(int argc, char **argv)
>  		{CMD_LINE_OPT_IPV6, 0, 0, 0},
>  		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
>  		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
> +		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
>  		{NULL, 0, 0, 0}
>  	};
> 
> @@ -2125,6 +2128,13 @@ parse_args(int argc, char **argv)
>  				}
>  			}
>  #endif
> +			if (!strncmp(lgopts[option_index].name,
> +				     CMD_LINE_OPT_PARSE_PTYPE,
> +				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
> +				printf("soft parse-ptype is enabled \n");
> +				parse_ptype = 1;
> +			}
> +
>  			break;
> 
>  		default:
> @@ -2559,6 +2569,74 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
>  	}
>  }
> 
> +static int
> +check_packet_type_ok(int portid)
> +{
> +	int i, ret;
> +	uint32_t *ptypes;
> +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> +
> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
> +	if (ret <= 0)
> +		return 0;
> +	ptypes = malloc(sizeof(uint32_t) * ret);
> +	rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
> +					 ptypes, ret);
> +	for (i = 0; i < ret; ++i) {
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> +			ptype_l3_ipv4 = 1;
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> +			ptype_l3_ipv6 = 1;
> +	}


I think you forgot to do: free(ptypes);
Also, formally speaking malloc can fail here, so probably need to check malloc() return value,
or just allocate ptypes[] on the stack - would be easier.

> +
> +	if (ptype_l3_ipv4 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> +
> +	if (ptype_l3_ipv6 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> +
> +	if (ptype_l3_ipv4 && ptype_l3_ipv6)
> +		return 1;
> +
> +	return 0;
> +}
> +static inline void
> +parse_packet_type(struct rte_mbuf *m)
> +{
> +	struct ether_hdr *eth_hdr;
> +	uint32_t packet_type = 0;
> +	uint16_t ethertype;
> +
> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> +	switch (ethertype) {
> +	case ETHER_TYPE_IPv4:
> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> +		break;
> +	case ETHER_TYPE_IPv6:
> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> +		break;

That's enough for LPM, for EM, don't we need to be sure there are no extensions
in the IP header? 

Konstantin

> +	default:
> +		break;
> +	}
> +
> +	m->packet_type |= packet_type;
> +}
> +
> +static uint16_t
> +cb_parse_packet_type(uint8_t port __rte_unused,
> +		     uint16_t queue __rte_unused,
> +		     struct rte_mbuf *pkts[],
> +		     uint16_t nb_pkts,
> +		     uint16_t max_pkts __rte_unused,
> +		     void *user_param __rte_unused)
> +{
> +	unsigned i;
> +
> +	for (i = 0; i < nb_pkts; ++i)
> +		parse_packet_type(pkts[i]);
> +}
> +
>  int
>  main(int argc, char **argv)
>  {
> @@ -2672,6 +2750,11 @@ main(int argc, char **argv)
>  				rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d, "
>  					"port=%d\n", ret, portid);
> 
> +			if (!check_packet_type_ok(portid) && !parse_ptype)
> +				rte_exit(EXIT_FAILURE,
> +					 "port %d cannot parse packet type, please add --%s\n",
> +					 portid, CMD_LINE_OPT_PARSE_PTYPE);
> +
>  			qconf = &lcore_conf[lcore_id];
>  			qconf->tx_queue_id[portid] = queueid;
>  			queueid++;
> @@ -2705,6 +2788,14 @@ main(int argc, char **argv)
>  			if (ret < 0)
>  				rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
>  						"port=%d\n", ret, portid);
> +			if (parse_ptype &&
> +			    !rte_eth_add_rx_callback(portid, queueid,
> +				    		     cb_parse_packet_type,
> +						     NULL))
> +				rte_exit(EXIT_FAILURE,
> +					 "Failed to add rx callback: port=%d\n",
> +					 portid);
> +
>  		}
>  	}
> 
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-01-15  5:45   ` [PATCH v2 07/12] pmd/ixgbe: " Jianfeng Tan
@ 2016-01-15 14:50     ` Ananyev, Konstantin
  2016-02-25  6:43       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-15 14:50 UTC (permalink / raw)
  To: Tan, Jianfeng, dev



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, January 15, 2016 5:46 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> Subject: [PATCH v2 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
>  drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
>  drivers/net/ixgbe/ixgbe_rxtx.c   |  5 ++++-
>  3 files changed, 44 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
> index 4c4c6df..b3ae7b2 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
> @@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
>  					     uint8_t is_rx);
>  static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
>  			       struct rte_eth_dev_info *dev_info);
> +static int ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[]);
>  static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
>  				 struct rte_eth_dev_info *dev_info);
>  static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
> @@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
>  	.xstats_reset         = ixgbe_dev_xstats_reset,
>  	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
>  	.dev_infos_get        = ixgbe_dev_info_get,
> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>  	.mtu_set              = ixgbe_dev_mtu_set,
>  	.vlan_filter_set      = ixgbe_vlan_filter_set,
>  	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
> @@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
>  	.xstats_reset         = ixgbevf_dev_stats_reset,
>  	.dev_close            = ixgbevf_dev_close,
>  	.dev_infos_get        = ixgbevf_dev_info_get,
> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>  	.mtu_set              = ixgbevf_dev_set_mtu,
>  	.vlan_filter_set      = ixgbevf_vlan_filter_set,
>  	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
> @@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>  	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
>  }
> 
> +static int
> +ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
> +{
> +	int num = 0;
> +
> +	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
> +	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec) {

Is there any point in that big if above?
All ixgbe recv functions support ptype recognition, so why to have it at all?
Same question for igb.
Konstantin

> +		/*
> +		 * for non-vec functions,
> +		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
> +		 * for vec functions,
> +		 * refers to _recv_raw_pkts_vec().
> +		 */
> +		ptypes[num++] = RTE_PTYPE_L2_ETHER;
> +		ptypes[num++] = RTE_PTYPE_L3_IPV4;
> +		ptypes[num++] = RTE_PTYPE_L3_IPV4_EXT;
> +		ptypes[num++] = RTE_PTYPE_L3_IPV6;
> +		ptypes[num++] = RTE_PTYPE_L3_IPV6_EXT;
> +		ptypes[num++] = RTE_PTYPE_L4_SCTP;
> +		ptypes[num++] = RTE_PTYPE_L4_TCP;
> +		ptypes[num++] = RTE_PTYPE_L4_UDP;
> +		ptypes[num++] = RTE_PTYPE_TUNNEL_IP;
> +		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6;
> +		ptypes[num++] = RTE_PTYPE_INNER_L3_IPV6_EXT;
> +		ptypes[num++] = RTE_PTYPE_INNER_L4_TCP;
> +		ptypes[num++] = RTE_PTYPE_INNER_L4_UDP;
> +	}
> +
> +	return num;
> +}
> +
>  static void
>  ixgbevf_dev_info_get(struct rte_eth_dev *dev,
>  		     struct rte_eth_dev_info *dev_info)
> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
> index d26771a..2479830 100644
> --- a/drivers/net/ixgbe/ixgbe_ethdev.h
> +++ b/drivers/net/ixgbe/ixgbe_ethdev.h
> @@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
>  uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>  		uint16_t nb_pkts);
> 
> +uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
> +			   uint16_t nb_pkts);
>  uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
>  		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
>  uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
> diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
> index 52a263c..d324099 100644
> --- a/drivers/net/ixgbe/ixgbe_rxtx.c
> +++ b/drivers/net/ixgbe/ixgbe_rxtx.c
> @@ -899,6 +899,9 @@ end_of_tx:
>  #define IXGBE_PACKET_TYPE_MAX               0X80
>  #define IXGBE_PACKET_TYPE_MASK              0X7F
>  #define IXGBE_PACKET_TYPE_SHIFT             0X04
> +/*
> + * @note: fix ixgbe_dev_ptype_info_get() if any change here.
> + */
>  static inline uint32_t
>  ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
>  {
> @@ -1247,7 +1250,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>  }
> 
>  /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
> -static uint16_t
> +uint16_t
>  ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
>  			   uint16_t nb_pkts)
>  {
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-01-15  5:45   ` [PATCH v2 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-01-15 13:58     ` Adrien Mazarguil
@ 2016-01-15 15:03     ` Ananyev, Konstantin
  2016-02-25  6:53       ` Tan, Jianfeng
  1 sibling, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-15 15:03 UTC (permalink / raw)
  To: Tan, Jianfeng, dev



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, January 15, 2016 5:46 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> Subject: [PATCH v2 01/12] ethdev: add API to query packet type filling info
> 
> Add a new API rte_eth_dev_get_ptype_info to query wether/what packet type will
> be filled by given pmd rx burst function.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 20 ++++++++++++++++++++
>  lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++
>  lib/librte_mbuf/rte_mbuf.h    |  6 ++++++
>  3 files changed, 53 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index ed971b4..cd34f46 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1614,6 +1614,26 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>  	dev_info->driver_name = dev->data->drv_name;
>  }
> 
> +int
> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> +			   uint32_t ptypes[], int num)
> +{
> +	int ret, i, j;
> +	struct rte_eth_dev *dev;
> +	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +	dev = &rte_eth_devices[port_id];
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> +	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
> +
> +	for (i = 0, j = 0; i < ret && j < num; ++i)
> +		if (all_ptypes[i] & ptype_mask)
> +			ptypes[j++] = all_ptypes[i];
> +
> +	return ret;

I think it needs to be something like:

j = 0;
for (i = 0, j = 0; i < ret; ++i) {
     if (all_ptypes[i] & ptype_mask) {
          if (j < num)
               ptypes[j] = all_ptypes[i];
          j++;
   }
}

return j;

Konstantin

> +}
> +
>  void
>  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
>  {
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index bada8ad..42f8188 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
>  				    struct rte_eth_dev_info *dev_info);
>  /**< @internal Get specific informations of an Ethernet device. */
> 
> +typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
> +					uint32_t ptypes[]);
> +/**< @internal Get ptype info of eth_rx_burst_t. */
> +
>  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
>  				    uint16_t queue_id);
>  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> @@ -1347,6 +1351,7 @@ struct eth_dev_ops {
>  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
>  	/**< Configure per queue stat counter mapping. */
>  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
>  	mtu_set_t                  mtu_set; /**< Set MTU. */
>  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
>  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> @@ -2273,6 +2278,28 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
>  				 struct rte_eth_dev_info *dev_info);
> 
>  /**
> + * Retrieve the contextual information of an Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param ptype_mask
> + *   A hint of what kind of packet type which the caller is interested in.
> + * @param ptypes
> + *   An array of packet types to be filled with.
> + * @param num
> + *   The size of ptypes array.
> + * @return
> + *   - (>0) Number of ptypes supported. May be greater than param num and
> + *	    caller needs to check that.
> + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> + *   - (-ENODEV) if *port_id* invalid.
> + */
> +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> +				      uint32_t ptype_mask,
> +				      uint32_t ptypes[],
> +				      int num);
> +
> +/**
>   * Retrieve the MTU of an Ethernet device.
>   *
>   * @param port_id
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index f234ac9..d116711 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -667,6 +667,12 @@ extern "C" {
>  #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
> 
>  /**
> +  * Total number of all kinds of RTE_PTYPE_*, except from *_MASK, is 37 for now
> +  * and reserve some space for new ptypes
> +  */
> +#define RTE_PTYPE_MAX_NUM		    64
> +
> +/**
>   * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
>   * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
>   * determine if it is an IPV4 packet.
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-01-15 13:58     ` Adrien Mazarguil
@ 2016-01-15 15:11       ` Ananyev, Konstantin
  2016-01-15 15:33         ` Adrien Mazarguil
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-01-15 15:11 UTC (permalink / raw)
  To: Adrien Mazarguil, Tan, Jianfeng; +Cc: dev

Hi lads,

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> Sent: Friday, January 15, 2016 1:59 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 01/12] ethdev: add API to query packet type filling info
> 
> Hi Jianfeng, a few comments below.
> 
> On Fri, Jan 15, 2016 at 01:45:48PM +0800, Jianfeng Tan wrote:
> > Add a new API rte_eth_dev_get_ptype_info to query wether/what packet type will
> > be filled by given pmd rx burst function.
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  lib/librte_ether/rte_ethdev.c | 20 ++++++++++++++++++++
> >  lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++
> >  lib/librte_mbuf/rte_mbuf.h    |  6 ++++++
> >  3 files changed, 53 insertions(+)
> >
> > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > index ed971b4..cd34f46 100644
> > --- a/lib/librte_ether/rte_ethdev.c
> > +++ b/lib/librte_ether/rte_ethdev.c
> > @@ -1614,6 +1614,26 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> >  	dev_info->driver_name = dev->data->drv_name;
> >  }
> >
> > +int
> > +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> > +			   uint32_t ptypes[], int num)
> > +{
> > +	int ret, i, j;
> > +	struct rte_eth_dev *dev;
> > +	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
> > +
> > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > +	dev = &rte_eth_devices[port_id];
> > +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> > +	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
> > +
> > +	for (i = 0, j = 0; i < ret && j < num; ++i)
> > +		if (all_ptypes[i] & ptype_mask)
> > +			ptypes[j++] = all_ptypes[i];
> > +
> > +	return ret;
> > +}
> 
> It's a good thing that the size of ptypes[] can be provided, but I think num
> should be passed to the dev_ptype_info_get() callback as well.
> 
> If you really do not want to pass the size, you have to force the array type
> size onto callbacks using a pointer to the array otherwise they look unsafe
> (and are actually unsafe when not called from the rte_eth_dev wrapper),
> something like this:
> 
>  int (*dev_ptype_info_get)(uint8_t port_id, uint32_t (*ptypes)[RTE_PTYPE_MAX_NUM]);
> 
> In which case you might as well drop the num argument from
> rte_eth_dev_get_ptype_info() to use the same syntax. That way there is no
> need to allocate a ptypes array on the stack twice.
> 
> But since people usually do not like this syntax, I think passing num and
> letting callbacks check for overflow themselves on the user-provided ptypes
> array directly is better. They have to return the total number of packet
> types supported even when num is 0 (ptypes may be NULL in that case).
> 
> I understand the result needs to be temporarily stored somewhere for
> filtering and for that purpose the entire size must be known in advance,
> hence my previous suggestion for rte_eth_dev_get_ptype_info() to return
> the total number of ptypes and providing a separate function for filtering
> a ptypes array for applications that need it:
> 
>  /* Return remaining number entries in ptypes[] after filtering it
>   * according to ptype_mask. */
>  int rte_eth_dev_ptypes_filter(uint32_t ptype_mask, uint32_t ptypes[], int num);
> 
> Usage would be like:
> 
>  int ptypes_num = rte_eth_dev_get_ptype_info(42, NULL, 0);
> 
>  if (ptypes_num <= 0)
>      goto err;
> 
>  uint32_t ptypes[ptypes_num];
> 
>  rte_eth_dev_get_ptype_info(42, ptypes, ptypes_num);
>  ptypes_num = rte_eth_dev_ptypes_filter(RTE_PTYPE_INNER_L4_MASK, ptypes, ptypes_num);
> 
>  if (ptypes_num <= 0)
>     goto err;
> 
>  /* process ptypes... */
> 
> What about this?

Actually while thinking about it, we probably can make:
const uint32_t * (*dev_ptype_info_get)(uint8_t port_id); 
So PMD return to ethdev layer a pointer to a constant array of supported ptypes,
terminated by  RTE_PTYPE_UNKNOWN.   
Then rte_eth_dev_get_ptype_info() will iterate over it, and fill array provided by the user.

all_pytpes = (*dev->dev_ops->dev_ptype_info_get)(dev);
for (i = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; i++) {
if (all_ptypes[i] & ptype_mask) {
          if (j < num)
               ptypes[j] = all_ptypes[i];
          j++;
}
return j;

Konstantin

> 
> > +
> >  void
> >  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
> >  {
> > diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > index bada8ad..42f8188 100644
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -1021,6 +1021,10 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
> >  				    struct rte_eth_dev_info *dev_info);
> >  /**< @internal Get specific informations of an Ethernet device. */
> >
> > +typedef int (*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev,
> > +					uint32_t ptypes[]);
> > +/**< @internal Get ptype info of eth_rx_burst_t. */
> > +
> >  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
> >  				    uint16_t queue_id);
> >  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> > @@ -1347,6 +1351,7 @@ struct eth_dev_ops {
> >  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
> >  	/**< Configure per queue stat counter mapping. */
> >  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> > +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
> >  	mtu_set_t                  mtu_set; /**< Set MTU. */
> >  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
> >  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> > @@ -2273,6 +2278,28 @@ extern void rte_eth_dev_info_get(uint8_t port_id,
> >  				 struct rte_eth_dev_info *dev_info);
> >
> >  /**
> > + * Retrieve the contextual information of an Ethernet device.
> > + *
> > + * @param port_id
> > + *   The port identifier of the Ethernet device.
> > + * @param ptype_mask
> > + *   A hint of what kind of packet type which the caller is interested in.
> > + * @param ptypes
> > + *   An array of packet types to be filled with.
> > + * @param num
> > + *   The size of ptypes array.
> > + * @return
> > + *   - (>0) Number of ptypes supported. May be greater than param num and
> > + *	    caller needs to check that.
> > + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> > + *   - (-ENODEV) if *port_id* invalid.
> > + */
> > +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> > +				      uint32_t ptype_mask,
> > +				      uint32_t ptypes[],
> > +				      int num);
> > +
> > +/**
> >   * Retrieve the MTU of an Ethernet device.
> >   *
> >   * @param port_id
> > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > index f234ac9..d116711 100644
> > --- a/lib/librte_mbuf/rte_mbuf.h
> > +++ b/lib/librte_mbuf/rte_mbuf.h
> > @@ -667,6 +667,12 @@ extern "C" {
> >  #define RTE_PTYPE_INNER_L4_MASK             0x0f000000
> >
> >  /**
> > +  * Total number of all kinds of RTE_PTYPE_*, except from *_MASK, is 37 for now
> > +  * and reserve some space for new ptypes
> > +  */
> > +#define RTE_PTYPE_MAX_NUM		    64
> 
> This macro should not be needed if the num argument is kept. Applications
> should only rely on returned values.
> 
> > +
> > +/**
> >   * Check if the (outer) L3 header is IPv4. To avoid comparing IPv4 types one by
> >   * one, bit 4 is selected to be used for IPv4 only. Then checking bit 4 can
> >   * determine if it is an IPV4 packet.
> > --
> > 2.1.4
> >
> 
> --
> Adrien Mazarguil
> 6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-01-15 15:11       ` Ananyev, Konstantin
@ 2016-01-15 15:33         ` Adrien Mazarguil
  0 siblings, 0 replies; 202+ messages in thread
From: Adrien Mazarguil @ 2016-01-15 15:33 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On Fri, Jan 15, 2016 at 03:11:18PM +0000, Ananyev, Konstantin wrote:
> Hi lads,
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Adrien Mazarguil
> > Sent: Friday, January 15, 2016 1:59 PM
> > To: Tan, Jianfeng
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v2 01/12] ethdev: add API to query packet type filling info
> > 
> > Hi Jianfeng, a few comments below.
> > 
> > On Fri, Jan 15, 2016 at 01:45:48PM +0800, Jianfeng Tan wrote:
> > > Add a new API rte_eth_dev_get_ptype_info to query wether/what packet type will
> > > be filled by given pmd rx burst function.
> > >
> > > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > > ---
> > >  lib/librte_ether/rte_ethdev.c | 20 ++++++++++++++++++++
> > >  lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++
> > >  lib/librte_mbuf/rte_mbuf.h    |  6 ++++++
> > >  3 files changed, 53 insertions(+)
> > >
> > > diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> > > index ed971b4..cd34f46 100644
> > > --- a/lib/librte_ether/rte_ethdev.c
> > > +++ b/lib/librte_ether/rte_ethdev.c
> > > @@ -1614,6 +1614,26 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> > >  	dev_info->driver_name = dev->data->drv_name;
> > >  }
> > >
> > > +int
> > > +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> > > +			   uint32_t ptypes[], int num)
> > > +{
> > > +	int ret, i, j;
> > > +	struct rte_eth_dev *dev;
> > > +	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
> > > +
> > > +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > > +	dev = &rte_eth_devices[port_id];
> > > +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> > > +	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
> > > +
> > > +	for (i = 0, j = 0; i < ret && j < num; ++i)
> > > +		if (all_ptypes[i] & ptype_mask)
> > > +			ptypes[j++] = all_ptypes[i];
> > > +
> > > +	return ret;
> > > +}
> > 
> > It's a good thing that the size of ptypes[] can be provided, but I think num
> > should be passed to the dev_ptype_info_get() callback as well.
> > 
> > If you really do not want to pass the size, you have to force the array type
> > size onto callbacks using a pointer to the array otherwise they look unsafe
> > (and are actually unsafe when not called from the rte_eth_dev wrapper),
> > something like this:
> > 
> >  int (*dev_ptype_info_get)(uint8_t port_id, uint32_t (*ptypes)[RTE_PTYPE_MAX_NUM]);
> > 
> > In which case you might as well drop the num argument from
> > rte_eth_dev_get_ptype_info() to use the same syntax. That way there is no
> > need to allocate a ptypes array on the stack twice.
> > 
> > But since people usually do not like this syntax, I think passing num and
> > letting callbacks check for overflow themselves on the user-provided ptypes
> > array directly is better. They have to return the total number of packet
> > types supported even when num is 0 (ptypes may be NULL in that case).
> > 
> > I understand the result needs to be temporarily stored somewhere for
> > filtering and for that purpose the entire size must be known in advance,
> > hence my previous suggestion for rte_eth_dev_get_ptype_info() to return
> > the total number of ptypes and providing a separate function for filtering
> > a ptypes array for applications that need it:
> > 
> >  /* Return remaining number entries in ptypes[] after filtering it
> >   * according to ptype_mask. */
> >  int rte_eth_dev_ptypes_filter(uint32_t ptype_mask, uint32_t ptypes[], int num);
> > 
> > Usage would be like:
> > 
> >  int ptypes_num = rte_eth_dev_get_ptype_info(42, NULL, 0);
> > 
> >  if (ptypes_num <= 0)
> >      goto err;
> > 
> >  uint32_t ptypes[ptypes_num];
> > 
> >  rte_eth_dev_get_ptype_info(42, ptypes, ptypes_num);
> >  ptypes_num = rte_eth_dev_ptypes_filter(RTE_PTYPE_INNER_L4_MASK, ptypes, ptypes_num);
> > 
> >  if (ptypes_num <= 0)
> >     goto err;
> > 
> >  /* process ptypes... */
> > 
> > What about this?
> 
> Actually while thinking about it, we probably can make:
> const uint32_t * (*dev_ptype_info_get)(uint8_t port_id); 
> So PMD return to ethdev layer a pointer to a constant array of supported ptypes,
> terminated by  RTE_PTYPE_UNKNOWN.   
>
> Then rte_eth_dev_get_ptype_info() will iterate over it, and fill array provided by the user.
> 
> all_pytpes = (*dev->dev_ops->dev_ptype_info_get)(dev);
> for (i = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; i++) {
> if (all_ptypes[i] & ptype_mask) {
>           if (j < num)
>                ptypes[j] = all_ptypes[i];
>           j++;
> }
> return j;

Looks like a much simpler and better approach, that's the implementation we
need! (ignore my overengineered blob above)

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 00/12] Add API to get packet type info
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
                     ` (11 preceding siblings ...)
  2016-01-15  5:45   ` [PATCH v2 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
@ 2016-02-23 17:31   ` Bruce Richardson
  12 siblings, 0 replies; 202+ messages in thread
From: Bruce Richardson @ 2016-02-23 17:31 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

On Fri, Jan 15, 2016 at 01:45:47PM +0800, Jianfeng Tan wrote:
> A new ether API rte_eth_dev_get_ptype_info() is added to query what
> packet type information will be provided by current pmd driver of the
> specifed port.
> 
> To achieve this, a new function pointer, dev_ptype_info_get, is added
> into struct eth_dev_ops. For those devices who do not implement it, it
> means it will not provide any ptype info.
> 
> v2:
>   - Move ptype_mask filter function from each PMDs into ether layer.
>   - Add ixgbe vPMD's ptype info.
>   - Fix code style issues.
>
Hi,

there are some outstanding comments on these patches. Can you send a V3 to
resolve them?

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-01-15 14:50     ` Ananyev, Konstantin
@ 2016-02-25  6:43       ` Tan, Jianfeng
  2016-02-25 11:10         ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-25  6:43 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 1/15/2016 10:50 PM, Ananyev, Konstantin wrote:
>
>> -----Original Message-----
>> From: Tan, Jianfeng
>> Sent: Friday, January 15, 2016 5:46 AM
>> To: dev@dpdk.org
>> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
>> Subject: [PATCH v2 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
>>   drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
>>   drivers/net/ixgbe/ixgbe_rxtx.c   |  5 ++++-
>>   3 files changed, 44 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
>> index 4c4c6df..b3ae7b2 100644
>> --- a/drivers/net/ixgbe/ixgbe_ethdev.c
>> +++ b/drivers/net/ixgbe/ixgbe_ethdev.c
>> @@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
>>   					     uint8_t is_rx);
>>   static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
>>   			       struct rte_eth_dev_info *dev_info);
>> +static int ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[]);
>>   static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
>>   				 struct rte_eth_dev_info *dev_info);
>>   static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
>> @@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
>>   	.xstats_reset         = ixgbe_dev_xstats_reset,
>>   	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
>>   	.dev_infos_get        = ixgbe_dev_info_get,
>> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>>   	.mtu_set              = ixgbe_dev_mtu_set,
>>   	.vlan_filter_set      = ixgbe_vlan_filter_set,
>>   	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
>> @@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
>>   	.xstats_reset         = ixgbevf_dev_stats_reset,
>>   	.dev_close            = ixgbevf_dev_close,
>>   	.dev_infos_get        = ixgbevf_dev_info_get,
>> +	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
>>   	.mtu_set              = ixgbevf_dev_set_mtu,
>>   	.vlan_filter_set      = ixgbevf_vlan_filter_set,
>>   	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
>> @@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
>>   	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
>>   }
>>
>> +static int
>> +ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
>> +{
>> +	int num = 0;
>> +
>> +	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
>> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
>> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
>> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
>> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
>> +	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec) {
> Is there any point in that big if above?
> All ixgbe recv functions support ptype recognition, so why to have it at all?
> Same question for igb.
> Konstantin

I'd like this code to put it explicitly instead of an "if 
(dev->rx_pkt_burst)" to indicate that all ixgbe recv functions supports 
these ptypes.

Is it make sense?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-01-15 15:03     ` Ananyev, Konstantin
@ 2016-02-25  6:53       ` Tan, Jianfeng
  2016-02-25 11:17         ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-25  6:53 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 1/15/2016 11:03 PM, Ananyev, Konstantin wrote:
>
>> -----Original Message-----
>> From: Tan, Jianfeng
>> Sent: Friday, January 15, 2016 5:46 AM
>> To: dev@dpdk.org
>> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
>> Subject: [PATCH v2 01/12] ethdev: add API to query packet type filling info
>>
>> Add a new API rte_eth_dev_get_ptype_info to query wether/what packet type will
>> be filled by given pmd rx burst function.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   lib/librte_ether/rte_ethdev.c | 20 ++++++++++++++++++++
>>   lib/librte_ether/rte_ethdev.h | 27 +++++++++++++++++++++++++++
>>   lib/librte_mbuf/rte_mbuf.h    |  6 ++++++
>>   3 files changed, 53 insertions(+)
>>
>> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
>> index ed971b4..cd34f46 100644
>> --- a/lib/librte_ether/rte_ethdev.c
>> +++ b/lib/librte_ether/rte_ethdev.c
>> @@ -1614,6 +1614,26 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>>   	dev_info->driver_name = dev->data->drv_name;
>>   }
>>
>> +int
>> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
>> +			   uint32_t ptypes[], int num)
>> +{
>> +	int ret, i, j;
>> +	struct rte_eth_dev *dev;
>> +	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
>> +
>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +	dev = &rte_eth_devices[port_id];
>> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
>> +	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
>> +
>> +	for (i = 0, j = 0; i < ret && j < num; ++i)
>> +		if (all_ptypes[i] & ptype_mask)
>> +			ptypes[j++] = all_ptypes[i];
>> +
>> +	return ret;
> I think it needs to be something like:
>
> j = 0;
> for (i = 0, j = 0; i < ret; ++i) {
>       if (all_ptypes[i] & ptype_mask) {
>            if (j < num)
>                 ptypes[j] = all_ptypes[i];
>            j++;
>     }
> }
>
> return j;
>
> Konstantin
>

You are right, my previous code is wrong.
But I have a concern about your code above: under the condition that the 
caller does not provide big enough array to store adequate ptypes, it 
has no way to return the not-enough-memory message back to caller.

So under that condition, how about we just return -ENOMEM?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v3 00/12] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (13 preceding siblings ...)
  2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
@ 2016-02-25  7:53 ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
                     ` (11 more replies)
  2016-02-26  0:04 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                   ` (6 subsequent siblings)
  21 siblings, 12 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it will not provide any ptype info.

v3:
  - Change how to use this API: api to allocate mem for storing ptype
    array; and caller to free the mem.
  - Change how to return back ptypes from PMDs: return a pointer to
    corresponding static const array of supported ptypes, terminated
    by RTE_PTYPE_UNKNOWN.
  - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
  - Fix l3fwd memory leak when calling the API.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Jianfeng Tan (12):
  ethdev: add API to query packet type filling info
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation
  examples/l3fwd: add option to parse ptype

 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 drivers/net/cxgbe/cxgbe_ethdev.c        |  14 ++++
 drivers/net/e1000/igb_ethdev.c          |  30 ++++++++
 drivers/net/enic/enic_ethdev.c          |  17 +++++
 drivers/net/fm10k/fm10k_ethdev.c        |  50 +++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c          |   3 +
 drivers/net/fm10k/fm10k_rxtx_vec.c      |   3 +
 drivers/net/i40e/i40e_ethdev.c          |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c       |   1 +
 drivers/net/i40e/i40e_rxtx.c            |  46 +++++++++++-
 drivers/net/i40e/i40e_rxtx.h            |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 ++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h        |   2 +
 drivers/net/ixgbe/ixgbe_rxtx.c          |   4 +-
 drivers/net/mlx4/mlx4.c                 |  21 ++++++
 drivers/net/mlx5/mlx5.c                 |   1 +
 drivers/net/mlx5/mlx5.h                 |   1 +
 drivers/net/mlx5/mlx5_ethdev.c          |  20 ++++++
 drivers/net/mlx5/mlx5_rxtx.c            |   2 +
 drivers/net/nfp/nfp_net.c               |  19 +++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 +++++
 examples/l3fwd/main.c                   | 122 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.c           |  32 +++++++++
 lib/librte_ether/rte_ethdev.h           |  23 ++++++
 24 files changed, 470 insertions(+), 3 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v3 01/12] ethdev: add API to query packet type filling info
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25 15:46     ` Ananyev, Konstantin
  2016-02-25  7:53   ` [PATCH v3 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
                     ` (10 subsequent siblings)
  11 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
type can be filled by given pmd rx burst function.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 32 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h | 23 +++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..b52555b 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1576,6 +1576,38 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t **p_ptypes)
+{
+	int i, j, ret;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, ret = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask)
+			ret++;
+	if (ret == 0)
+		return 0;
+
+	*p_ptypes = (uint32_t *)malloc(sizeof(uint32_t) * ret);
+	if (*p_ptypes == NULL)
+		return -ENOMEM;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask)
+			*p_ptypes[j++] = all_ptypes[i];
+	return ret;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..341e2ff 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get ptype info of eth_rx_burst_t. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2268,6 +2272,25 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the packet type information of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param p_ptypes
+ *   A pointer to store address of adequent packet types array. Caller to free.
+ * @return
+ *   - (>0) Number of ptypes supported. Need caller to free the array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENOMEM) if fail to malloc required memory to store ptypes.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
+				      uint32_t ptype_mask,
+				      uint32_t **p_ptypes);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 02/12] pmd/cxgbe: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 03/12] pmd/e1000: " Jianfeng Tan
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..33bd815 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,19 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static const uint32_t *cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +790,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_ptype_info_get	= cxgbe_dev_ptype_info_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 03/12] pmd/e1000: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 04/12] pmd/enic: " Jianfeng Tan
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4ed5e95..b3a3ee6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -103,6 +103,7 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static const uint32_t *eth_igb_ptype_info_get(struct rte_eth_dev *dev);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -319,6 +320,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -376,6 +378,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1910,6 +1913,33 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static const uint32_t *
+eth_igb_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+	    dev->rx_pkt_burst == eth_igb_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 04/12] pmd/enic: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-02-25  7:53   ` [PATCH v3 03/12] pmd/e1000: " Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 05/12] pmd/fm10k: " Jianfeng Tan
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2a88043..fbeab6f 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -54,6 +54,9 @@
 #define ENICPMD_FUNC_TRACE() (void)0
 #endif
 
+static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+				  uint16_t nb_pkts);
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -431,6 +434,19 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
+static const uint32_t *enicpmd_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == enicpmd_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -566,6 +582,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_ptype_info_get   = enicpmd_dev_ptype_info_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 05/12] pmd/fm10k: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-02-25  7:53   ` [PATCH v3 04/12] pmd/enic: " Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 06/12] pmd/i40e: " Jianfeng Tan
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..429cbdd 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		static uint32_t ptypes[] = {
+			/* refers to rx_desc_to_ol_flags() */
+			RTE_PTYPE_L2_ETHER,
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		static uint32_t ptypes_vec[] = {
+			/* refers to fm10k_desc_to_pktype_v() */
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_TUNNEL_GENEVE,
+			RTE_PTYPE_TUNNEL_NVGRE,
+			RTE_PTYPE_TUNNEL_VXLAN,
+			RTE_PTYPE_TUNNEL_GRE,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes_vec;
+	}
+
+	return NULL;
+}
+#else
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev __rte_unused)
+{
+	return NULL;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2423,6 +2472,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_ptype_info_get	= fm10k_dev_ptype_info_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index e958865..cbe0111 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,9 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 2a57eef..f347641 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -109,6 +109,9 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get().
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 06/12] pmd/i40e: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-02-25  7:53   ` [PATCH v3 05/12] pmd/fm10k: " Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 07/12] pmd/ixgbe: " Jianfeng Tan
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 46 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..81849fa 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -439,6 +439,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_ptype_info_get           = i40e_dev_ptype_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..afd436e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -196,6 +196,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_ptype_info_get   = i40e_dev_ptype_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 40cffc1..1a952df 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -194,7 +194,10 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/* For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2093,6 +2096,47 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 	return 0;
 }
 
+const uint32_t *
+i40e_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_TIMESYNC,
+		RTE_PTYPE_L2_ETHER_LLDP,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_L4_NONFRAG,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L2_ETHER_VLAN,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_ICMP,
+		RTE_PTYPE_INNER_L4_NONFRAG,
+		RTE_PTYPE_INNER_L4_SCTP,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+	    dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+	    dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..3a59d81 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,7 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+const uint32_t *i40e_dev_ptype_info_get(struct rte_eth_dev *dev);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-02-25  7:53   ` [PATCH v3 06/12] pmd/i40e: " Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 08/12] pmd/mlx4: " Jianfeng Tan
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  4 +++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3e6fe86..605d958 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static const uint32_t *ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static const uint32_t *
+ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* For non-vec functions,
+		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+		 * for vec functions,
+		 * refers to _recv_raw_pkts_vec().
+		 */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
+	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec)
+		return ptypes;
+	return NULL;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index d26771a..b07d3da 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+				    uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index e95e6b7..17851cc 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -899,6 +899,8 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+
+/* @note: fix ixgbe_dev_ptype_info_get() if any change here. */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1247,7 +1249,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-02-25  7:53   ` [PATCH v3 07/12] pmd/ixgbe: " Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:53   ` [PATCH v3 09/12] pmd/mlx5: " Jianfeng Tan
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ee00151..85fdebf 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2835,6 +2835,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4267,6 +4269,24 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static uint32_t *
+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == mlx4_rx_burst ||
+	    dev->rx_pkt_burst == mlx4_rx_burst_sp)
+		return ptypes;
+	return NULL;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -4988,6 +5008,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 09/12] pmd/mlx5: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-02-25  7:53   ` [PATCH v3 08/12] pmd/mlx4: " Jianfeng Tan
@ 2016-02-25  7:53   ` Jianfeng Tan
  2016-02-25  7:54   ` [PATCH v3 10/12] pmd/nfp: " Jianfeng Tan
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:53 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c        |  2 +-
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  1 +
 drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 5 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 85fdebf..58f4e1a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4269,7 +4269,7 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
-static uint32_t *
+static const uint32_t *
 mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
 {
 	static const uint32_t ptypes[] = {
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..e18b1e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -153,6 +153,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_ptype_info_get = mlx5_dev_ptype_info_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b84d31d..196435d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -156,6 +156,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+const uint32_t *mlx5_dev_ptype_info_get(struct rte_eth_dev *dev);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..406f8dc 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -526,6 +526,26 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+const uint32_t *
+mlx5_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+
+	};
+
+	if (dev->rx_pkt_burst == mlx5_rx_burst ||
+	    dev->rx_pkt_burst == mlx5_rx_burst_sp)
+		return ptypes;
+	return NULL;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index fa5e648..79bdf8d 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -603,6 +603,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 10/12] pmd/nfp: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-02-25  7:53   ` [PATCH v3 09/12] pmd/mlx5: " Jianfeng Tan
@ 2016-02-25  7:54   ` Jianfeng Tan
  2016-02-25  7:54   ` [PATCH v3 11/12] pmd/vmxnet3: " Jianfeng Tan
  2016-02-25  7:54   ` [PATCH v3 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:54 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/nfp/nfp_net.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index fd4dd39..5894a9d 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1073,6 +1073,24 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 }
 
+static const uint32_t *
+nfp_net_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to nfp_net_set_hash() */
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_MASK,
+		RTE_PTYPE_UNKNOWN
+	};
+
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts)
+		return ptypes;
+	return num;
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2292,6 +2310,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_ptype_info_get	= nfp_net_ptype_info_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 11/12] pmd/vmxnet3: add dev_ptype_info_get implementation
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-02-25  7:54   ` [PATCH v3 10/12] pmd/nfp: " Jianfeng Tan
@ 2016-02-25  7:54   ` Jianfeng Tan
  2016-02-25  7:54   ` [PATCH v3 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:54 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..ac120a1 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,7 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static const uint32_t *vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -118,6 +119,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.link_update          = vmxnet3_dev_link_update,
 	.stats_get            = vmxnet3_dev_stats_get,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_ptype_info_get   = vmxnet3_dev_ptype_info_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -718,6 +720,20 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, struct rte_
 	};
 }
 
+static const uint32_t *
+vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 12/12] examples/l3fwd: add option to parse ptype
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
                     ` (10 preceding siblings ...)
  2016-02-25  7:54   ` [PATCH v3 11/12] pmd/vmxnet3: " Jianfeng Tan
@ 2016-02-25  7:54   ` Jianfeng Tan
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-25  7:54 UTC (permalink / raw)
  To: dev

As a example to use ptype info, l3fwd needs firstly to use
rte_eth_dev_get_ptype_info() API to check if device and/or PMD driver will
parse and fill the needed packet type; if not, use the newly added option,
--parse-ptype, to analyze it in the callback softly.

Under the mode of EXACT_MATCH, ip packets with extensions or ip packets
which are neither tcp nor udp cannot work well because it needs the 5
tuples to caculate hash.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 examples/l3fwd/main.c                   | 122 ++++++++++++++++++++++++++++++++
 2 files changed, 127 insertions(+), 1 deletion(-)

diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst
index 4ce734b..e0c22e3 100644
--- a/doc/guides/sample_app_ug/l3_forward.rst
+++ b/doc/guides/sample_app_ug/l3_forward.rst
@@ -93,7 +93,7 @@ The application has a number of command line options:
 
 .. code-block:: console
 
-    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6]
+    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6] [--parse-ptype]
 
 where,
 
@@ -114,6 +114,8 @@ where,
 
 *   --ipv6: optional, set it if running ipv6 packets
 
+*   --parse-ptype: optional, set it if use software way to analyze packet type
+
 For example, consider a dual processor socket platform where cores 0-7 and 16-23 appear on socket 0, while cores 8-15 and 24-31 appear on socket 1.
 Let's say that the programmer wants to use memory from both NUMA nodes, the platform has only two ports, one connected to each NUMA node,
 and the programmer wants to use two cores from each processor socket to do the packet processing.
@@ -334,6 +336,8 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below:
 
 The simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function.
 
+Known issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well with this mode.
+
 Packet Forwarding for LPM-based Lookups
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 410f72d..3c43a90 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -178,6 +178,8 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
 static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by default. */
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
 static int ipv6 = 0; /**< ipv6 is false by default. */
@@ -2029,6 +2031,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /* Parse the argument given in the command line of the application */
 static int
@@ -2045,6 +2048,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -2132,6 +2136,13 @@ parse_args(int argc, char **argv)
 				}
 			}
 #endif
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -2580,6 +2591,105 @@ signal_handler(int signum)
 	}
 }
 
+static int
+check_packet_type_ok(int portid)
+{
+	int i, ret;
+	uint32_t *ptypes;
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, &ptypes);
+	if (ret <= 0)
+		return 0;
+
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+	free(ptypes);
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+}
+static inline void
+parse_packet_type(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = 0;
+	uint16_t ethertype;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+		{
+			int hdr_len;
+			struct ipv4_hdr *hdr;
+
+			hdr = (struct ipv4_hdr *)((uint8_t *)eth_hdr +
+						sizeof(struct ether_hdr));
+			hdr_len = (hdr->version_ihl & IPV4_HDR_IHL_MASK)
+				* IPV4_IHL_MULTIPLIER;
+			/* Exact match uses 5 tuples to calculate hash, so
+			 * adequate packets should not only have no ip header
+			 * extension but also be TCP/UDP packet
+			 */
+			if (hdr_len == sizeof(struct ipv4_hdr) &&
+			    (hdr->next_proto_id == 6 ||
+			     hdr->next_proto_id == 17))
+				packet_type |= RTE_PTYPE_L3_IPV4;
+		}
+#elif (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+#endif
+		break;
+	case ETHER_TYPE_IPv6:
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+		{
+			struct ipv6_hdr *hdr;
+
+			hdr = (struct ipv6_hdr *)((uint8_t *)eth_hdr +
+						  sizeof(struct ether_hdr));
+			if (hdr->proto == 6 || hdr->proto == 17)
+				packet_type |= RTE_PTYPE_L3_IPV4;
+		}
+
+#elif (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	m->packet_type |= packet_type;
+}
+
+static uint16_t
+cb_parse_packet_type(uint8_t port __rte_unused,
+		     uint16_t queue __rte_unused,
+		     struct rte_mbuf *pkts[],
+		     uint16_t nb_pkts,
+		     uint16_t max_pkts __rte_unused,
+		     void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_packet_type(pkts[i]);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -2697,6 +2807,11 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d, "
 					"port=%d\n", ret, portid);
 
+			if (!check_packet_type_ok(portid) && !parse_ptype)
+				rte_exit(EXIT_FAILURE,
+					 "port %d cannot parse packet type, please add --%s\n",
+					 portid, CMD_LINE_OPT_PARSE_PTYPE);
+
 			qconf = &lcore_conf[lcore_id];
 			qconf->tx_queue_id[portid] = queueid;
 			queueid++;
@@ -2730,6 +2845,13 @@ main(int argc, char **argv)
 			if (ret < 0)
 				rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
 						"port=%d\n", ret, portid);
+			if (parse_ptype &&
+			    !rte_eth_add_rx_callback(portid, queueid,
+						     cb_parse_packet_type,
+						     NULL))
+				rte_exit(EXIT_FAILURE,
+					 "Failed to add rx callback: port=%d\n",
+					 portid);
 		}
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
  2016-01-15 14:47     ` Ananyev, Konstantin
@ 2016-02-25 10:41       ` Tan, Jianfeng
  2016-02-25 10:57         ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-25 10:41 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 1/15/2016 10:47 PM, Ananyev, Konstantin wrote:
> Hi Jianfeng,
>
>> -----Original Message-----
>> From: Tan, Jianfeng
>> Sent: Friday, January 15, 2016 5:46 AM
>> To: dev@dpdk.org
>> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
>> Subject: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
>>
>> As a example to use ptype info, l3fwd needs firstly to use
>> rte_eth_dev_get_ptype_info() API to check if device and/or PMD driver will
>> parse and fill the needed packet type. If not, use the newly added option,
>> --parse-ptype, to analyze it in the callback softly.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   examples/l3fwd/main.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
>>   1 file changed, 91 insertions(+)
>>
...
>> +static inline void
>> +parse_packet_type(struct rte_mbuf *m)
>> +{
>> +	struct ether_hdr *eth_hdr;
>> +	uint32_t packet_type = 0;
>> +	uint16_t ethertype;
>> +
>> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
>> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
>> +	switch (ethertype) {
>> +	case ETHER_TYPE_IPv4:
>> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
>> +		break;
>> +	case ETHER_TYPE_IPv6:
>> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
>> +		break;
> That's enough for LPM, for EM, don't we need to be sure there are no extensions
> in the IP header?
>
> Konstantin

Yes, EM needs to differentiate RTE_PTYPE_L3_IPV4/RTE_PTYPE_L3_IPV4_EXT, 
RTE_PTYPE_L3_IPV6/RTE_PTYPE_L3_IPV6_EXT:
a. for soft ptype parser here, I'll add the code to do it.

b. for hardware ptype parser, things become complex:
those NICs which can differentiate:
e1000
fmf10k
ixgbe
those NICs which cannot differentiate:
cxgbe (ipv4, ipv6)
enic (ipv4, ipv6)
i40e (ipv4_ext_unknown, ipv6_ext_unknown)
mlx4 (ipv4, ipv6)
mlx5 (ipv4, ipv6)
nfp (ipv4, ipv6, ipv6_ext)
vmxnet3 (ipv4, ipv4_ext)

As a result, l3fwd can only work perfectly on those NICs which can 
differentiate.

SO if we really do the strict checking?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
  2016-02-25 10:41       ` Tan, Jianfeng
@ 2016-02-25 10:57         ` Ananyev, Konstantin
  0 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-25 10:57 UTC (permalink / raw)
  To: Tan, Jianfeng, dev


Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Thursday, February 25, 2016 10:41 AM
> To: Ananyev, Konstantin; dev@dpdk.org
> Cc: Zhang, Helin
> Subject: Re: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
> 
> Hi Konstantin,
> 
> On 1/15/2016 10:47 PM, Ananyev, Konstantin wrote:
> > Hi Jianfeng,
> >
> >> -----Original Message-----
> >> From: Tan, Jianfeng
> >> Sent: Friday, January 15, 2016 5:46 AM
> >> To: dev@dpdk.org
> >> Cc: Zhang, Helin; Ananyev, Konstantin; Tan, Jianfeng
> >> Subject: [PATCH v2 12/12] examples/l3fwd: add option to parse ptype
> >>
> >> As a example to use ptype info, l3fwd needs firstly to use
> >> rte_eth_dev_get_ptype_info() API to check if device and/or PMD driver will
> >> parse and fill the needed packet type. If not, use the newly added option,
> >> --parse-ptype, to analyze it in the callback softly.
> >>
> >> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> >> ---
> >>   examples/l3fwd/main.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++
> >>   1 file changed, 91 insertions(+)
> >>
> ...
> >> +static inline void
> >> +parse_packet_type(struct rte_mbuf *m)
> >> +{
> >> +	struct ether_hdr *eth_hdr;
> >> +	uint32_t packet_type = 0;
> >> +	uint16_t ethertype;
> >> +
> >> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> >> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> >> +	switch (ethertype) {
> >> +	case ETHER_TYPE_IPv4:
> >> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> >> +		break;
> >> +	case ETHER_TYPE_IPv6:
> >> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> >> +		break;
> > That's enough for LPM, for EM, don't we need to be sure there are no extensions
> > in the IP header?
> >
> > Konstantin
> 
> Yes, EM needs to differentiate RTE_PTYPE_L3_IPV4/RTE_PTYPE_L3_IPV4_EXT,
> RTE_PTYPE_L3_IPV6/RTE_PTYPE_L3_IPV6_EXT:
> a. for soft ptype parser here, I'll add the code to do it.
> 
> b. for hardware ptype parser, things become complex:
> those NICs which can differentiate:
> e1000
> fmf10k
> ixgbe
> those NICs which cannot differentiate:
> cxgbe (ipv4, ipv6)
> enic (ipv4, ipv6)
> i40e (ipv4_ext_unknown, ipv6_ext_unknown)

Yep, I am aware about that difference  between i40e and rest of Intel PMDs :(

> mlx4 (ipv4, ipv6)
> mlx5 (ipv4, ipv6)
> nfp (ipv4, ipv6, ipv6_ext)
> vmxnet3 (ipv4, ipv4_ext)
> 
> As a result, l3fwd can only work perfectly on those NICs which can
> differentiate.

Well, we can do a SW parsing for that NICs,
but I presume it might slowdown things quite a bit. 

> 
> SO if we really do the strict checking?

Ok, but then we probably need to put into SA guide that l3fwd EM
not supposed to work with IP with extentions.

Konstantin

> 
> Thanks,
> Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-02-25  6:43       ` Tan, Jianfeng
@ 2016-02-25 11:10         ` Ananyev, Konstantin
  0 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-25 11:10 UTC (permalink / raw)
  To: Tan, Jianfeng, dev


> >>
> >> +static int
> >> +ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev, uint32_t ptypes[])
> >> +{
> >> +	int num = 0;
> >> +
> >> +	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
> >> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
> >> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
> >> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
> >> +	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
> >> +	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec) {
> > Is there any point in that big if above?
> > All ixgbe recv functions support ptype recognition, so why to have it at all?
> > Same question for igb.
> > Konstantin
> 
> I'd like this code to put it explicitly instead of an "if
> (dev->rx_pkt_burst)" to indicate that all ixgbe recv functions supports
> these ptypes.
> 
> Is it make sense?

It seems a bit of overhead to me, but if you would like to keep it as it is,
I wouldn't insist.
Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-02-25  6:53       ` Tan, Jianfeng
@ 2016-02-25 11:17         ` Ananyev, Konstantin
  2016-02-25 14:57           ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-25 11:17 UTC (permalink / raw)
  To: Tan, Jianfeng, dev


> >> +int
> >> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> >> +			   uint32_t ptypes[], int num)
> >> +{
> >> +	int ret, i, j;
> >> +	struct rte_eth_dev *dev;
> >> +	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
> >> +
> >> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> >> +	dev = &rte_eth_devices[port_id];
> >> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> >> +	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
> >> +
> >> +	for (i = 0, j = 0; i < ret && j < num; ++i)
> >> +		if (all_ptypes[i] & ptype_mask)
> >> +			ptypes[j++] = all_ptypes[i];
> >> +
> >> +	return ret;
> > I think it needs to be something like:
> >
> > j = 0;
> > for (i = 0, j = 0; i < ret; ++i) {
> >       if (all_ptypes[i] & ptype_mask) {
> >            if (j < num)
> >                 ptypes[j] = all_ptypes[i];
> >            j++;
> >     }
> > }
> >
> > return j;
> >
> > Konstantin
> >
> 
> You are right, my previous code is wrong.
> But I have a concern about your code above: under the condition that the
> caller does not provide big enough array to store adequate ptypes, it
> has no way to return the not-enough-memory message back to caller.
> 
> So under that condition, how about we just return -ENOMEM?
> 

As I remember, the agreement was - we don't return an -ENOMEM in that case.
What we do return - number of entries in ptypes[] that would be required to 
store all adequate ptypes (similar to what snprinf() does).
So the user can do something like that (if he needs to): 

num = rte_eth_dev_get_ptype_info(port,  ptype_mask, NULL, 0);
if (num < 0) {/*error handling*/}
ptypes = alloca(num * ptypes[0]);
n = rte_eth_dev_get_ptype_info(port,  ptype_mask, ptypes, num);
...

Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2 01/12] ethdev: add API to query packet type filling info
  2016-02-25 11:17         ` Ananyev, Konstantin
@ 2016-02-25 14:57           ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-25 14:57 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev



On 2/25/2016 7:17 PM, Ananyev, Konstantin wrote:
>>>> +int
>>>> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
>>>> +			   uint32_t ptypes[], int num)
>>>> +{
>>>> +	int ret, i, j;
>>>> +	struct rte_eth_dev *dev;
>>>> +	uint32_t all_ptypes[RTE_PTYPE_MAX_NUM];
>>>> +
>>>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>> +	dev = &rte_eth_devices[port_id];
>>>> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
>>>> +	ret = (*dev->dev_ops->dev_ptype_info_get)(dev, all_ptypes);
>>>> +
>>>> +	for (i = 0, j = 0; i < ret && j < num; ++i)
>>>> +		if (all_ptypes[i] & ptype_mask)
>>>> +			ptypes[j++] = all_ptypes[i];
>>>> +
>>>> +	return ret;
>>> I think it needs to be something like:
>>>
>>> j = 0;
>>> for (i = 0, j = 0; i < ret; ++i) {
>>>        if (all_ptypes[i] & ptype_mask) {
>>>             if (j < num)
>>>                  ptypes[j] = all_ptypes[i];
>>>             j++;
>>>      }
>>> }
>>>
>>> return j;
>>>
>>> Konstantin
>>>
>> You are right, my previous code is wrong.
>> But I have a concern about your code above: under the condition that the
>> caller does not provide big enough array to store adequate ptypes, it
>> has no way to return the not-enough-memory message back to caller.
>>
>> So under that condition, how about we just return -ENOMEM?
>>
> As I remember, the agreement was - we don't return an -ENOMEM in that case.
> What we do return - number of entries in ptypes[] that would be required to
> store all adequate ptypes (similar to what snprinf() does).
> So the user can do something like that (if he needs to):
>
> num = rte_eth_dev_get_ptype_info(port,  ptype_mask, NULL, 0);
> if (num < 0) {/*error handling*/}
> ptypes = alloca(num * ptypes[0]);
> n = rte_eth_dev_get_ptype_info(port,  ptype_mask, ptypes, num);
> ...
>
> Konstantin
>

Oh, yes. Sorry, I previously misunderstood your code.

But I still have a concern of above way that this APIs should be called 
two times. I suggest to use a way, like strdup, callee to malloc, caller 
to free. I send out v3 right now, please have a look at if it's OK.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v3 01/12] ethdev: add API to query packet type filling info
  2016-02-25  7:53   ` [PATCH v3 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-02-25 15:46     ` Ananyev, Konstantin
  2016-02-25 16:36       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-25 15:46 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi Jainfeng,

> 
> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
> type can be filled by given pmd rx burst function.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  lib/librte_ether/rte_ethdev.c | 32 ++++++++++++++++++++++++++++++++
>  lib/librte_ether/rte_ethdev.h | 23 +++++++++++++++++++++++
>  2 files changed, 55 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index 1257965..b52555b 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1576,6 +1576,38 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>  	dev_info->driver_name = dev->data->drv_name;
>  }
> 
> +int
> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> +			   uint32_t **p_ptypes)
> +{
> +	int i, j, ret;
> +	struct rte_eth_dev *dev;
> +	const uint32_t *all_ptypes;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> +	dev = &rte_eth_devices[port_id];
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> +	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
> +
> +	if (!all_ptypes)
> +		return 0;
> +
> +	for (i = 0, ret = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
> +		if (all_ptypes[i] & ptype_mask)
> +			ret++;
> +	if (ret == 0)
> +		return 0;
> +
> +	*p_ptypes = (uint32_t *)malloc(sizeof(uint32_t) * ret);
> +	if (*p_ptypes == NULL)
> +		return -ENOMEM;


I thought we all agreed to follow snprintf()-like logic and avoid any memory allocations inside that function.
So why malloc() again?
Konstantin

> +
> +	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
> +		if (all_ptypes[i] & ptype_mask)
> +			*p_ptypes[j++] = all_ptypes[i];
> +	return ret;
> +}
> +
>  void
>  rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
>  {
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16da821..341e2ff 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
>  				    struct rte_eth_dev_info *dev_info);
>  /**< @internal Get specific informations of an Ethernet device. */
> 
> +typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
> +/**< @internal Get ptype info of eth_rx_burst_t. */
> +
>  typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
>  				    uint16_t queue_id);
>  /**< @internal Start rx and tx of a queue of an Ethernet device. */
> @@ -1347,6 +1350,7 @@ struct eth_dev_ops {
>  	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
>  	/**< Configure per queue stat counter mapping. */
>  	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
>  	mtu_set_t                  mtu_set; /**< Set MTU. */
>  	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
>  	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> @@ -2268,6 +2272,25 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
>  void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
> 
>  /**
> + * Retrieve the packet type information of an Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param ptype_mask
> + *   A hint of what kind of packet type which the caller is interested in.
> + * @param p_ptypes
> + *   A pointer to store address of adequent packet types array. Caller to free.
> + * @return
> + *   - (>0) Number of ptypes supported. Need caller to free the array.
> + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> + *   - (-ENOMEM) if fail to malloc required memory to store ptypes.
> + *   - (-ENODEV) if *port_id* invalid.
> + */
> +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> +				      uint32_t ptype_mask,
> +				      uint32_t **p_ptypes);
> +
> +/**
>   * Retrieve the MTU of an Ethernet device.
>   *
>   * @param port_id
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v3 01/12] ethdev: add API to query packet type filling info
  2016-02-25 15:46     ` Ananyev, Konstantin
@ 2016-02-25 16:36       ` Tan, Jianfeng
  2016-02-25 17:16         ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-25 16:36 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 2/25/2016 11:46 PM, Ananyev, Konstantin wrote:
> Hi Jainfeng,
>
>> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
>> type can be filled by given pmd rx burst function.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   lib/librte_ether/rte_ethdev.c | 32 ++++++++++++++++++++++++++++++++
>>   lib/librte_ether/rte_ethdev.h | 23 +++++++++++++++++++++++
>>   2 files changed, 55 insertions(+)
>>
>> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
>> index 1257965..b52555b 100644
>> --- a/lib/librte_ether/rte_ethdev.c
>> +++ b/lib/librte_ether/rte_ethdev.c
>> @@ -1576,6 +1576,38 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>>   	dev_info->driver_name = dev->data->drv_name;
>>   }
>>
>> +int
>> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
>> +			   uint32_t **p_ptypes)
>> +{
>> +	int i, j, ret;
>> +	struct rte_eth_dev *dev;
>> +	const uint32_t *all_ptypes;
>> +
>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>> +	dev = &rte_eth_devices[port_id];
>> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
>> +	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
>> +
>> +	if (!all_ptypes)
>> +		return 0;
>> +
>> +	for (i = 0, ret = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
>> +		if (all_ptypes[i] & ptype_mask)
>> +			ret++;
>> +	if (ret == 0)
>> +		return 0;
>> +
>> +	*p_ptypes = (uint32_t *)malloc(sizeof(uint32_t) * ret);
>> +	if (*p_ptypes == NULL)
>> +		return -ENOMEM;
>
> I thought we all agreed to follow snprintf()-like logic and avoid any memory allocations inside that function.
> So why malloc() again?
> Konstantin
>

Sorry for the setback. I still have concerns that snprintf()-like needs 
to be called twice by an application to get the ptype info. So I write 
this implementation for you to comment.

So what's the reason why we should avoid memory allocations inside that 
function?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v3 01/12] ethdev: add API to query packet type filling info
  2016-02-25 16:36       ` Tan, Jianfeng
@ 2016-02-25 17:16         ` Ananyev, Konstantin
  2016-02-26  1:42           ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-25 17:16 UTC (permalink / raw)
  To: Tan, Jianfeng, dev



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Thursday, February 25, 2016 4:36 PM
> To: Ananyev, Konstantin; dev@dpdk.org
> Cc: Zhang, Helin; nelio.laranjeiro@6wind.com; adrien.mazarguil@6wind.com; rahul.lakkireddy@chelsio.com
> Subject: Re: [PATCH v3 01/12] ethdev: add API to query packet type filling info
> 
> Hi Konstantin,
> 
> On 2/25/2016 11:46 PM, Ananyev, Konstantin wrote:
> > Hi Jainfeng,
> >
> >> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
> >> type can be filled by given pmd rx burst function.
> >>
> >> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> >> ---
> >>   lib/librte_ether/rte_ethdev.c | 32 ++++++++++++++++++++++++++++++++
> >>   lib/librte_ether/rte_ethdev.h | 23 +++++++++++++++++++++++
> >>   2 files changed, 55 insertions(+)
> >>
> >> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> >> index 1257965..b52555b 100644
> >> --- a/lib/librte_ether/rte_ethdev.c
> >> +++ b/lib/librte_ether/rte_ethdev.c
> >> @@ -1576,6 +1576,38 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
> >>   	dev_info->driver_name = dev->data->drv_name;
> >>   }
> >>
> >> +int
> >> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> >> +			   uint32_t **p_ptypes)
> >> +{
> >> +	int i, j, ret;
> >> +	struct rte_eth_dev *dev;
> >> +	const uint32_t *all_ptypes;
> >> +
> >> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> >> +	dev = &rte_eth_devices[port_id];
> >> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
> >> +	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
> >> +
> >> +	if (!all_ptypes)
> >> +		return 0;
> >> +
> >> +	for (i = 0, ret = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
> >> +		if (all_ptypes[i] & ptype_mask)
> >> +			ret++;
> >> +	if (ret == 0)
> >> +		return 0;
> >> +
> >> +	*p_ptypes = (uint32_t *)malloc(sizeof(uint32_t) * ret);
> >> +	if (*p_ptypes == NULL)
> >> +		return -ENOMEM;
> >
> > I thought we all agreed to follow snprintf()-like logic and avoid any memory allocations inside that function.
> > So why malloc() again?
> > Konstantin
> >
> 
> Sorry for the setback. I still have concerns that snprintf()-like needs
> to be called twice by an application to get the ptype info. So I write
> this implementation for you to comment.
> 
> So what's the reason why we should avoid memory allocations inside that
> function?

By the same reason none of other rte_ethdev get_info() style functions
(rte_eth_dev_info_get, rte_eth_rx_queue_info_get, rte_eth_xstats_get,
rte_eth_dev_rss_reta_query, etc) allocate space themselves.
It is a good practice to let user to decide himself how/where to allocate/free a space for that date:
on a stack, inside a data segment (global variable), on heap (malloc),
at hugepages via rte_malloc, somewhere else.  

BTW, if you had concerns about that approach, why didn't you provide any arguments
when it was discussed/agreed?
Instead you came up a month later with same old approach that voids my and other
reviewers comments and even v2 of your own patch. 
Do you have any good reason for that?

Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v4 00/12] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (14 preceding siblings ...)
  2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
@ 2016-02-26  0:04 ` Jianfeng Tan
  2016-02-26  0:04   ` [PATCH v4 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                   ` (5 subsequent siblings)
  21 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:04 UTC (permalink / raw)
  To: dev

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it will not provide any ptype info.

v4:
  - Change how to use this API: to previously agreement reached in mail.

v3:
  - Change how to use this API: api to allocate mem for storing ptype
    array; and caller to free the mem.
  - Change how to return back ptypes from PMDs: return a pointer to
    corresponding static const array of supported ptypes, terminated
    by RTE_PTYPE_UNKNOWN.
  - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
  - Fix l3fwd memory leak when calling the API.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Jianfeng Tan (12):
  ethdev: add API to query packet type filling info
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation
  examples/l3fwd: add option to parse ptype

 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 drivers/net/cxgbe/cxgbe_ethdev.c        |  14 ++++
 drivers/net/e1000/igb_ethdev.c          |  30 ++++++++
 drivers/net/enic/enic_ethdev.c          |  17 +++++
 drivers/net/fm10k/fm10k_ethdev.c        |  50 +++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c          |   3 +
 drivers/net/fm10k/fm10k_rxtx_vec.c      |   3 +
 drivers/net/i40e/i40e_ethdev.c          |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c       |   1 +
 drivers/net/i40e/i40e_rxtx.c            |  46 +++++++++++-
 drivers/net/i40e/i40e_rxtx.h            |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 ++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h        |   2 +
 drivers/net/ixgbe/ixgbe_rxtx.c          |   4 +-
 drivers/net/mlx4/mlx4.c                 |  21 ++++++
 drivers/net/mlx5/mlx5.c                 |   1 +
 drivers/net/mlx5/mlx5.h                 |   1 +
 drivers/net/mlx5/mlx5_ethdev.c          |  20 +++++
 drivers/net/mlx5/mlx5_rxtx.c            |   2 +
 drivers/net/nfp/nfp_net.c               |  19 +++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ++++
 examples/l3fwd/main.c                   | 128 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.c           |  26 +++++++
 lib/librte_ether/rte_ethdev.h           |  26 +++++++
 24 files changed, 473 insertions(+), 3 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v4 01/12] ethdev: add API to query packet type filling info
  2016-02-26  0:04 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
@ 2016-02-26  0:04   ` Jianfeng Tan
  0 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:04 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
type can be filled by given pmd rx burst function.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 26 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..66dc7c5 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1576,6 +1576,32 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..16f32a0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get ptype info of eth_rx_burst_t. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2268,6 +2272,28 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the packet type information of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
+				      uint32_t ptype_mask,
+				      uint32_t *ptypes,
+				      int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 00/12] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (15 preceding siblings ...)
  2016-02-26  0:04 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
@ 2016-02-26  0:09 ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
                     ` (11 more replies)
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                   ` (4 subsequent siblings)
  21 siblings, 12 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it will not provide any ptype info.

v4:
  - Change how to use this API: to previously agreement reached in mail.

v3:
  - Change how to use this API: api to allocate mem for storing ptype
    array; and caller to free the mem.
  - Change how to return back ptypes from PMDs: return a pointer to
    corresponding static const array of supported ptypes, terminated
    by RTE_PTYPE_UNKNOWN.
  - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
  - Fix l3fwd memory leak when calling the API.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Jianfeng Tan (12):
  ethdev: add API to query packet type filling info
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation
  examples/l3fwd: add option to parse ptype

 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 drivers/net/cxgbe/cxgbe_ethdev.c        |  14 ++++
 drivers/net/e1000/igb_ethdev.c          |  30 ++++++++
 drivers/net/enic/enic_ethdev.c          |  17 +++++
 drivers/net/fm10k/fm10k_ethdev.c        |  50 +++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c          |   3 +
 drivers/net/fm10k/fm10k_rxtx_vec.c      |   3 +
 drivers/net/i40e/i40e_ethdev.c          |   1 +
 drivers/net/i40e/i40e_ethdev_vf.c       |   1 +
 drivers/net/i40e/i40e_rxtx.c            |  46 +++++++++++-
 drivers/net/i40e/i40e_rxtx.h            |   1 +
 drivers/net/ixgbe/ixgbe_ethdev.c        |  38 ++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h        |   2 +
 drivers/net/ixgbe/ixgbe_rxtx.c          |   4 +-
 drivers/net/mlx4/mlx4.c                 |  21 ++++++
 drivers/net/mlx5/mlx5.c                 |   1 +
 drivers/net/mlx5/mlx5.h                 |   1 +
 drivers/net/mlx5/mlx5_ethdev.c          |  20 +++++
 drivers/net/mlx5/mlx5_rxtx.c            |   2 +
 drivers/net/nfp/nfp_net.c               |  19 +++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c    |  16 ++++
 examples/l3fwd/main.c                   | 128 ++++++++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.c           |  26 +++++++
 lib/librte_ether/rte_ethdev.h           |  26 +++++++
 24 files changed, 473 insertions(+), 3 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v4 01/12] ethdev: add API to query packet type filling info
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
                     ` (10 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
type can be filled by given pmd rx burst function.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 26 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..66dc7c5 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1576,6 +1576,32 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..16f32a0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get ptype info of eth_rx_burst_t. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2268,6 +2272,28 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the packet type information of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
+				      uint32_t ptype_mask,
+				      uint32_t *ptypes,
+				      int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 02/12] pmd/cxgbe: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 03/12] pmd/e1000: " Jianfeng Tan
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..33bd815 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,19 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static const uint32_t *cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +790,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_ptype_info_get	= cxgbe_dev_ptype_info_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 03/12] pmd/e1000: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 04/12] pmd/enic: " Jianfeng Tan
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4ed5e95..b3a3ee6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -103,6 +103,7 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static const uint32_t *eth_igb_ptype_info_get(struct rte_eth_dev *dev);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -319,6 +320,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -376,6 +378,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1910,6 +1913,33 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static const uint32_t *
+eth_igb_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+	    dev->rx_pkt_burst == eth_igb_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 04/12] pmd/enic: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 03/12] pmd/e1000: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 05/12] pmd/fm10k: " Jianfeng Tan
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2a88043..fbeab6f 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -54,6 +54,9 @@
 #define ENICPMD_FUNC_TRACE() (void)0
 #endif
 
+static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+				  uint16_t nb_pkts);
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -431,6 +434,19 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
+static const uint32_t *enicpmd_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == enicpmd_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -566,6 +582,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_ptype_info_get   = enicpmd_dev_ptype_info_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 04/12] pmd/enic: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-03-02 20:11     ` Chen, Jing D
  2016-02-26  0:09   ` [PATCH v4 06/12] pmd/i40e: " Jianfeng Tan
                     ` (6 subsequent siblings)
  11 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..429cbdd 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		static uint32_t ptypes[] = {
+			/* refers to rx_desc_to_ol_flags() */
+			RTE_PTYPE_L2_ETHER,
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		static uint32_t ptypes_vec[] = {
+			/* refers to fm10k_desc_to_pktype_v() */
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_TUNNEL_GENEVE,
+			RTE_PTYPE_TUNNEL_NVGRE,
+			RTE_PTYPE_TUNNEL_VXLAN,
+			RTE_PTYPE_TUNNEL_GRE,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes_vec;
+	}
+
+	return NULL;
+}
+#else
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev __rte_unused)
+{
+	return NULL;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2423,6 +2472,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_ptype_info_get	= fm10k_dev_ptype_info_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index e958865..cbe0111 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,9 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 2a57eef..f347641 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -109,6 +109,9 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get().
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 06/12] pmd/i40e: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 05/12] pmd/fm10k: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 07/12] pmd/ixgbe: " Jianfeng Tan
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 46 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..81849fa 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -439,6 +439,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_ptype_info_get           = i40e_dev_ptype_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..afd436e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -196,6 +196,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_ptype_info_get   = i40e_dev_ptype_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 40cffc1..1a952df 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -194,7 +194,10 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/* For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2093,6 +2096,47 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 	return 0;
 }
 
+const uint32_t *
+i40e_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_TIMESYNC,
+		RTE_PTYPE_L2_ETHER_LLDP,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_L4_NONFRAG,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L2_ETHER_VLAN,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_ICMP,
+		RTE_PTYPE_INNER_L4_NONFRAG,
+		RTE_PTYPE_INNER_L4_SCTP,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+	    dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+	    dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..3a59d81 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,7 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+const uint32_t *i40e_dev_ptype_info_get(struct rte_eth_dev *dev);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 07/12] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 06/12] pmd/i40e: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 08/12] pmd/mlx4: " Jianfeng Tan
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  4 +++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3e6fe86..605d958 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static const uint32_t *ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static const uint32_t *
+ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* For non-vec functions,
+		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+		 * for vec functions,
+		 * refers to _recv_raw_pkts_vec().
+		 */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
+	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec)
+		return ptypes;
+	return NULL;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index d26771a..b07d3da 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+				    uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index e95e6b7..17851cc 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -899,6 +899,8 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+
+/* @note: fix ixgbe_dev_ptype_info_get() if any change here. */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1247,7 +1249,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 08/12] pmd/mlx4: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 07/12] pmd/ixgbe: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 09/12] pmd/mlx5: " Jianfeng Tan
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ee00151..85fdebf 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2835,6 +2835,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4267,6 +4269,24 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static uint32_t *
+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == mlx4_rx_burst ||
+	    dev->rx_pkt_burst == mlx4_rx_burst_sp)
+		return ptypes;
+	return NULL;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -4988,6 +5008,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 09/12] pmd/mlx5: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 08/12] pmd/mlx4: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  8:26     ` Adrien Mazarguil
  2016-02-26  0:09   ` [PATCH v4 10/12] pmd/nfp: " Jianfeng Tan
                     ` (2 subsequent siblings)
  11 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c        |  2 +-
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  1 +
 drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 5 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 85fdebf..58f4e1a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -4269,7 +4269,7 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
-static uint32_t *
+static const uint32_t *
 mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
 {
 	static const uint32_t ptypes[] = {
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..e18b1e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -153,6 +153,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_ptype_info_get = mlx5_dev_ptype_info_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b84d31d..196435d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -156,6 +156,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+const uint32_t *mlx5_dev_ptype_info_get(struct rte_eth_dev *dev);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..406f8dc 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -526,6 +526,26 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+const uint32_t *
+mlx5_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+
+	};
+
+	if (dev->rx_pkt_burst == mlx5_rx_burst ||
+	    dev->rx_pkt_burst == mlx5_rx_burst_sp)
+		return ptypes;
+	return NULL;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index fa5e648..79bdf8d 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -603,6 +603,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 10/12] pmd/nfp: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 09/12] pmd/mlx5: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 11/12] pmd/vmxnet3: " Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/nfp/nfp_net.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index fd4dd39..5894a9d 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1073,6 +1073,24 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 }
 
+static const uint32_t *
+nfp_net_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to nfp_net_set_hash() */
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_MASK,
+		RTE_PTYPE_UNKNOWN
+	};
+
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts)
+		return ptypes;
+	return num;
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2292,6 +2310,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_ptype_info_get	= nfp_net_ptype_info_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 11/12] pmd/vmxnet3: add dev_ptype_info_get implementation
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 10/12] pmd/nfp: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26  0:09   ` [PATCH v4 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..ac120a1 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,7 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static const uint32_t *vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -118,6 +119,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.link_update          = vmxnet3_dev_link_update,
 	.stats_get            = vmxnet3_dev_stats_get,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_ptype_info_get   = vmxnet3_dev_ptype_info_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -718,6 +720,20 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, struct rte_
 	};
 }
 
+static const uint32_t *
+vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 12/12] examples/l3fwd: add option to parse ptype
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
                     ` (10 preceding siblings ...)
  2016-02-26  0:09   ` [PATCH v4 11/12] pmd/vmxnet3: " Jianfeng Tan
@ 2016-02-26  0:09   ` Jianfeng Tan
  2016-02-26 13:14     ` Ananyev, Konstantin
  11 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  0:09 UTC (permalink / raw)
  To: dev

As a example to use ptype info, l3fwd needs firstly to use
rte_eth_dev_get_ptype_info() API to check if device and/or PMD driver will
parse and fill the needed packet type; if not, use the newly added option,
--parse-ptype, to analyze it in the callback softly.

Under the mode of EXACT_MATCH, ip packets with extensions or ip packets
which are neither tcp nor udp cannot work well because it needs the 5
tuples to caculate hash.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 examples/l3fwd/main.c                   | 128 ++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst
index 4ce734b..e0c22e3 100644
--- a/doc/guides/sample_app_ug/l3_forward.rst
+++ b/doc/guides/sample_app_ug/l3_forward.rst
@@ -93,7 +93,7 @@ The application has a number of command line options:
 
 .. code-block:: console
 
-    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6]
+    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6] [--parse-ptype]
 
 where,
 
@@ -114,6 +114,8 @@ where,
 
 *   --ipv6: optional, set it if running ipv6 packets
 
+*   --parse-ptype: optional, set it if use software way to analyze packet type
+
 For example, consider a dual processor socket platform where cores 0-7 and 16-23 appear on socket 0, while cores 8-15 and 24-31 appear on socket 1.
 Let's say that the programmer wants to use memory from both NUMA nodes, the platform has only two ports, one connected to each NUMA node,
 and the programmer wants to use two cores from each processor socket to do the packet processing.
@@ -334,6 +336,8 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below:
 
 The simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function.
 
+Known issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well with this mode.
+
 Packet Forwarding for LPM-based Lookups
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 410f72d..738b94a 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -178,6 +178,8 @@ static __m128i val_eth[RTE_MAX_ETHPORTS];
 static uint32_t enabled_port_mask = 0;
 static int promiscuous_on = 0; /**< Ports set in promiscuous mode off by default. */
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 #if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
 static int ipv6 = 0; /**< ipv6 is false by default. */
@@ -2029,6 +2031,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /* Parse the argument given in the command line of the application */
 static int
@@ -2045,6 +2048,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -2132,6 +2136,13 @@ parse_args(int argc, char **argv)
 				}
 			}
 #endif
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -2580,6 +2591,111 @@ signal_handler(int signum)
 	}
 }
 
+static int
+check_packet_type_ok(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+	
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
+					 ptypes, ret);
+	/* It is not a perfect pre-check, i.e., IP packets with extension and
+	 * IP packets which are not TCP/UDP, can pass this check, but cannot
+	 * work well at the mode of EXACT_MATCH.
+	 */
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+}
+static inline void
+parse_packet_type(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = 0;
+	uint16_t ethertype;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+		{
+			int hdr_len;
+			struct ipv4_hdr *hdr;
+
+			hdr = (struct ipv4_hdr *)((uint8_t *)eth_hdr +
+						sizeof(struct ether_hdr));
+			hdr_len = (hdr->version_ihl & IPV4_HDR_IHL_MASK)
+				* IPV4_IHL_MULTIPLIER;
+			/* Exact match uses 5 tuples to calculate hash, so
+			 * adequate packets should not only have no ip header
+			 * extension but also be TCP/UDP packet
+			 */
+			if (hdr_len == sizeof(struct ipv4_hdr) &&
+			    (hdr->next_proto_id == 6 ||
+			     hdr->next_proto_id == 17))
+				packet_type |= RTE_PTYPE_L3_IPV4;
+		}
+#elif (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+#endif
+		break;
+	case ETHER_TYPE_IPv6:
+#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
+		{
+			struct ipv6_hdr *hdr;
+
+			hdr = (struct ipv6_hdr *)((uint8_t *)eth_hdr +
+						  sizeof(struct ether_hdr));
+			if (hdr->proto == 6 || hdr->proto == 17)
+				packet_type |= RTE_PTYPE_L3_IPV4;
+		}
+
+#elif (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+#endif
+		break;
+	default:
+		break;
+	}
+
+	m->packet_type |= packet_type;
+}
+
+static uint16_t
+cb_parse_packet_type(uint8_t port __rte_unused,
+		     uint16_t queue __rte_unused,
+		     struct rte_mbuf *pkts[],
+		     uint16_t nb_pkts,
+		     uint16_t max_pkts __rte_unused,
+		     void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		parse_packet_type(pkts[i]);
+}
+
 int
 main(int argc, char **argv)
 {
@@ -2697,6 +2813,11 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE, "rte_eth_tx_queue_setup: err=%d, "
 					"port=%d\n", ret, portid);
 
+			if (!check_packet_type_ok(portid) && !parse_ptype)
+				rte_exit(EXIT_FAILURE,
+					 "port %d cannot parse packet type, please add --%s\n",
+					 portid, CMD_LINE_OPT_PARSE_PTYPE);
+
 			qconf = &lcore_conf[lcore_id];
 			qconf->tx_queue_id[portid] = queueid;
 			queueid++;
@@ -2730,6 +2851,13 @@ main(int argc, char **argv)
 			if (ret < 0)
 				rte_exit(EXIT_FAILURE, "rte_eth_rx_queue_setup: err=%d,"
 						"port=%d\n", ret, portid);
+			if (parse_ptype &&
+			    !rte_eth_add_rx_callback(portid, queueid,
+						     cb_parse_packet_type,
+						     NULL))
+				rte_exit(EXIT_FAILURE,
+					 "Failed to add rx callback: port=%d\n",
+					 portid);
 		}
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v3 01/12] ethdev: add API to query packet type filling info
  2016-02-25 17:16         ` Ananyev, Konstantin
@ 2016-02-26  1:42           ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-26  1:42 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 2/26/2016 1:16 AM, Ananyev, Konstantin wrote:
>
>> -----Original Message-----
>> From: Tan, Jianfeng
>> Sent: Thursday, February 25, 2016 4:36 PM
>> To: Ananyev, Konstantin; dev@dpdk.org
>> Cc: Zhang, Helin; nelio.laranjeiro@6wind.com; adrien.mazarguil@6wind.com; rahul.lakkireddy@chelsio.com
>> Subject: Re: [PATCH v3 01/12] ethdev: add API to query packet type filling info
>>
>> Hi Konstantin,
>>
>> On 2/25/2016 11:46 PM, Ananyev, Konstantin wrote:
>>> Hi Jainfeng,
>>>
>>>> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
>>>> type can be filled by given pmd rx burst function.
>>>>
>>>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>>>> ---
>>>>    lib/librte_ether/rte_ethdev.c | 32 ++++++++++++++++++++++++++++++++
>>>>    lib/librte_ether/rte_ethdev.h | 23 +++++++++++++++++++++++
>>>>    2 files changed, 55 insertions(+)
>>>>
>>>> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
>>>> index 1257965..b52555b 100644
>>>> --- a/lib/librte_ether/rte_ethdev.c
>>>> +++ b/lib/librte_ether/rte_ethdev.c
>>>> @@ -1576,6 +1576,38 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
>>>>    	dev_info->driver_name = dev->data->drv_name;
>>>>    }
>>>>
>>>> +int
>>>> +rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
>>>> +			   uint32_t **p_ptypes)
>>>> +{
>>>> +	int i, j, ret;
>>>> +	struct rte_eth_dev *dev;
>>>> +	const uint32_t *all_ptypes;
>>>> +
>>>> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>>>> +	dev = &rte_eth_devices[port_id];
>>>> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
>>>> +	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
>>>> +
>>>> +	if (!all_ptypes)
>>>> +		return 0;
>>>> +
>>>> +	for (i = 0, ret = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
>>>> +		if (all_ptypes[i] & ptype_mask)
>>>> +			ret++;
>>>> +	if (ret == 0)
>>>> +		return 0;
>>>> +
>>>> +	*p_ptypes = (uint32_t *)malloc(sizeof(uint32_t) * ret);
>>>> +	if (*p_ptypes == NULL)
>>>> +		return -ENOMEM;
>>> I thought we all agreed to follow snprintf()-like logic and avoid any memory allocations inside that function.
>>> So why malloc() again?
>>> Konstantin
>>>
>> Sorry for the setback. I still have concerns that snprintf()-like needs
>> to be called twice by an application to get the ptype info. So I write
>> this implementation for you to comment.
>>
>> So what's the reason why we should avoid memory allocations inside that
>> function?
> By the same reason none of other rte_ethdev get_info() style functions
> (rte_eth_dev_info_get, rte_eth_rx_queue_info_get, rte_eth_xstats_get,
> rte_eth_dev_rss_reta_query, etc) allocate space themselves.
> It is a good practice to let user to decide himself how/where to allocate/free a space for that date:
> on a stack, inside a data segment (global variable), on heap (malloc),
> at hugepages via rte_malloc, somewhere else.
>
> BTW, if you had concerns about that approach, why didn't you provide any arguments
> when it was discussed/agreed?
> Instead you came up a month later with same old approach that voids my and other
> reviewers comments and even v2 of your own patch.
> Do you have any good reason for that?
>
> Konstantin
>

That makes sense for me now. Thanks for explanation. Will send out v4 as 
previous discussion result.

I'd like to say sorry for this delayed and wrong way to raise concern. 
Sorry for waste of your time.

Appreciate your comments on this.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v5 00/11] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (16 preceding siblings ...)
  2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
@ 2016-02-26  7:34 ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
                     ` (11 more replies)
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                   ` (3 subsequent siblings)
  21 siblings, 12 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it will not provide any ptype info.

v5:
  - Exclude l3fwd change from this series, as a separated one.
  - Fix malposition of mlx4 code in mlx5 commit introduced in v4.

v4:
  - Change how to use this API: to previously agreement reached in mail.

v3:
  - Change how to use this API: api to allocate mem for storing ptype
    array; and caller to free the mem.
  - Change how to return back ptypes from PMDs: return a pointer to
    corresponding static const array of supported ptypes, terminated
    by RTE_PTYPE_UNKNOWN.
  - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
  - Fix l3fwd memory leak when calling the API.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Jianfeng Tan (11):
  ethdev: add API to query packet type filling info
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation

 drivers/net/cxgbe/cxgbe_ethdev.c     | 14 ++++++++++
 drivers/net/e1000/igb_ethdev.c       | 30 ++++++++++++++++++++++
 drivers/net/enic/enic_ethdev.c       | 17 ++++++++++++
 drivers/net/fm10k/fm10k_ethdev.c     | 50 ++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c       |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c   |  3 +++
 drivers/net/i40e/i40e_ethdev.c       |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c    |  1 +
 drivers/net/i40e/i40e_rxtx.c         | 46 ++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h         |  1 +
 drivers/net/ixgbe/ixgbe_ethdev.c     | 38 +++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h     |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c       |  4 ++-
 drivers/net/mlx4/mlx4.c              | 21 +++++++++++++++
 drivers/net/mlx5/mlx5.c              |  1 +
 drivers/net/mlx5/mlx5.h              |  1 +
 drivers/net/mlx5/mlx5_ethdev.c       | 20 +++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c         |  2 ++
 drivers/net/nfp/nfp_net.c            | 19 ++++++++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 ++++++++++++
 lib/librte_ether/rte_ethdev.c        | 26 +++++++++++++++++++
 lib/librte_ether/rte_ethdev.h        | 26 +++++++++++++++++++
 22 files changed, 340 insertions(+), 2 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v5 01/11] ethdev: add API to query packet type filling info
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-29 11:34     ` Panu Matilainen
  2016-02-26  7:34   ` [PATCH v5 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
                     ` (10 subsequent siblings)
  11 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
type can be filled by given pmd rx burst function.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 26 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
 2 files changed, 52 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..66dc7c5 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1576,6 +1576,32 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..16f32a0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get ptype info of eth_rx_burst_t. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2268,6 +2272,28 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the packet type information of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
+				      uint32_t ptype_mask,
+				      uint32_t *ptypes,
+				      int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 02/11] pmd/cxgbe: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 03/11] pmd/e1000: " Jianfeng Tan
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..33bd815 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,19 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static const uint32_t *cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +790,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_ptype_info_get	= cxgbe_dev_ptype_info_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 03/11] pmd/e1000: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 04/11] pmd/enic: " Jianfeng Tan
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4ed5e95..b3a3ee6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -103,6 +103,7 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static const uint32_t *eth_igb_ptype_info_get(struct rte_eth_dev *dev);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -319,6 +320,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -376,6 +378,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1910,6 +1913,33 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static const uint32_t *
+eth_igb_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+	    dev->rx_pkt_burst == eth_igb_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 04/11] pmd/enic: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 03/11] pmd/e1000: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 05/11] pmd/fm10k: " Jianfeng Tan
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2a88043..fbeab6f 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -54,6 +54,9 @@
 #define ENICPMD_FUNC_TRACE() (void)0
 #endif
 
+static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+				  uint16_t nb_pkts);
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -431,6 +434,19 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
+static const uint32_t *enicpmd_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == enicpmd_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -566,6 +582,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_ptype_info_get   = enicpmd_dev_ptype_info_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 05/11] pmd/fm10k: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 04/11] pmd/enic: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 06/11] pmd/i40e: " Jianfeng Tan
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..429cbdd 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		static uint32_t ptypes[] = {
+			/* refers to rx_desc_to_ol_flags() */
+			RTE_PTYPE_L2_ETHER,
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		static uint32_t ptypes_vec[] = {
+			/* refers to fm10k_desc_to_pktype_v() */
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_TUNNEL_GENEVE,
+			RTE_PTYPE_TUNNEL_NVGRE,
+			RTE_PTYPE_TUNNEL_VXLAN,
+			RTE_PTYPE_TUNNEL_GRE,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes_vec;
+	}
+
+	return NULL;
+}
+#else
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev __rte_unused)
+{
+	return NULL;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2423,6 +2472,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_ptype_info_get	= fm10k_dev_ptype_info_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index e958865..cbe0111 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,9 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 2a57eef..f347641 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -109,6 +109,9 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get().
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 06/11] pmd/i40e: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 05/11] pmd/fm10k: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 07/11] pmd/ixgbe: " Jianfeng Tan
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 46 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..81849fa 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -439,6 +439,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_ptype_info_get           = i40e_dev_ptype_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..afd436e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -196,6 +196,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_ptype_info_get   = i40e_dev_ptype_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 40cffc1..1a952df 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -194,7 +194,10 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/* For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2093,6 +2096,47 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 	return 0;
 }
 
+const uint32_t *
+i40e_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_TIMESYNC,
+		RTE_PTYPE_L2_ETHER_LLDP,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_L4_NONFRAG,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L2_ETHER_VLAN,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_ICMP,
+		RTE_PTYPE_INNER_L4_NONFRAG,
+		RTE_PTYPE_INNER_L4_SCTP,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+	    dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+	    dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..3a59d81 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,7 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+const uint32_t *i40e_dev_ptype_info_get(struct rte_eth_dev *dev);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 07/11] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 06/11] pmd/i40e: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 08/11] pmd/mlx4: " Jianfeng Tan
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  4 +++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3e6fe86..605d958 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static const uint32_t *ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static const uint32_t *
+ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* For non-vec functions,
+		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+		 * for vec functions,
+		 * refers to _recv_raw_pkts_vec().
+		 */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
+	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec)
+		return ptypes;
+	return NULL;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index d26771a..b07d3da 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+				    uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index e95e6b7..17851cc 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -899,6 +899,8 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+
+/* @note: fix ixgbe_dev_ptype_info_get() if any change here. */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1247,7 +1249,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 08/11] pmd/mlx4: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 07/11] pmd/ixgbe: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 09/11] pmd/mlx5: " Jianfeng Tan
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ee00151..58f4e1a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2835,6 +2835,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4267,6 +4269,24 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static const uint32_t *
+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == mlx4_rx_burst ||
+	    dev->rx_pkt_burst == mlx4_rx_burst_sp)
+		return ptypes;
+	return NULL;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -4988,6 +5008,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 09/11] pmd/mlx5: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 08/11] pmd/mlx4: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 10/11] pmd/nfp: " Jianfeng Tan
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  1 +
 drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 4 files changed, 24 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..e18b1e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -153,6 +153,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_ptype_info_get = mlx5_dev_ptype_info_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b84d31d..196435d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -156,6 +156,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+const uint32_t *mlx5_dev_ptype_info_get(struct rte_eth_dev *dev);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..406f8dc 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -526,6 +526,26 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+const uint32_t *
+mlx5_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+
+	};
+
+	if (dev->rx_pkt_burst == mlx5_rx_burst ||
+	    dev->rx_pkt_burst == mlx5_rx_burst_sp)
+		return ptypes;
+	return NULL;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index fa5e648..79bdf8d 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -603,6 +603,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 10/11] pmd/nfp: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 09/11] pmd/mlx5: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-26  7:34   ` [PATCH v5 11/11] pmd/vmxnet3: " Jianfeng Tan
  2016-02-29 16:54   ` [PATCH v5 00/11] Add API to get packet type info Ananyev, Konstantin
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/nfp/nfp_net.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index fd4dd39..5894a9d 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1073,6 +1073,24 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 }
 
+static const uint32_t *
+nfp_net_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to nfp_net_set_hash() */
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_MASK,
+		RTE_PTYPE_UNKNOWN
+	};
+
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts)
+		return ptypes;
+	return num;
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2292,6 +2310,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_ptype_info_get	= nfp_net_ptype_info_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v5 11/11] pmd/vmxnet3: add dev_ptype_info_get implementation
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 10/11] pmd/nfp: " Jianfeng Tan
@ 2016-02-26  7:34   ` Jianfeng Tan
  2016-02-29 16:54   ` [PATCH v5 00/11] Add API to get packet type info Ananyev, Konstantin
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-26  7:34 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..ac120a1 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,7 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static const uint32_t *vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -118,6 +119,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.link_update          = vmxnet3_dev_link_update,
 	.stats_get            = vmxnet3_dev_stats_get,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_ptype_info_get   = vmxnet3_dev_ptype_info_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -718,6 +720,20 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, struct rte_
 	};
 }
 
+static const uint32_t *
+vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 09/12] pmd/mlx5: add dev_ptype_info_get implementation
  2016-02-26  0:09   ` [PATCH v4 09/12] pmd/mlx5: " Jianfeng Tan
@ 2016-02-26  8:26     ` Adrien Mazarguil
  2016-02-26  8:36       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Adrien Mazarguil @ 2016-02-26  8:26 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

Hi Jianfeng,

On Fri, Feb 26, 2016 at 08:09:28AM +0800, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  drivers/net/mlx4/mlx4.c        |  2 +-
>  drivers/net/mlx5/mlx5.c        |  1 +
>  drivers/net/mlx5/mlx5.h        |  1 +
>  drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
>  drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
>  5 files changed, 25 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index 85fdebf..58f4e1a 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -4269,7 +4269,7 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>  	priv_unlock(priv);
>  }
>  
> -static uint32_t *
> +static const uint32_t *
>  mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
>  {
>  	static const uint32_t ptypes[] = {

I'm probably nitpicking here but this change should be merged in the mlx4
patch. Otherwise both mlx4 and mlx5 patches look fine to me.

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 09/12] pmd/mlx5: add dev_ptype_info_get implementation
  2016-02-26  8:26     ` Adrien Mazarguil
@ 2016-02-26  8:36       ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-26  8:36 UTC (permalink / raw)
  To: dev, helin.zhang, konstantin.ananyev, nelio.laranjeiro, rahul.lakkireddy

Hi,

On 2/26/2016 4:26 PM, Adrien Mazarguil wrote:
> Hi Jianfeng,
>
> On Fri, Feb 26, 2016 at 08:09:28AM +0800, Jianfeng Tan wrote:
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   drivers/net/mlx4/mlx4.c        |  2 +-
>>   drivers/net/mlx5/mlx5.c        |  1 +
>>   drivers/net/mlx5/mlx5.h        |  1 +
>>   drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
>>   drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
>>   5 files changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
>> index 85fdebf..58f4e1a 100644
>> --- a/drivers/net/mlx4/mlx4.c
>> +++ b/drivers/net/mlx4/mlx4.c
>> @@ -4269,7 +4269,7 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
>>   	priv_unlock(priv);
>>   }
>>   
>> -static uint32_t *
>> +static const uint32_t *
>>   mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
>>   {
>>   	static const uint32_t ptypes[] = {
> I'm probably nitpicking here but this change should be merged in the mlx4
> patch. Otherwise both mlx4 and mlx5 patches look fine to me.
>

Oops, nice catch. It's should be in mlx4 commit. I'll fix it.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 12/12] examples/l3fwd: add option to parse ptype
  2016-02-26  0:09   ` [PATCH v4 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
@ 2016-02-26 13:14     ` Ananyev, Konstantin
  2016-02-26 14:21       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-26 13:14 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi Jianfeng,

> 
> +static int
> +check_packet_type_ok(int portid)
> +{
> +	int i, ret;
> +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> +
> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
> +	if (ret <= 0)
> +		return 0;
> +
> +	uint32_t ptypes[ret];
> +
> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
> +					 ptypes, ret);
> +	/* It is not a perfect pre-check, i.e., IP packets with extension and
> +	 * IP packets which are not TCP/UDP, can pass this check, but cannot
> +	 * work well at the mode of EXACT_MATCH.
> +	 */
> +	for (i = 0; i < ret; ++i) {
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> +			ptype_l3_ipv4 = 1;
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> +			ptype_l3_ipv6 = 1;
> +	}
> +
> +	if (ptype_l3_ipv4 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> +
> +	if (ptype_l3_ipv6 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> +
> +	if (ptype_l3_ipv4 && ptype_l3_ipv6)
> +		return 1;
> +
> +	return 0;
> +}
> +static inline void
> +parse_packet_type(struct rte_mbuf *m)
> +{
> +	struct ether_hdr *eth_hdr;
> +	uint32_t packet_type = 0;
> +	uint16_t ethertype;
> +
> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> +	switch (ethertype) {
> +	case ETHER_TYPE_IPv4:
> +#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
> +		{
> +			int hdr_len;
> +			struct ipv4_hdr *hdr;
> +
> +			hdr = (struct ipv4_hdr *)((uint8_t *)eth_hdr +
> +						sizeof(struct ether_hdr));
> +			hdr_len = (hdr->version_ihl & IPV4_HDR_IHL_MASK)
> +				* IPV4_IHL_MULTIPLIER;
> +			/* Exact match uses 5 tuples to calculate hash, so
> +			 * adequate packets should not only have no ip header
> +			 * extension but also be TCP/UDP packet
> +			 */
> +			if (hdr_len == sizeof(struct ipv4_hdr) &&
> +			    (hdr->next_proto_id == 6 ||
> +			     hdr->next_proto_id == 17))

Use IPPORTO_UDP, IPPORTO_TCP instead of hardcoded values.

> +				packet_type |= RTE_PTYPE_L3_IPV4;
> +		}

Actually it is a good point:
for EM case should l3fwd process only TCP/UDP packets?
If yes, then it needs to check not only L3, but also L4 type too
Which means that for EM and LPM check_packet_type_ok() should also be different.
Or we can leave it as it is - in that case EM even for non UDP/TCP packet would still
do route  lookup using first 4B of L3 payload.

If you choose first approach, then there is another thing to consider -
there are 2 patches in flight for l3fwd:
http://dpdk.org/dev/patchwork/patch/10800/
http://dpdk.org/dev/patchwork/patch/10782/

Which makes LPM/EM choice for l3fwd a runtime decision.
So  APP_LOOKUP_METHOD macro would not be available after it.
Probably need to take that into account for your changes.
Might be exclude l3fwd from this patch series, then rebase it
on these patches and submit as a separate one?

> +#elif (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> +#endif
> +		break;
> +	case ETHER_TYPE_IPv6:
> +#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
> +		{
> +			struct ipv6_hdr *hdr;
> +
> +			hdr = (struct ipv6_hdr *)((uint8_t *)eth_hdr +
> +						  sizeof(struct ether_hdr));
> +			if (hdr->proto == 6 || hdr->proto == 17)
> +				packet_type |= RTE_PTYPE_L3_IPV4;

s/ RTE_PTYPE_L3_IPV4/RTE_PTYPE_L3_IPV6/
?

Apart from that the series looks good to me.
Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 12/12] examples/l3fwd: add option to parse ptype
  2016-02-26 13:14     ` Ananyev, Konstantin
@ 2016-02-26 14:21       ` Tan, Jianfeng
  2016-02-26 14:27         ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-26 14:21 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 2/26/2016 9:14 PM, Ananyev, Konstantin wrote:
> Hi Jianfeng,
>
>> +static int
...
>> +			if (hdr_len == sizeof(struct ipv4_hdr) &&
>> +			    (hdr->next_proto_id == 6 ||
>> +			     hdr->next_proto_id == 17))
> Use IPPORTO_UDP, IPPORTO_TCP instead of hardcoded values.

Yes, will fix it.

>> +				packet_type |= RTE_PTYPE_L3_IPV4;
>> +		}
> Actually it is a good point:
> for EM case should l3fwd process only TCP/UDP packets?
> If yes, then it needs to check not only L3, but also L4 type too
> Which means that for EM and LPM check_packet_type_ok() should also be different.
> Or we can leave it as it is - in that case EM even for non UDP/TCP packet would still
> do route  lookup using first 4B of L3 payload.

I'd like to follow the first approach, (if nobody strongly objects to 
it), because it's EM's real intention to use 5 tuples.

> If you choose first approach, then there is another thing to consider -
> there are 2 patches in flight for l3fwd:
> http://dpdk.org/dev/patchwork/patch/10800/
> http://dpdk.org/dev/patchwork/patch/10782/
>
> Which makes LPM/EM choice for l3fwd a runtime decision.
> So  APP_LOOKUP_METHOD macro would not be available after it.
> Probably need to take that into account for your changes.
> Might be exclude l3fwd from this patch series, then rebase it
> on these patches and submit as a separate one?

Thanks for reminding me of this. And that sounds a good idea to me. This 
commit will be excluded and submitted as a separate one.

>> +#elif (APP_LOOKUP_METHOD == APP_LOOKUP_LPM)
>> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
>> +#endif
>> +		break;
>> +	case ETHER_TYPE_IPv6:
>> +#if (APP_LOOKUP_METHOD == APP_LOOKUP_EXACT_MATCH)
>> +		{
>> +			struct ipv6_hdr *hdr;
>> +
>> +			hdr = (struct ipv6_hdr *)((uint8_t *)eth_hdr +
>> +						  sizeof(struct ether_hdr));
>> +			if (hdr->proto == 6 || hdr->proto == 17)
>> +				packet_type |= RTE_PTYPE_L3_IPV4;
> s/ RTE_PTYPE_L3_IPV4/RTE_PTYPE_L3_IPV6/
> ?

Oops, nice catch. Will fix it.

Thanks,
Jianfeng

> Apart from that the series looks good to me.
> Konstantin
>

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 12/12] examples/l3fwd: add option to parse ptype
  2016-02-26 14:21       ` Tan, Jianfeng
@ 2016-02-26 14:27         ` Ananyev, Konstantin
  0 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-26 14:27 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

> > Actually it is a good point:
> > for EM case should l3fwd process only TCP/UDP packets?
> > If yes, then it needs to check not only L3, but also L4 type too
> > Which means that for EM and LPM check_packet_type_ok() should also be different.
> > Or we can leave it as it is - in that case EM even for non UDP/TCP packet would still
> > do route  lookup using first 4B of L3 payload.
> 
> I'd like to follow the first approach, (if nobody strongly objects to
> it), because it's EM's real intention to use 5 tuples.

Ok with me.
Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v5 01/11] ethdev: add API to query packet type filling info
  2016-02-26  7:34   ` [PATCH v5 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-02-29 11:34     ` Panu Matilainen
  2016-02-29 16:41       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Panu Matilainen @ 2016-02-29 11:34 UTC (permalink / raw)
  To: dev, Jianfeng Tan

On 02/26/2016 09:34 AM, Jianfeng Tan wrote:
> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
> type can be filled by given pmd rx burst function.
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>   lib/librte_ether/rte_ethdev.c | 26 ++++++++++++++++++++++++++
>   lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
>   2 files changed, 52 insertions(+)
>
[...]
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16da821..16f32a0 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
>   				    struct rte_eth_dev_info *dev_info);
>   /**< @internal Get specific informations of an Ethernet device. */
>
> +typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
> +/**< @internal Get ptype info of eth_rx_burst_t. */
> +
>   typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
>   				    uint16_t queue_id);
>   /**< @internal Start rx and tx of a queue of an Ethernet device. */
> @@ -1347,6 +1350,7 @@ struct eth_dev_ops {
>   	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
>   	/**< Configure per queue stat counter mapping. */
>   	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
> +	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
>   	mtu_set_t                  mtu_set; /**< Set MTU. */
>   	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
>   	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
> @@ -2268,6 +2272,28 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);

Technically this is an ABI break but its marked internal and I guess it 
falls into the "drivers only" territory similar to what was discussed in 
this thead: http://dpdk.org/ml/archives/dev/2016-January/032348.html so 
its probably ok.

>   void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
>
>   /**
> + * Retrieve the packet type information of an Ethernet device.
> + *
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param ptype_mask
> + *   A hint of what kind of packet type which the caller is interested in.
> + * @param ptypes
> + *   An array pointer to store adequent packet types, allocated by caller.
> + * @param num
> + *  Size of the array pointed by param ptypes.
> + * @return
> + *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
> + *          packet types will not be filled in the given array.
> + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> + *   - (-ENODEV) if *port_id* invalid.
> + */
> +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
> +				      uint32_t ptype_mask,
> +				      uint32_t *ptypes,
> +				      int num);
> +
> +/**
>    * Retrieve the MTU of an Ethernet device.
>    *
>    * @param port_id
>

"extern" is redundant in headers. We just saw a round of removing them 
(commit dd34ff1f0e03b2c5e4a97e9fbcba5c8238aac573), lets not add them back :)

More importantly, to export a function you need to add an entry for it 
in rte_ether_version.map.

	- Panu -

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v5 01/11] ethdev: add API to query packet type filling info
  2016-02-29 11:34     ` Panu Matilainen
@ 2016-02-29 16:41       ` Tan, Jianfeng
  2016-03-01  6:29         ` Panu Matilainen
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-02-29 16:41 UTC (permalink / raw)
  To: Panu Matilainen, dev

Hi Panu,

On 2/29/2016 7:34 PM, Panu Matilainen wrote:
> On 02/26/2016 09:34 AM, Jianfeng Tan wrote:
>> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
>> type can be filled by given pmd rx burst function.
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   lib/librte_ether/rte_ethdev.c | 26 ++++++++++++++++++++++++++
>>   lib/librte_ether/rte_ethdev.h | 26 ++++++++++++++++++++++++++
>>   2 files changed, 52 insertions(+)
>>
> [...]
>> diff --git a/lib/librte_ether/rte_ethdev.h 
>> b/lib/librte_ether/rte_ethdev.h
>> index 16da821..16f32a0 100644
>> --- a/lib/librte_ether/rte_ethdev.h
>> +++ b/lib/librte_ether/rte_ethdev.h
>> @@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct 
>> rte_eth_dev *dev,
>>                       struct rte_eth_dev_info *dev_info);
>>   /**< @internal Get specific informations of an Ethernet device. */
>>
>> +typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct 
>> rte_eth_dev *dev);
>> +/**< @internal Get ptype info of eth_rx_burst_t. */
>> +
>>   typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
>>                       uint16_t queue_id);
>>   /**< @internal Start rx and tx of a queue of an Ethernet device. */
>> @@ -1347,6 +1350,7 @@ struct eth_dev_ops {
>>       eth_queue_stats_mapping_set_t queue_stats_mapping_set;
>>       /**< Configure per queue stat counter mapping. */
>>       eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
>> +    eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype 
>> info */
>>       mtu_set_t                  mtu_set; /**< Set MTU. */
>>       vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN 
>> Setup. */
>>       vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN 
>> TPID Setup. */
>> @@ -2268,6 +2272,28 @@ void rte_eth_macaddr_get(uint8_t port_id, 
>> struct ether_addr *mac_addr);
>
> Technically this is an ABI break but its marked internal and I guess 
> it falls into the "drivers only" territory similar to what was 
> discussed in this thead: 
> http://dpdk.org/ml/archives/dev/2016-January/032348.html so its 
> probably ok.

Yes, I think so too.

>
>>   void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info 
>> *dev_info);
>>
>>   /**
>> + * Retrieve the packet type information of an Ethernet device.
>> + *
>> + * @param port_id
>> + *   The port identifier of the Ethernet device.
>> + * @param ptype_mask
>> + *   A hint of what kind of packet type which the caller is 
>> interested in.
>> + * @param ptypes
>> + *   An array pointer to store adequent packet types, allocated by 
>> caller.
>> + * @param num
>> + *  Size of the array pointed by param ptypes.
>> + * @return
>> + *   - (>0) Number of ptypes supported. If it exceeds param num, 
>> exceeding
>> + *          packet types will not be filled in the given array.
>> + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
>> + *   - (-ENODEV) if *port_id* invalid.
>> + */
>> +extern int rte_eth_dev_get_ptype_info(uint8_t port_id,
>> +                      uint32_t ptype_mask,
>> +                      uint32_t *ptypes,
>> +                      int num);
>> +
>> +/**
>>    * Retrieve the MTU of an Ethernet device.
>>    *
>>    * @param port_id
>>
>
> "extern" is redundant in headers. We just saw a round of removing them 
> (commit dd34ff1f0e03b2c5e4a97e9fbcba5c8238aac573), lets not add them 
> back :)
>
> More importantly, to export a function you need to add an entry for it 
> in rte_ether_version.map.

Oh, yes, thanks for pointing out this, I'll change this and update 
rte_ether_version.map.

Is it like this? Before or after DPDK_2.2 {}?
DPDK_2.3 {
     global:

     rte_eth_dev_get_ptype_info;

     local: *;
};

Thanks,
Jianfeng

>
>     - Panu -
>
>

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v5 00/11] Add API to get packet type info
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
                     ` (10 preceding siblings ...)
  2016-02-26  7:34   ` [PATCH v5 11/11] pmd/vmxnet3: " Jianfeng Tan
@ 2016-02-29 16:54   ` Ananyev, Konstantin
  2016-02-29 17:01     ` Adrien Mazarguil
  11 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-02-29 16:54 UTC (permalink / raw)
  To: Tan, Jianfeng, dev



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, February 26, 2016 7:34 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; nelio.laranjeiro@6wind.com; adrien.mazarguil@6wind.com; rahul.lakkireddy@chelsio.com;
> Tan, Jianfeng
> Subject: [PATCH v5 00/11] Add API to get packet type info
> 
> To achieve this, a new function pointer, dev_ptype_info_get, is added
> into struct eth_dev_ops. For those devices who do not implement it, it
> means it will not provide any ptype info.
> 
> v5:
>   - Exclude l3fwd change from this series, as a separated one.
>   - Fix malposition of mlx4 code in mlx5 commit introduced in v4.
> 
> v4:
>   - Change how to use this API: to previously agreement reached in mail.
> 
> v3:
>   - Change how to use this API: api to allocate mem for storing ptype
>     array; and caller to free the mem.
>   - Change how to return back ptypes from PMDs: return a pointer to
>     corresponding static const array of supported ptypes, terminated
>     by RTE_PTYPE_UNKNOWN.
>   - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
>   - Fix l3fwd memory leak when calling the API.
> 
> v2:
>   - Move ptype_mask filter function from each PMDs into ether layer.
>   - Add ixgbe vPMD's ptype info.
>   - Fix code style issues.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> 

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v5 00/11] Add API to get packet type info
  2016-02-29 16:54   ` [PATCH v5 00/11] Add API to get packet type info Ananyev, Konstantin
@ 2016-02-29 17:01     ` Adrien Mazarguil
  0 siblings, 0 replies; 202+ messages in thread
From: Adrien Mazarguil @ 2016-02-29 17:01 UTC (permalink / raw)
  To: Ananyev, Konstantin; +Cc: dev

On Mon, Feb 29, 2016 at 04:54:19PM +0000, Ananyev, Konstantin wrote:
> 
> 
> > -----Original Message-----
> > From: Tan, Jianfeng
> > Sent: Friday, February 26, 2016 7:34 AM
> > To: dev@dpdk.org
> > Cc: Zhang, Helin; Ananyev, Konstantin; nelio.laranjeiro@6wind.com; adrien.mazarguil@6wind.com; rahul.lakkireddy@chelsio.com;
> > Tan, Jianfeng
> > Subject: [PATCH v5 00/11] Add API to get packet type info
> > 
> > To achieve this, a new function pointer, dev_ptype_info_get, is added
> > into struct eth_dev_ops. For those devices who do not implement it, it
> > means it will not provide any ptype info.
> > 
> > v5:
> >   - Exclude l3fwd change from this series, as a separated one.
> >   - Fix malposition of mlx4 code in mlx5 commit introduced in v4.
> > 
> > v4:
> >   - Change how to use this API: to previously agreement reached in mail.
> > 
> > v3:
> >   - Change how to use this API: api to allocate mem for storing ptype
> >     array; and caller to free the mem.
> >   - Change how to return back ptypes from PMDs: return a pointer to
> >     corresponding static const array of supported ptypes, terminated
> >     by RTE_PTYPE_UNKNOWN.
> >   - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
> >   - Fix l3fwd memory leak when calling the API.
> > 
> > v2:
> >   - Move ptype_mask filter function from each PMDs into ether layer.
> >   - Add ixgbe vPMD's ptype info.
> >   - Fix code style issues.
> > 
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > 
> 
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

Fine for me as well.

Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

-- 
Adrien Mazarguil
6WIND

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v6 00/11] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (17 preceding siblings ...)
  2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
@ 2016-02-29 20:30 ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
                     ` (10 more replies)
  2016-03-01  1:23 ` [PATCH] examples/l3fwd: fix using packet type blindly Jianfeng Tan
                   ` (2 subsequent siblings)
  21 siblings, 11 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it does not provide any ptype info.

v6:
  - Remove extern in function declaration.
  - Update rte_ether_version.map.

v5:
  - Exclude l3fwd change from this series, as a separated one.
  - Fix malposition of mlx4 code in mlx5 commit introduced in v4.

v4:
  - Change how to use this API: to previously agreement reached in mail.

v3:
  - Change how to use this API: api to allocate mem for storing ptype
    array; and caller to free the mem.
  - Change how to return back ptypes from PMDs: return a pointer to
    corresponding static const array of supported ptypes, terminated
    by RTE_PTYPE_UNKNOWN.
  - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
  - Fix l3fwd memory leak when calling the API.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

Jianfeng Tan (11):
  ethdev: add API to query packet type filling info
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation

 drivers/net/cxgbe/cxgbe_ethdev.c       | 14 ++++++++++
 drivers/net/e1000/igb_ethdev.c         | 30 ++++++++++++++++++++
 drivers/net/enic/enic_ethdev.c         | 17 ++++++++++++
 drivers/net/fm10k/fm10k_ethdev.c       | 50 ++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c         |  3 ++
 drivers/net/fm10k/fm10k_rxtx_vec.c     |  3 ++
 drivers/net/i40e/i40e_ethdev.c         |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c      |  1 +
 drivers/net/i40e/i40e_rxtx.c           | 46 ++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h           |  1 +
 drivers/net/ixgbe/ixgbe_ethdev.c       | 38 ++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h       |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c         |  4 ++-
 drivers/net/mlx4/mlx4.c                | 21 ++++++++++++++
 drivers/net/mlx5/mlx5.c                |  1 +
 drivers/net/mlx5/mlx5.h                |  1 +
 drivers/net/mlx5/mlx5_ethdev.c         | 20 ++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c           |  2 ++
 drivers/net/nfp/nfp_net.c              | 19 +++++++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c   | 16 +++++++++++
 lib/librte_ether/rte_ethdev.c          | 26 ++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 24 ++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  7 +++++
 23 files changed, 345 insertions(+), 2 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v6 01/11] ethdev: add API to query packet type filling info
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
                     ` (9 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
type can be filled by given pmd rx burst function.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c          | 26 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 24 ++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  7 +++++++
 3 files changed, 57 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1257965..66dc7c5 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1576,6 +1576,32 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..75261ca 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get ptype info of eth_rx_burst_t. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2268,6 +2272,26 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the packet type information of an Ethernet device.
+ *
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			       uint32_t *ptypes, int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..3d2c4b6 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,10 @@ DPDK_2.2 {
 
 	local: *;
 };
+DPDK_2.3 {
+	global:
+
+	rte_eth_dev_get_ptype_info;
+
+	local: *; 
+};
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 02/11] pmd/cxgbe: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 03/11] pmd/e1000: " Jianfeng Tan
                     ` (8 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..33bd815 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,19 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static const uint32_t *cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +790,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_ptype_info_get	= cxgbe_dev_ptype_info_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 03/11] pmd/e1000: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 04/11] pmd/enic: " Jianfeng Tan
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/e1000/igb_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4ed5e95..b3a3ee6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -103,6 +103,7 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static const uint32_t *eth_igb_ptype_info_get(struct rte_eth_dev *dev);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -319,6 +320,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -376,6 +378,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1910,6 +1913,33 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static const uint32_t *
+eth_igb_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+	    dev->rx_pkt_burst == eth_igb_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 04/11] pmd/enic: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 03/11] pmd/e1000: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 05/11] pmd/fm10k: " Jianfeng Tan
                     ` (6 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2a88043..fbeab6f 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -54,6 +54,9 @@
 #define ENICPMD_FUNC_TRACE() (void)0
 #endif
 
+static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+				  uint16_t nb_pkts);
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -431,6 +434,19 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
+static const uint32_t *enicpmd_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == enicpmd_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -566,6 +582,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_ptype_info_get   = enicpmd_dev_ptype_info_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 05/11] pmd/fm10k: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 04/11] pmd/enic: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 06/11] pmd/i40e: " Jianfeng Tan
                     ` (5 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..429cbdd 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		static uint32_t ptypes[] = {
+			/* refers to rx_desc_to_ol_flags() */
+			RTE_PTYPE_L2_ETHER,
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		static uint32_t ptypes_vec[] = {
+			/* refers to fm10k_desc_to_pktype_v() */
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_TUNNEL_GENEVE,
+			RTE_PTYPE_TUNNEL_NVGRE,
+			RTE_PTYPE_TUNNEL_VXLAN,
+			RTE_PTYPE_TUNNEL_GRE,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes_vec;
+	}
+
+	return NULL;
+}
+#else
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev __rte_unused)
+{
+	return NULL;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2423,6 +2472,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_ptype_info_get	= fm10k_dev_ptype_info_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index e958865..cbe0111 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,9 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 2a57eef..f347641 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -109,6 +109,9 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get().
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 06/11] pmd/i40e: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 05/11] pmd/fm10k: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 07/11] pmd/ixgbe: " Jianfeng Tan
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 46 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ef24122..81849fa 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -439,6 +439,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_ptype_info_get           = i40e_dev_ptype_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..afd436e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -196,6 +196,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_ptype_info_get   = i40e_dev_ptype_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 40cffc1..1a952df 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -194,7 +194,10 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/* For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2093,6 +2096,47 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 	return 0;
 }
 
+const uint32_t *
+i40e_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_TIMESYNC,
+		RTE_PTYPE_L2_ETHER_LLDP,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_L4_NONFRAG,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L2_ETHER_VLAN,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_ICMP,
+		RTE_PTYPE_INNER_L4_NONFRAG,
+		RTE_PTYPE_INNER_L4_SCTP,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+	    dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+	    dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..3a59d81 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,7 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+const uint32_t *i40e_dev_ptype_info_get(struct rte_eth_dev *dev);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 07/11] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 06/11] pmd/i40e: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 08/11] pmd/mlx4: " Jianfeng Tan
                     ` (3 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  4 +++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3e6fe86..605d958 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static const uint32_t *ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static const uint32_t *
+ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* For non-vec functions,
+		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+		 * for vec functions,
+		 * refers to _recv_raw_pkts_vec().
+		 */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
+	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec)
+		return ptypes;
+	return NULL;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index d26771a..b07d3da 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+				    uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index e95e6b7..17851cc 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -899,6 +899,8 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+
+/* @note: fix ixgbe_dev_ptype_info_get() if any change here. */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1247,7 +1249,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 08/11] pmd/mlx4: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 07/11] pmd/ixgbe: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 09/11] pmd/mlx5: " Jianfeng Tan
                     ` (2 subsequent siblings)
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx4/mlx4.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ee00151..58f4e1a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2835,6 +2835,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4267,6 +4269,24 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static const uint32_t *
+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == mlx4_rx_burst ||
+	    dev->rx_pkt_burst == mlx4_rx_burst_sp)
+		return ptypes;
+	return NULL;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -4988,6 +5008,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 09/11] pmd/mlx5: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 08/11] pmd/mlx4: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 10/11] pmd/nfp: " Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 11/11] pmd/vmxnet3: " Jianfeng Tan
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  1 +
 drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 4 files changed, 24 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..e18b1e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -153,6 +153,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_ptype_info_get = mlx5_dev_ptype_info_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b84d31d..196435d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -156,6 +156,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+const uint32_t *mlx5_dev_ptype_info_get(struct rte_eth_dev *dev);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..406f8dc 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -526,6 +526,26 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+const uint32_t *
+mlx5_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+
+	};
+
+	if (dev->rx_pkt_burst == mlx5_rx_burst ||
+	    dev->rx_pkt_burst == mlx5_rx_burst_sp)
+		return ptypes;
+	return NULL;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index fa5e648..79bdf8d 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -603,6 +603,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 10/11] pmd/nfp: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 09/11] pmd/mlx5: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  2016-02-29 20:30   ` [PATCH v6 11/11] pmd/vmxnet3: " Jianfeng Tan
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/nfp/nfp_net.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index fd4dd39..5894a9d 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1073,6 +1073,24 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 }
 
+static const uint32_t *
+nfp_net_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to nfp_net_set_hash() */
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_MASK,
+		RTE_PTYPE_UNKNOWN
+	};
+
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts)
+		return ptypes;
+	return num;
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2292,6 +2310,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_ptype_info_get	= nfp_net_ptype_info_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v6 11/11] pmd/vmxnet3: add dev_ptype_info_get implementation
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-02-29 20:30   ` [PATCH v6 10/11] pmd/nfp: " Jianfeng Tan
@ 2016-02-29 20:30   ` Jianfeng Tan
  10 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-02-29 20:30 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..ac120a1 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,7 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static const uint32_t *vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -118,6 +119,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.link_update          = vmxnet3_dev_link_update,
 	.stats_get            = vmxnet3_dev_stats_get,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_ptype_info_get   = vmxnet3_dev_ptype_info_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -718,6 +720,20 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, struct rte_
 	};
 }
 
+static const uint32_t *
+vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH] examples/l3fwd: fix using packet type blindly
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (18 preceding siblings ...)
  2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
@ 2016-03-01  1:23 ` Jianfeng Tan
  2016-03-01 13:51   ` Ananyev, Konstantin
                     ` (3 more replies)
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
  21 siblings, 4 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-01  1:23 UTC (permalink / raw)
  To: dev

As a example to use ptype info, l3fwd needs firstly to use
rte_eth_dev_get_ptype_info() API to check if device and/or
its PMD driver will parse and fill the needed packet type;
if not, use the newly added option, --parse-ptype, to
analyze it in the callback softly.

As the mode of EXACT_MATCH uses the 5 tuples to caculate
hash, so we narrow down its scope to:
  a. ip packets with no extensions, and
  b. L4 payload should be either tcp or udp.

Note: this patch does not completely solve the issue, "cannot
run l3fwd on virtio or other devices", because hw_ip_checksum
may be not supported by the devices. Currently we can: option
1, remove this requirements; option 2, wait for virtio front
end (pmd) to support it.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst  |  5 ++
 doc/guides/sample_app_ug/l3_forward.rst |  6 ++-
 examples/l3fwd/l3fwd.h                  | 12 +++++
 examples/l3fwd/l3fwd_em.c               | 94 +++++++++++++++++++++++++++++++++
 examples/l3fwd/l3fwd_lpm.c              | 57 ++++++++++++++++++++
 examples/l3fwd/main.c                   | 50 ++++++++++++++++++
 6 files changed, 223 insertions(+), 1 deletion(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 64e913d..4d6260e 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -68,6 +68,11 @@ This section should contain bug fixes added to the relevant sections. Sample for
   vhost-switch often fails to allocate mbuf when dequeue from vring because it
   wrongly calculates the number of mbufs needed.
 
+* **examples/l3fwd: Fixed using packet type blindly.**
+
+  l3fwd makes use of packet type information without even query if devices or PMDs
+  really set it. For those don't set ptypes, add an option to parse it softly.
+
 
 EAL
 ~~~
diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst
index 4ce734b..e0c22e3 100644
--- a/doc/guides/sample_app_ug/l3_forward.rst
+++ b/doc/guides/sample_app_ug/l3_forward.rst
@@ -93,7 +93,7 @@ The application has a number of command line options:
 
 .. code-block:: console
 
-    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6]
+    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6] [--parse-ptype]
 
 where,
 
@@ -114,6 +114,8 @@ where,
 
 *   --ipv6: optional, set it if running ipv6 packets
 
+*   --parse-ptype: optional, set it if use software way to analyze packet type
+
 For example, consider a dual processor socket platform where cores 0-7 and 16-23 appear on socket 0, while cores 8-15 and 24-31 appear on socket 1.
 Let's say that the programmer wants to use memory from both NUMA nodes, the platform has only two ports, one connected to each NUMA node,
 and the programmer wants to use two cores from each processor socket to do the packet processing.
@@ -334,6 +336,8 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below:
 
 The simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function.
 
+Known issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well with this mode.
+
 Packet Forwarding for LPM-based Lookups
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index da6d369..966c83b 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -198,6 +198,18 @@ void
 setup_hash(const int socketid);
 
 int
+em_check_ptype(int portid);
+
+int
+lpm_check_ptype(int portid);
+
+void
+em_parse_ptype(struct rte_mbuf *);
+
+void
+lpm_parse_ptype(struct rte_mbuf *);
+
+int
 em_main_loop(__attribute__((unused)) void *dummy);
 
 int
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index f6a65d8..1061baf 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -42,6 +42,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <stdbool.h>
+#include <netinet/in.h>
 
 #include <rte_debug.h>
 #include <rte_ether.h>
@@ -508,6 +509,99 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h,
 	printf("Hash: Adding 0x%x keys\n", nr_flow);
 }
 
+/* Requirements:
+ * 1. IP packets without extension;
+ * 2. L4 payload should be either TCP or UDP.
+ */
+int
+em_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4_ext = 0;
+	int ptype_l3_ipv6_ext = 0;
+	int ptype_l4_tcp = 0;
+	int ptype_l4_udp = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid,
+					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
+					 NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_ptype_info(portid,
+					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
+					 ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		switch (ptypes[i]) {
+		case RTE_PTYPE_L3_IPV4_EXT:
+			ptype_l3_ipv4_ext = 1;
+			break;
+		case RTE_PTYPE_L3_IPV6_EXT:
+			ptype_l3_ipv6_ext = 1;
+			break;
+		case RTE_PTYPE_L4_TCP:
+			ptype_l4_tcp = 1;
+			break;
+		case RTE_PTYPE_L4_UDP:
+			ptype_l4_udp = 1;
+			break;
+		}
+	}
+
+	if (ptype_l3_ipv4_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
+	if (ptype_l3_ipv6_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
+	if (ptype_l3_ipv4_ext && ptype_l3_ipv6_ext)
+		return 1;
+
+	if (ptype_l4_tcp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
+	if (ptype_l4_udp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
+	if (ptype_l4_tcp || ptype_l4_udp)
+		return 1;
+
+	return 0;
+}
+
+void
+em_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = 0;
+	uint16_t ethertype;
+	void *l4;
+	int hdr_len;
+	struct ipv4_hdr *ipv4_hdr;
+	struct ipv6_hdr *ipv6_hdr;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	l4 = (uint8_t *)eth_hdr + sizeof(struct ether_hdr);
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+		ipv4_hdr = (struct ipv4_hdr *)l4;
+		hdr_len = (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
+			  IPV4_IHL_MULTIPLIER;
+		if (hdr_len == sizeof(struct ipv4_hdr) &&
+		    (ipv4_hdr->next_proto_id == IPPROTO_TCP ||
+		     ipv4_hdr->next_proto_id == IPPROTO_UDP))
+			packet_type |= RTE_PTYPE_L3_IPV4;
+		break;
+	case ETHER_TYPE_IPv6:
+		ipv6_hdr = (struct ipv6_hdr *)l4;
+		if (ipv6_hdr->proto == IPPROTO_TCP ||
+		    ipv6_hdr->proto == IPPROTO_UDP)
+			packet_type |= RTE_PTYPE_L3_IPV6;
+		break;
+	}
+
+	m->packet_type |= packet_type;
+}
+
 /* main processing loop */
 int
 em_main_loop(__attribute__((unused)) void *dummy)
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index e0ed3c4..981227a 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -280,6 +280,63 @@ setup_lpm(const int socketid)
 	}
 }
 
+int
+lpm_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
+					 ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+
+}
+
+void
+lpm_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = 0;
+	uint16_t ethertype;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+		break;
+	case ETHER_TYPE_IPv6:
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		break;
+	default:
+		break;
+	}
+
+	m->packet_type |= packet_type;
+}
+
 /* Return ipv4/ipv6 lpm fwd lookup struct. */
 void *
 lpm_get_ipv4_l3fwd_lookup_struct(const int socketid)
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 0e33039..8889828 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -103,6 +103,8 @@ static int l3fwd_lpm_on;
 static int l3fwd_em_on;
 
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 /* Global variables. */
 
@@ -172,6 +174,8 @@ static struct rte_mempool * pktmbuf_pool[NB_SOCKETS];
 
 struct l3fwd_lkp_mode {
 	void  (*setup)(int);
+	int   (*check_ptype)(int);
+	void  (*parse_ptype)(struct rte_mbuf *);
 	int   (*main_loop)(void *);
 	void* (*get_ipv4_lookup_struct)(int);
 	void* (*get_ipv6_lookup_struct)(int);
@@ -181,6 +185,8 @@ static struct l3fwd_lkp_mode l3fwd_lkp;
 
 static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 	.setup                  = setup_hash,
+	.check_ptype		= em_check_ptype,
+	.parse_ptype		= em_parse_ptype,
 	.main_loop              = em_main_loop,
 	.get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
@@ -188,6 +194,8 @@ static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 
 static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
 	.setup                  = setup_lpm,
+	.check_ptype		= lpm_check_ptype,
+	.parse_ptype		= lpm_parse_ptype,
 	.main_loop              = lpm_main_loop,
 	.get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
@@ -209,6 +217,22 @@ setup_l3fwd_lookup_tables(void)
 		l3fwd_lkp = l3fwd_lpm_lkp;
 }
 
+static uint16_t
+cb_parse_packet_type(uint8_t port __rte_unused,
+		     uint16_t queue __rte_unused,
+		     struct rte_mbuf *pkts[],
+		     uint16_t nb_pkts,
+		     uint16_t max_pkts __rte_unused,
+		     void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		l3fwd_lkp.parse_ptype(pkts[i]);
+
+	return nb_pkts;
+}
+
 static int
 check_lcore_params(void)
 {
@@ -456,6 +480,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -486,6 +511,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -612,6 +638,14 @@ parse_args(int argc, char **argv)
 					return -1;
 				}
 			}
+
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -938,6 +972,22 @@ main(int argc, char **argv)
 				rte_exit(EXIT_FAILURE,
 				"rte_eth_rx_queue_setup: err=%d, port=%d\n",
 				ret, portid);
+
+			ret = l3fwd_lkp.check_ptype(portid);
+			if (ret)
+				continue;
+			if (!parse_ptype)
+				rte_exit(EXIT_FAILURE,
+					 "port %d cannot parse packet type, please add --%s\n",
+					 portid, CMD_LINE_OPT_PARSE_PTYPE);
+
+			if (rte_eth_add_rx_callback(portid, queueid,
+						    cb_parse_packet_type,
+						    NULL))
+				continue;
+			rte_exit(EXIT_FAILURE,
+				 "Failed to add rx callback: port=%d\n",
+				 portid);
 		}
 	}
 
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v5 01/11] ethdev: add API to query packet type filling info
  2016-02-29 16:41       ` Tan, Jianfeng
@ 2016-03-01  6:29         ` Panu Matilainen
  2016-03-01  7:59           ` Thomas Monjalon
  2016-03-01  8:00           ` Tan, Jianfeng
  0 siblings, 2 replies; 202+ messages in thread
From: Panu Matilainen @ 2016-03-01  6:29 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

On 02/29/2016 06:41 PM, Tan, Jianfeng wrote:
> Hi Panu,
>
> On 2/29/2016 7:34 PM, Panu Matilainen wrote:
[...]
>>
>> More importantly, to export a function you need to add an entry for it
>> in rte_ether_version.map.
>
> Oh, yes, thanks for pointing out this, I'll change this and update
> rte_ether_version.map.
>
> Is it like this? Before or after DPDK_2.2 {}?
> DPDK_2.3 {
>      global:
>
>      rte_eth_dev_get_ptype_info;
>
>      local: *;
> };

Sorry I didn't have a chance to reply to this yesterday and I see you 
already posted a v6 with the above, which is almost but not quite there: 
it needs to inherit from DPDK_2.2, ie

DPDK_2.3 {
      global:

      rte_eth_dev_get_ptype_info;

      local: *;
} DPDK_2.2;

...but if there are no other reasons to respin the series perhaps Thomas 
can fixup that while applying.

Then there's the actual version, which should optimally be DPDK_16.04 
but that's purely cosmetical. There are a number of patches floating 
around with DPDK_2.3 {} and librte_eal actually has one on board, so 
clearly the dust from versioning change has not yet settled.

	- Panu -

>
> Thanks,
> Jianfeng
>
>>
>>     - Panu -
>>
>>
>

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v5 01/11] ethdev: add API to query packet type filling info
  2016-03-01  6:29         ` Panu Matilainen
@ 2016-03-01  7:59           ` Thomas Monjalon
  2016-03-01  8:00           ` Tan, Jianfeng
  1 sibling, 0 replies; 202+ messages in thread
From: Thomas Monjalon @ 2016-03-01  7:59 UTC (permalink / raw)
  To: Panu Matilainen; +Cc: dev

2016-03-01 08:29, Panu Matilainen:
> DPDK_2.3 {
>       global:
> 
>       rte_eth_dev_get_ptype_info;
> 
>       local: *;
> } DPDK_2.2;
> 
> ...but if there are no other reasons to respin the series perhaps Thomas 
> can fixup that while applying.
> 
> Then there's the actual version, which should optimally be DPDK_16.04 
> but that's purely cosmetical. There are a number of patches floating 
> around with DPDK_2.3 {} and librte_eal actually has one on board, so 
> clearly the dust from versioning change has not yet settled.

Yes it must be 16.04.
I've just sent a patch for EAL:
	http://dpdk.org/ml/archives/dev/2016-March/034266.html
Thanks

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v5 01/11] ethdev: add API to query packet type filling info
  2016-03-01  6:29         ` Panu Matilainen
  2016-03-01  7:59           ` Thomas Monjalon
@ 2016-03-01  8:00           ` Tan, Jianfeng
  1 sibling, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-01  8:00 UTC (permalink / raw)
  To: Panu Matilainen, dev, Thomas Monjalon



On 3/1/2016 2:29 PM, Panu Matilainen wrote:
> On 02/29/2016 06:41 PM, Tan, Jianfeng wrote:
>> Hi Panu,
>>
>> On 2/29/2016 7:34 PM, Panu Matilainen wrote:
> [...]
>>>
>>> More importantly, to export a function you need to add an entry for it
>>> in rte_ether_version.map.
>>
>> Oh, yes, thanks for pointing out this, I'll change this and update
>> rte_ether_version.map.
>>
>> Is it like this? Before or after DPDK_2.2 {}?
>> DPDK_2.3 {
>>      global:
>>
>>      rte_eth_dev_get_ptype_info;
>>
>>      local: *;
>> };
>
> Sorry I didn't have a chance to reply to this yesterday and I see you 
> already posted a v6 with the above, which is almost but not quite 
> there: it needs to inherit from DPDK_2.2, ie
>
> DPDK_2.3 {
>      global:
>
>      rte_eth_dev_get_ptype_info;
>
>      local: *;
> } DPDK_2.2;
>
> ...but if there are no other reasons to respin the series perhaps 
> Thomas can fixup that while applying.

OK, thanks. Should I add this new API into _API Changes_ section in 
doc/guides/rel_notes/release_16_04.rst?

>
> Then there's the actual version, which should optimally be DPDK_16.04 
> but that's purely cosmetical. There are a number of patches floating 
> around with DPDK_2.3 {} and librte_eal actually has one on board, so 
> clearly the dust from versioning change has not yet settled.

Maybe Thomas can give some advice here? DPDK_2.3 or DPDK_16.04 be used here?

Thanks,
Jianfeng

>
>     - Panu -
>
>>
>> Thanks,
>> Jianfeng
>>
>>>
>>>     - Panu -
>>>
>>>
>>
>

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH] examples/l3fwd: fix using packet type blindly
  2016-03-01  1:23 ` [PATCH] examples/l3fwd: fix using packet type blindly Jianfeng Tan
@ 2016-03-01 13:51   ` Ananyev, Konstantin
  2016-03-01 14:17     ` Tan, Jianfeng
  2016-03-04  8:38   ` [PATCH v2] " Jianfeng Tan
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-03-01 13:51 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi Jianfeng,

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Tuesday, March 01, 2016 1:24 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; nelio.laranjeiro@6wind.com; adrien.mazarguil@6wind.com; rahul.lakkireddy@chelsio.com;
> pmatilai@redhat.com; Tan, Jianfeng
> Subject: [PATCH] examples/l3fwd: fix using packet type blindly
> 
> As a example to use ptype info, l3fwd needs firstly to use
> rte_eth_dev_get_ptype_info() API to check if device and/or
> its PMD driver will parse and fill the needed packet type;
> if not, use the newly added option, --parse-ptype, to
> analyze it in the callback softly.
> 
> As the mode of EXACT_MATCH uses the 5 tuples to caculate
> hash, so we narrow down its scope to:
>   a. ip packets with no extensions, and
>   b. L4 payload should be either tcp or udp.
> 
> Note: this patch does not completely solve the issue, "cannot
> run l3fwd on virtio or other devices", because hw_ip_checksum
> may be not supported by the devices. Currently we can: option
> 1, remove this requirements; option 2, wait for virtio front
> end (pmd) to support it.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  doc/guides/rel_notes/release_16_04.rst  |  5 ++
>  doc/guides/sample_app_ug/l3_forward.rst |  6 ++-
>  examples/l3fwd/l3fwd.h                  | 12 +++++
>  examples/l3fwd/l3fwd_em.c               | 94 +++++++++++++++++++++++++++++++++
>  examples/l3fwd/l3fwd_lpm.c              | 57 ++++++++++++++++++++
>  examples/l3fwd/main.c                   | 50 ++++++++++++++++++
>  6 files changed, 223 insertions(+), 1 deletion(-)
> 
> diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
> index 64e913d..4d6260e 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -68,6 +68,11 @@ This section should contain bug fixes added to the relevant sections. Sample for
>    vhost-switch often fails to allocate mbuf when dequeue from vring because it
>    wrongly calculates the number of mbufs needed.
> 
> +* **examples/l3fwd: Fixed using packet type blindly.**
> +
> +  l3fwd makes use of packet type information without even query if devices or PMDs
> +  really set it. For those don't set ptypes, add an option to parse it softly.
> +
> 
>  EAL
>  ~~~
> diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst
> index 4ce734b..e0c22e3 100644
> --- a/doc/guides/sample_app_ug/l3_forward.rst
> +++ b/doc/guides/sample_app_ug/l3_forward.rst
> @@ -93,7 +93,7 @@ The application has a number of command line options:
> 
>  .. code-block:: console
> 
> -    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len
> PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6]
> +    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len
> PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6] [--parse-ptype]
> 
>  where,
> 
> @@ -114,6 +114,8 @@ where,
> 
>  *   --ipv6: optional, set it if running ipv6 packets
> 
> +*   --parse-ptype: optional, set it if use software way to analyze packet type
> +
>  For example, consider a dual processor socket platform where cores 0-7 and 16-23 appear on socket 0, while cores 8-15 and 24-31
> appear on socket 1.
>  Let's say that the programmer wants to use memory from both NUMA nodes, the platform has only two ports, one connected to
> each NUMA node,
>  and the programmer wants to use two cores from each processor socket to do the packet processing.
> @@ -334,6 +336,8 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below:
> 
>  The simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function.
> 
> +Known issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well with this mode.
> +
>  Packet Forwarding for LPM-based Lookups
>  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 
> diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
> index da6d369..966c83b 100644
> --- a/examples/l3fwd/l3fwd.h
> +++ b/examples/l3fwd/l3fwd.h
> @@ -198,6 +198,18 @@ void
>  setup_hash(const int socketid);
> 
>  int
> +em_check_ptype(int portid);
> +
> +int
> +lpm_check_ptype(int portid);
> +
> +void
> +em_parse_ptype(struct rte_mbuf *);
> +
> +void
> +lpm_parse_ptype(struct rte_mbuf *);
> +
> +int
>  em_main_loop(__attribute__((unused)) void *dummy);
> 
>  int
> diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
> index f6a65d8..1061baf 100644
> --- a/examples/l3fwd/l3fwd_em.c
> +++ b/examples/l3fwd/l3fwd_em.c
> @@ -42,6 +42,7 @@
>  #include <errno.h>
>  #include <getopt.h>
>  #include <stdbool.h>
> +#include <netinet/in.h>
> 
>  #include <rte_debug.h>
>  #include <rte_ether.h>
> @@ -508,6 +509,99 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h,
>  	printf("Hash: Adding 0x%x keys\n", nr_flow);
>  }
> 
> +/* Requirements:
> + * 1. IP packets without extension;
> + * 2. L4 payload should be either TCP or UDP.
> + */
> +int
> +em_check_ptype(int portid)
> +{
> +	int i, ret;
> +	int ptype_l3_ipv4_ext = 0;
> +	int ptype_l3_ipv6_ext = 0;
> +	int ptype_l4_tcp = 0;
> +	int ptype_l4_udp = 0;
> +
> +	ret = rte_eth_dev_get_ptype_info(portid,
> +					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
> +					 NULL, 0);
> +	if (ret <= 0)
> +		return 0;
> +
> +	uint32_t ptypes[ret];
> +
> +	ret = rte_eth_dev_get_ptype_info(portid,
> +					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
> +					 ptypes, ret);
> +	for (i = 0; i < ret; ++i) {
> +		switch (ptypes[i]) {
> +		case RTE_PTYPE_L3_IPV4_EXT:
> +			ptype_l3_ipv4_ext = 1;
> +			break;
> +		case RTE_PTYPE_L3_IPV6_EXT:
> +			ptype_l3_ipv6_ext = 1;
> +			break;
> +		case RTE_PTYPE_L4_TCP:
> +			ptype_l4_tcp = 1;
> +			break;
> +		case RTE_PTYPE_L4_UDP:
> +			ptype_l4_udp = 1;
> +			break;
> +		}
> +	}
> +
> +	if (ptype_l3_ipv4_ext == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
> +	if (ptype_l3_ipv6_ext == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
> +	if (ptype_l3_ipv4_ext && ptype_l3_ipv6_ext)
> +		return 1;

Why return here?
You'll miss L4 ptype checks below.

> +
> +	if (ptype_l4_tcp == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
> +	if (ptype_l4_udp == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
> +	if (ptype_l4_tcp || ptype_l4_udp)
> +		return 1;
> +
> +	return 0;
> +}
> +
> +void
> +em_parse_ptype(struct rte_mbuf *m)
> +{
> +	struct ether_hdr *eth_hdr;
> +	uint32_t packet_type = 0;
> +	uint16_t ethertype;
> +	void *l4;
> +	int hdr_len;
> +	struct ipv4_hdr *ipv4_hdr;
> +	struct ipv6_hdr *ipv6_hdr;
> +
> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> +	l4 = (uint8_t *)eth_hdr + sizeof(struct ether_hdr);

Just curious why l4? It looks like l3 :)

> +	switch (ethertype) {
> +	case ETHER_TYPE_IPv4:
> +		ipv4_hdr = (struct ipv4_hdr *)l4;
> +		hdr_len = (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
> +			  IPV4_IHL_MULTIPLIER;
> +		if (hdr_len == sizeof(struct ipv4_hdr) &&
> +		    (ipv4_hdr->next_proto_id == IPPROTO_TCP ||
> +		     ipv4_hdr->next_proto_id == IPPROTO_UDP))
> +			packet_type |= RTE_PTYPE_L3_IPV4;

I think it needs to be something like:
If (hdr_len == sizeof(struct ipv4_hdr)) { 
        packet_type = RTE_PTYPE_L3_IPV4;
       if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
	packet_type |= RTE_PTYPE_L4_TCP;
       else if ipv4_hdr->next_proto_id == IPPROTO_UDP)
                packet_type |= RTE_PTYPE_L4_TCP;
}

And then inside em forward check ptype to be sure that is IPV4 with no options and UDP/TCP packet.
Same for IPv6.

> +		break;
> +	case ETHER_TYPE_IPv6:
> +		ipv6_hdr = (struct ipv6_hdr *)l4;
> +		if (ipv6_hdr->proto == IPPROTO_TCP ||
> +		    ipv6_hdr->proto == IPPROTO_UDP)
> +			packet_type |= RTE_PTYPE_L3_IPV6;
> +		break;
> +	}
> +
> +	m->packet_type |= packet_type;
> +}
> +
>  /* main processing loop */
>  int
>  em_main_loop(__attribute__((unused)) void *dummy)
> diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
> index e0ed3c4..981227a 100644
> --- a/examples/l3fwd/l3fwd_lpm.c
> +++ b/examples/l3fwd/l3fwd_lpm.c
> @@ -280,6 +280,63 @@ setup_lpm(const int socketid)
>  	}
>  }
> 
> +int
> +lpm_check_ptype(int portid)
> +{
> +	int i, ret;
> +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
> +
> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
> +	if (ret <= 0)
> +		return 0;
> +
> +	uint32_t ptypes[ret];
> +
> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
> +					 ptypes, ret);
> +	for (i = 0; i < ret; ++i) {
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
> +			ptype_l3_ipv4 = 1;
> +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
> +			ptype_l3_ipv6 = 1;
> +	}
> +
> +	if (ptype_l3_ipv4 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
> +
> +	if (ptype_l3_ipv6 == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
> +
> +	if (ptype_l3_ipv4 && ptype_l3_ipv6)
> +		return 1;
> +
> +	return 0;
> +
> +}
> +
> +void
> +lpm_parse_ptype(struct rte_mbuf *m)
> +{
> +	struct ether_hdr *eth_hdr;
> +	uint32_t packet_type = 0;
> +	uint16_t ethertype;
> +
> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> +	switch (ethertype) {
> +	case ETHER_TYPE_IPv4:
> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> +		break;
> +	case ETHER_TYPE_IPv6:
> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> +		break;
> +	default:
> +		break;
> +	}
> +
> +	m->packet_type |= packet_type;

Might be safer:
m->packet_type = packet_type;

> +}
> +
>  /* Return ipv4/ipv6 lpm fwd lookup struct. */
>  void *
>  lpm_get_ipv4_l3fwd_lookup_struct(const int socketid)
> diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
> index 0e33039..8889828 100644
> --- a/examples/l3fwd/main.c
> +++ b/examples/l3fwd/main.c
> @@ -103,6 +103,8 @@ static int l3fwd_lpm_on;
>  static int l3fwd_em_on;
> 
>  static int numa_on = 1; /**< NUMA is enabled by default. */
> +static int parse_ptype; /**< Parse packet type using rx callback, and */
> +			/**< disabled by default */
> 
>  /* Global variables. */
> 
> @@ -172,6 +174,8 @@ static struct rte_mempool * pktmbuf_pool[NB_SOCKETS];
> 
>  struct l3fwd_lkp_mode {
>  	void  (*setup)(int);
> +	int   (*check_ptype)(int);
> +	void  (*parse_ptype)(struct rte_mbuf *);
>  	int   (*main_loop)(void *);
>  	void* (*get_ipv4_lookup_struct)(int);
>  	void* (*get_ipv6_lookup_struct)(int);
> @@ -181,6 +185,8 @@ static struct l3fwd_lkp_mode l3fwd_lkp;
> 
>  static struct l3fwd_lkp_mode l3fwd_em_lkp = {
>  	.setup                  = setup_hash,
> +	.check_ptype		= em_check_ptype,
> +	.parse_ptype		= em_parse_ptype,
>  	.main_loop              = em_main_loop,
>  	.get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
>  	.get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
> @@ -188,6 +194,8 @@ static struct l3fwd_lkp_mode l3fwd_em_lkp = {
> 
>  static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
>  	.setup                  = setup_lpm,
> +	.check_ptype		= lpm_check_ptype,
> +	.parse_ptype		= lpm_parse_ptype,
>  	.main_loop              = lpm_main_loop,
>  	.get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
>  	.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
> @@ -209,6 +217,22 @@ setup_l3fwd_lookup_tables(void)
>  		l3fwd_lkp = l3fwd_lpm_lkp;
>  }
> 
> +static uint16_t
> +cb_parse_packet_type(uint8_t port __rte_unused,
> +		     uint16_t queue __rte_unused,
> +		     struct rte_mbuf *pkts[],
> +		     uint16_t nb_pkts,
> +		     uint16_t max_pkts __rte_unused,
> +		     void *user_param __rte_unused)
> +{
> +	unsigned i;
> +
> +	for (i = 0; i < nb_pkts; ++i)
> +		l3fwd_lkp.parse_ptype(pkts[i]);


No need to create callback chains.
That way you have extra call per packet.
Just 2 callbaclks: cb_lpm_parse_ptype & cb_em_parse_ptype,
and then register one depending on which mode are we in.
Would be simpler and faster, I believe.  

Konstantin

> +
> +	return nb_pkts;
> +}
> +
>  static int
>  check_lcore_params(void)
>  {
> @@ -456,6 +480,7 @@ parse_eth_dest(const char *optarg)
>  #define CMD_LINE_OPT_IPV6 "ipv6"
>  #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
>  #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
> +#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
> 
>  /*
>   * This expression is used to calculate the number of mbufs needed
> @@ -486,6 +511,7 @@ parse_args(int argc, char **argv)
>  		{CMD_LINE_OPT_IPV6, 0, 0, 0},
>  		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
>  		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
> +		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
>  		{NULL, 0, 0, 0}
>  	};
> 
> @@ -612,6 +638,14 @@ parse_args(int argc, char **argv)
>  					return -1;
>  				}
>  			}
> +
> +			if (!strncmp(lgopts[option_index].name,
> +				     CMD_LINE_OPT_PARSE_PTYPE,
> +				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
> +				printf("soft parse-ptype is enabled\n");
> +				parse_ptype = 1;
> +			}
> +
>  			break;
> 
>  		default:
> @@ -938,6 +972,22 @@ main(int argc, char **argv)
>  				rte_exit(EXIT_FAILURE,
>  				"rte_eth_rx_queue_setup: err=%d, port=%d\n",
>  				ret, portid);
> +
> +			ret = l3fwd_lkp.check_ptype(portid);
> +			if (ret)
> +				continue;
> +			if (!parse_ptype)
> +				rte_exit(EXIT_FAILURE,
> +					 "port %d cannot parse packet type, please add --%s\n",
> +					 portid, CMD_LINE_OPT_PARSE_PTYPE);
> +
> +			if (rte_eth_add_rx_callback(portid, queueid,
> +						    cb_parse_packet_type,
> +						    NULL))
> +				continue;
> +			rte_exit(EXIT_FAILURE,
> +				 "Failed to add rx callback: port=%d\n",
> +				 portid);
>  		}
>  	}
> 
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH] examples/l3fwd: fix using packet type blindly
  2016-03-01 13:51   ` Ananyev, Konstantin
@ 2016-03-01 14:17     ` Tan, Jianfeng
  2016-03-01 14:30       ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-01 14:17 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 3/1/2016 9:51 PM, Ananyev, Konstantin wrote:
> Hi Jianfeng,
>
>> -----Original Message-----
>> From: Tan, Jianfeng
>> Sent: Tuesday, March 01, 2016 1:24 AM
>> To: dev@dpdk.org
>> Cc: Zhang, Helin; Ananyev, Konstantin; nelio.laranjeiro@6wind.com; adrien.mazarguil@6wind.com; rahul.lakkireddy@chelsio.com;
>> pmatilai@redhat.com; Tan, Jianfeng
>> Subject: [PATCH] examples/l3fwd: fix using packet type blindly
>>
>> As a example to use ptype info, l3fwd needs firstly to use
>> rte_eth_dev_get_ptype_info() API to check if device and/or
>> its PMD driver will parse and fill the needed packet type;
>> if not, use the newly added option, --parse-ptype, to
>> analyze it in the callback softly.
>>
>> As the mode of EXACT_MATCH uses the 5 tuples to caculate
>> hash, so we narrow down its scope to:
>>    a. ip packets with no extensions, and
>>    b. L4 payload should be either tcp or udp.
[...]
>> +
>> +	if (ptype_l3_ipv4_ext == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
>> +	if (ptype_l3_ipv6_ext == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
>> +	if (ptype_l3_ipv4_ext && ptype_l3_ipv6_ext)
>> +		return 1;
> Why return here?
> You'll miss L4 ptype checks below.

Oops, should be: if (!ptype_l3_ipv4_ext || !ptype_l3_ipv6_ext) return 0; 
and continue check L4 ptype.

>> +
>> +	if (ptype_l4_tcp == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
>> +	if (ptype_l4_udp == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
>> +	if (ptype_l4_tcp || ptype_l4_udp)
>> +		return 1;
>> +
>> +	return 0;
>> +}
>> +
>> +void
>> +em_parse_ptype(struct rte_mbuf *m)
>> +{
>> +	struct ether_hdr *eth_hdr;
>> +	uint32_t packet_type = 0;
>> +	uint16_t ethertype;
>> +	void *l4;
>> +	int hdr_len;
>> +	struct ipv4_hdr *ipv4_hdr;
>> +	struct ipv6_hdr *ipv6_hdr;
>> +
>> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
>> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
>> +	l4 = (uint8_t *)eth_hdr + sizeof(struct ether_hdr);
> Just curious why l4? It looks like l3 :)

Yes, it's typo, should be l3. Thanks for pointing it out.

>> +	switch (ethertype) {
>> +	case ETHER_TYPE_IPv4:
>> +		ipv4_hdr = (struct ipv4_hdr *)l4;
>> +		hdr_len = (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
>> +			  IPV4_IHL_MULTIPLIER;
>> +		if (hdr_len == sizeof(struct ipv4_hdr) &&
>> +		    (ipv4_hdr->next_proto_id == IPPROTO_TCP ||
>> +		     ipv4_hdr->next_proto_id == IPPROTO_UDP))
>> +			packet_type |= RTE_PTYPE_L3_IPV4;
> I think it needs to be something like:
> If (hdr_len == sizeof(struct ipv4_hdr)) {
>          packet_type = RTE_PTYPE_L3_IPV4;
>         if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
> 	packet_type |= RTE_PTYPE_L4_TCP;
>         else if ipv4_hdr->next_proto_id == IPPROTO_UDP)
>                  packet_type |= RTE_PTYPE_L4_TCP;
> }
>
> And then inside em forward check ptype to be sure that is IPV4 with no options and UDP/TCP packet.
> Same for IPv6.

Got it, I'll change it and add this check in em forward function.

>> +		break;
>> +	case ETHER_TYPE_IPv6:
>> +		ipv6_hdr = (struct ipv6_hdr *)l4;
>> +		if (ipv6_hdr->proto == IPPROTO_TCP ||
>> +		    ipv6_hdr->proto == IPPROTO_UDP)
>> +			packet_type |= RTE_PTYPE_L3_IPV6;
>> +		break;
>> +	}
>> +
>> +	m->packet_type |= packet_type;
>> +}
>> +
>>   /* main processing loop */
>>   int
>>   em_main_loop(__attribute__((unused)) void *dummy)
>> diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
>> index e0ed3c4..981227a 100644
>> --- a/examples/l3fwd/l3fwd_lpm.c
>> +++ b/examples/l3fwd/l3fwd_lpm.c
>> @@ -280,6 +280,63 @@ setup_lpm(const int socketid)
>>   	}
>>   }
>>
>> +int
>> +lpm_check_ptype(int portid)
>> +{
>> +	int i, ret;
>> +	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
>> +
>> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
>> +	if (ret <= 0)
>> +		return 0;
>> +
>> +	uint32_t ptypes[ret];
>> +
>> +	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
>> +					 ptypes, ret);
>> +	for (i = 0; i < ret; ++i) {
>> +		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
>> +			ptype_l3_ipv4 = 1;
>> +		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
>> +			ptype_l3_ipv6 = 1;
>> +	}
>> +
>> +	if (ptype_l3_ipv4 == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
>> +
>> +	if (ptype_l3_ipv6 == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
>> +
>> +	if (ptype_l3_ipv4 && ptype_l3_ipv6)
>> +		return 1;
>> +
>> +	return 0;
>> +
>> +}
>> +
>> +void
>> +lpm_parse_ptype(struct rte_mbuf *m)
>> +{
>> +	struct ether_hdr *eth_hdr;
>> +	uint32_t packet_type = 0;
>> +	uint16_t ethertype;
>> +
>> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
>> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
>> +	switch (ethertype) {
>> +	case ETHER_TYPE_IPv4:
>> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
>> +		break;
>> +	case ETHER_TYPE_IPv6:
>> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
>> +		break;
>> +	default:
>> +		break;
>> +	}
>> +
>> +	m->packet_type |= packet_type;
> Might be safer:
> m->packet_type = packet_type;

Your previous comment on this says that the assignment will write off 
some ptype info PMDs have filled. But for l3fwd, I think it does not 
care other ptype info.

[...]
> +static uint16_t
> +cb_parse_packet_type(uint8_t port __rte_unused,
> +		     uint16_t queue __rte_unused,
> +		     struct rte_mbuf *pkts[],
> +		     uint16_t nb_pkts,
> +		     uint16_t max_pkts __rte_unused,
> +		     void *user_param __rte_unused)
> +{
> +	unsigned i;
> +
> +	for (i = 0; i < nb_pkts; ++i)
> +		l3fwd_lkp.parse_ptype(pkts[i]);
>
> No need to create callback chains.
> That way you have extra call per packet.
> Just 2 callbaclks: cb_lpm_parse_ptype & cb_em_parse_ptype,
> and then register one depending on which mode are we in.
> Would be simpler and faster, I believe.

Yes, I was considering it too. In addition, shall I use vector 
instruction here to accelerate it?

Thanks,
Jianfeng

>
> Konstantin
>

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH] examples/l3fwd: fix using packet type blindly
  2016-03-01 14:17     ` Tan, Jianfeng
@ 2016-03-01 14:30       ` Ananyev, Konstantin
  0 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-03-01 14:30 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

> >> +
> >> +void
> >> +lpm_parse_ptype(struct rte_mbuf *m)
> >> +{
> >> +	struct ether_hdr *eth_hdr;
> >> +	uint32_t packet_type = 0;
> >> +	uint16_t ethertype;
> >> +
> >> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> >> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> >> +	switch (ethertype) {
> >> +	case ETHER_TYPE_IPv4:
> >> +		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
> >> +		break;
> >> +	case ETHER_TYPE_IPv6:
> >> +		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
> >> +		break;
> >> +	default:
> >> +		break;
> >> +	}
> >> +
> >> +	m->packet_type |= packet_type;
> > Might be safer:
> > m->packet_type = packet_type;
> 
> Your previous comment on this says that the assignment will write off
> some ptype info PMDs have filled. But for l3fwd, I think it does not
> care other ptype info.

Ah, yes - missed that you setup it to 0 at the start of that function.
Probably better than to use PTYPE_UNKNOW macro 

> 
> [...]
> > +static uint16_t
> > +cb_parse_packet_type(uint8_t port __rte_unused,
> > +		     uint16_t queue __rte_unused,
> > +		     struct rte_mbuf *pkts[],
> > +		     uint16_t nb_pkts,
> > +		     uint16_t max_pkts __rte_unused,
> > +		     void *user_param __rte_unused)
> > +{
> > +	unsigned i;
> > +
> > +	for (i = 0; i < nb_pkts; ++i)
> > +		l3fwd_lkp.parse_ptype(pkts[i]);
> >
> > No need to create callback chains.
> > That way you have extra call per packet.
> > Just 2 callbaclks: cb_lpm_parse_ptype & cb_em_parse_ptype,
> > and then register one depending on which mode are we in.
> > Would be simpler and faster, I believe.
> 
> Yes, I was considering it too. In addition, shall I use vector
> instruction here to accelerate it?

If you like you can have 2 versions one scalar one, another vector one.
Same as we have for the rest of EM/LPM processing.
Just scalar one would do too, at least for now.

Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation
  2016-02-26  0:09   ` [PATCH v4 05/12] pmd/fm10k: " Jianfeng Tan
@ 2016-03-02 20:11     ` Chen, Jing D
  2016-03-03  6:03       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Chen, Jing D @ 2016-03-02 20:11 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi,

-----Original Message-----
From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jianfeng Tan
Sent: Thursday, February 25, 2016 6:09 PM
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..429cbdd 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev) {
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		static uint32_t ptypes[] = {
+			/* refers to rx_desc_to_ol_flags() */
+			RTE_PTYPE_L2_ETHER,
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		static uint32_t ptypes_vec[] = {
+			/* refers to fm10k_desc_to_pktype_v() */
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_TUNNEL_GENEVE,
+			RTE_PTYPE_TUNNEL_NVGRE,
+			RTE_PTYPE_TUNNEL_VXLAN,
+			RTE_PTYPE_TUNNEL_GRE,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes_vec;
+	}
+
+	return NULL;
+}
May I know when " fm10k_dev_ptype_info_get " will be called? In fm10k, the actual 
Rx/tx func will be decided after port is started. 

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation
  2016-03-02 20:11     ` Chen, Jing D
@ 2016-03-03  6:03       ` Tan, Jianfeng
  2016-03-03 15:47         ` Ananyev, Konstantin
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-03  6:03 UTC (permalink / raw)
  To: Chen, Jing D, dev

Hi,

On 3/3/2016 4:11 AM, Chen, Jing D wrote:
> Hi,
>
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jianfeng Tan
> Sent: Thursday, February 25, 2016 6:09 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>   drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
>   drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
>   drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
>   3 files changed, 56 insertions(+)
>
> diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
> index 421266b..429cbdd 100644
> --- a/drivers/net/fm10k/fm10k_ethdev.c
> +++ b/drivers/net/fm10k/fm10k_ethdev.c
> @@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
>   	};
>   }
>   
> +#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
> +static const uint32_t *
> +fm10k_dev_ptype_info_get(struct rte_eth_dev *dev) {
> +	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
> +	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
> +		static uint32_t ptypes[] = {
> +			/* refers to rx_desc_to_ol_flags() */
> +			RTE_PTYPE_L2_ETHER,
> +			RTE_PTYPE_L3_IPV4,
> +			RTE_PTYPE_L3_IPV4_EXT,
> +			RTE_PTYPE_L3_IPV6,
> +			RTE_PTYPE_L3_IPV6_EXT,
> +			RTE_PTYPE_L4_TCP,
> +			RTE_PTYPE_L4_UDP,
> +			RTE_PTYPE_UNKNOWN
> +		};
> +
> +		return ptypes;
> +	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
> +		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
> +		static uint32_t ptypes_vec[] = {
> +			/* refers to fm10k_desc_to_pktype_v() */
> +			RTE_PTYPE_L3_IPV4,
> +			RTE_PTYPE_L3_IPV4_EXT,
> +			RTE_PTYPE_L3_IPV6,
> +			RTE_PTYPE_L3_IPV6_EXT,
> +			RTE_PTYPE_L4_TCP,
> +			RTE_PTYPE_L4_UDP,
> +			RTE_PTYPE_TUNNEL_GENEVE,
> +			RTE_PTYPE_TUNNEL_NVGRE,
> +			RTE_PTYPE_TUNNEL_VXLAN,
> +			RTE_PTYPE_TUNNEL_GRE,
> +			RTE_PTYPE_UNKNOWN
> +		};
> +
> +		return ptypes_vec;
> +	}
> +
> +	return NULL;
> +}
> May I know when " fm10k_dev_ptype_info_get " will be called? In fm10k, the actual
> Rx/tx func will be decided after port is started.

Thank you for pointing out this. It's indeed an issue here. And it makes 
no difference when all rx functions fill the same ptypes, which, 
unfortunately, does not apply to all PMDs. According to my analysis, 
only in fm10k's case, we should call ptype_info_get after dev_start(), 
and for other PMDs, it can called just after rx_queue_setup. So in all, 
I need to add this as a caution in API declaration.

__details__

eth_cxgbe_dev_init

eth_igb_dev_init
eth_igbvf_dev_init
eth_igb_rx_init <- eth_igb_start (makes no difference, rx functins fill 
same ptypes)
eth_igbvf_rx_init <- igbvf_dev_start (makes no difference, rx functins 
fill same ptypes)

eth_enicpmd_dev_init

fm10k_set_rx_function <- fm10k_dev_rx_init <- fm10k_dev_start

eth_i40e_dev_init
i40evf_dev_init
i40e_set_rx_function <- eth_i40e_dev_init
                                      <- i40evf_dev_init
                                      <- i40e_dev_rx_init <- 
i40e_dev_rxtx_init <- i40e_dev_start (makes no difference, rx functins 
fill same ptypes)
                                      <- i40evf_rx_init <- 
i40evf_dev_start (makes no difference, rx functins fill same ptypes)

ixgbe_set_rx_function <- eth_ixgbe_dev_init
                                        <- ixgbe_dev_rx_init <- 
ixgbe_dev_start (makes no difference, rx functions fill same ptypes)
                                        <- ixgbevf_dev_rx_init

mlx4_rx_queue_setup
mlx4_dev_set_mtu (makes no difference, rx functions fill same ptypes)

mlx5_rx_queue_setup
mlx5_dev_set_mtu (makes no difference, rx functions fill same ptypes)

nfp_net_init

eth_vmxnet3_dev_init

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation
  2016-03-03  6:03       ` Tan, Jianfeng
@ 2016-03-03 15:47         ` Ananyev, Konstantin
  0 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-03-03 15:47 UTC (permalink / raw)
  To: Tan, Jianfeng, Chen, Jing D, dev



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Tan, Jianfeng
> Sent: Thursday, March 03, 2016 6:04 AM
> To: Chen, Jing D; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation
> 
> Hi,
> 
> On 3/3/2016 4:11 AM, Chen, Jing D wrote:
> > Hi,
> >
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Jianfeng Tan
> > Sent: Thursday, February 25, 2016 6:09 PM
> > To: dev@dpdk.org
> > Subject: [dpdk-dev] [PATCH v4 05/12] pmd/fm10k: add dev_ptype_info_get implementation
> >
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >   drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
> >   drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
> >   drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
> >   3 files changed, 56 insertions(+)
> >
> > diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
> > index 421266b..429cbdd 100644
> > --- a/drivers/net/fm10k/fm10k_ethdev.c
> > +++ b/drivers/net/fm10k/fm10k_ethdev.c
> > @@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
> >   	};
> >   }
> >
> > +#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
> > +static const uint32_t *
> > +fm10k_dev_ptype_info_get(struct rte_eth_dev *dev) {
> > +	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
> > +	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
> > +		static uint32_t ptypes[] = {
> > +			/* refers to rx_desc_to_ol_flags() */
> > +			RTE_PTYPE_L2_ETHER,
> > +			RTE_PTYPE_L3_IPV4,
> > +			RTE_PTYPE_L3_IPV4_EXT,
> > +			RTE_PTYPE_L3_IPV6,
> > +			RTE_PTYPE_L3_IPV6_EXT,
> > +			RTE_PTYPE_L4_TCP,
> > +			RTE_PTYPE_L4_UDP,
> > +			RTE_PTYPE_UNKNOWN
> > +		};
> > +
> > +		return ptypes;
> > +	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
> > +		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
> > +		static uint32_t ptypes_vec[] = {
> > +			/* refers to fm10k_desc_to_pktype_v() */
> > +			RTE_PTYPE_L3_IPV4,
> > +			RTE_PTYPE_L3_IPV4_EXT,
> > +			RTE_PTYPE_L3_IPV6,
> > +			RTE_PTYPE_L3_IPV6_EXT,
> > +			RTE_PTYPE_L4_TCP,
> > +			RTE_PTYPE_L4_UDP,
> > +			RTE_PTYPE_TUNNEL_GENEVE,
> > +			RTE_PTYPE_TUNNEL_NVGRE,
> > +			RTE_PTYPE_TUNNEL_VXLAN,
> > +			RTE_PTYPE_TUNNEL_GRE,
> > +			RTE_PTYPE_UNKNOWN
> > +		};
> > +
> > +		return ptypes_vec;
> > +	}
> > +
> > +	return NULL;
> > +}
> > May I know when " fm10k_dev_ptype_info_get " will be called? In fm10k, the actual
> > Rx/tx func will be decided after port is started.
> 
> Thank you for pointing out this. It's indeed an issue here. And it makes
> no difference when all rx functions fill the same ptypes, which,
> unfortunately, does not apply to all PMDs. According to my analysis,
> only in fm10k's case, we should call ptype_info_get after dev_start(),
> and for other PMDs, it can called just after rx_queue_setup. So in all,
> I need to add this as a caution in API declaration.

Good catch Mark :)
I think it should be called after dev_start() for all devices:
dev_start() is the usual point where final decision
what RX function should be used is made.
At least for the PMDs I am aware about (ixgbe, i40e, igb).

Konstantin

> 
> __details__
> 
> eth_cxgbe_dev_init
> 
> eth_igb_dev_init
> eth_igbvf_dev_init
> eth_igb_rx_init <- eth_igb_start (makes no difference, rx functins fill
> same ptypes)
> eth_igbvf_rx_init <- igbvf_dev_start (makes no difference, rx functins
> fill same ptypes)
> 
> eth_enicpmd_dev_init
> 
> fm10k_set_rx_function <- fm10k_dev_rx_init <- fm10k_dev_start
> 
> eth_i40e_dev_init
> i40evf_dev_init
> i40e_set_rx_function <- eth_i40e_dev_init
>                                       <- i40evf_dev_init
>                                       <- i40e_dev_rx_init <-
> i40e_dev_rxtx_init <- i40e_dev_start (makes no difference, rx functins
> fill same ptypes)
>                                       <- i40evf_rx_init <-
> i40evf_dev_start (makes no difference, rx functins fill same ptypes)
> 
> ixgbe_set_rx_function <- eth_ixgbe_dev_init
>                                         <- ixgbe_dev_rx_init <-
> ixgbe_dev_start (makes no difference, rx functions fill same ptypes)
>                                         <- ixgbevf_dev_rx_init
> 
> mlx4_rx_queue_setup
> mlx4_dev_set_mtu (makes no difference, rx functions fill same ptypes)
> 
> mlx5_rx_queue_setup
> mlx5_dev_set_mtu (makes no difference, rx functions fill same ptypes)
> 
> nfp_net_init
> 
> eth_vmxnet3_dev_init
> 
> Thanks,
> Jianfeng
> 
> 

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v2] examples/l3fwd: fix using packet type blindly
  2016-03-01  1:23 ` [PATCH] examples/l3fwd: fix using packet type blindly Jianfeng Tan
  2016-03-01 13:51   ` Ananyev, Konstantin
@ 2016-03-04  8:38   ` Jianfeng Tan
  2016-03-07 18:51     ` Ananyev, Konstantin
  2016-03-10  5:50   ` [PATCH v3 0/2] " Jianfeng Tan
  2016-03-25  0:47   ` [PATCH v4 0/3] packet type Jianfeng Tan
  3 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-04  8:38 UTC (permalink / raw)
  To: dev

This patch will work on below patch series.
 - [PATCH v6 00/11] Add API to get packet type info

As a example to use ptype info, l3fwd needs firstly to use
rte_eth_dev_get_ptype_info() API to check if device and/or
its PMD driver will parse and fill the needed packet type;
if not, use the newly added option, --parse-ptype, to
analyze it in the callback softly.

As the mode of EXACT_MATCH uses the 5 tuples to caculate
hash, so we narrow down its scope to:
  a. ip packets with no extensions, and
  b. L4 payload should be either tcp or udp.

Note: this patch does not completely solve the issue, "cannot
run l3fwd on virtio or other devices", because hw_ip_checksum
may be not supported by the devices. Currently we can:
  a. remove this requirements;
  b. wait for virtio front end (pmd) to support it.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
v2:
 - Add patchset dependence in commit log.
 - Change hardcoded 0 to RTE_PTYPE_UNKNOWN.
 - More accurate em_parse_type.
 - Add restrictions in EM forwarding functions.
 - Define cb directly to avoid too many function calls when do analyze.
 - Some typo fixed.
 - Change the position to call rte_eth_dev_get_ptype_info
   after rte_eth_dev_start().

 doc/guides/rel_notes/release_16_04.rst  |   5 ++
 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 examples/l3fwd/l3fwd.h                  |  14 ++++
 examples/l3fwd/l3fwd_em.c               | 115 ++++++++++++++++++++++++++++++++
 examples/l3fwd/l3fwd_em.h               |  10 ++-
 examples/l3fwd/l3fwd_em_hlm_sse.h       |  17 +++--
 examples/l3fwd/l3fwd_em_sse.h           |   9 ++-
 examples/l3fwd/l3fwd_lpm.c              |  71 ++++++++++++++++++++
 examples/l3fwd/main.c                   |  52 +++++++++++++++
 9 files changed, 289 insertions(+), 10 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 64e913d..4d6260e 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -68,6 +68,11 @@ This section should contain bug fixes added to the relevant sections. Sample for
   vhost-switch often fails to allocate mbuf when dequeue from vring because it
   wrongly calculates the number of mbufs needed.
 
+* **examples/l3fwd: Fixed using packet type blindly.**
+
+  l3fwd makes use of packet type information without even query if devices or PMDs
+  really set it. For those don't set ptypes, add an option to parse it softly.
+
 
 EAL
 ~~~
diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst
index 4ce734b..46a1782 100644
--- a/doc/guides/sample_app_ug/l3_forward.rst
+++ b/doc/guides/sample_app_ug/l3_forward.rst
@@ -93,7 +93,7 @@ The application has a number of command line options:
 
 .. code-block:: console
 
-    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6]
+    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6] [--parse-ptype]
 
 where,
 
@@ -114,6 +114,8 @@ where,
 
 *   --ipv6: optional, set it if running ipv6 packets
 
+*   --parse-ptype: optional, set it if use software way to analyze packet type
+
 For example, consider a dual processor socket platform where cores 0-7 and 16-23 appear on socket 0, while cores 8-15 and 24-31 appear on socket 1.
 Let's say that the programmer wants to use memory from both NUMA nodes, the platform has only two ports, one connected to each NUMA node,
 and the programmer wants to use two cores from each processor socket to do the packet processing.
@@ -334,6 +336,8 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below:
 
 The simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function.
 
+Known issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well at this mode.
+
 Packet Forwarding for LPM-based Lookups
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index da6d369..6ae2454 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -198,6 +198,20 @@ void
 setup_hash(const int socketid);
 
 int
+em_check_ptype(int portid);
+
+int
+lpm_check_ptype(int portid);
+
+uint16_t
+em_cb_parse_ptype(uint8_t port, uint16_t queue, struct rte_mbuf *pkts[],
+		  uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
+
+uint16_t
+lpm_cb_parse_ptype(uint8_t port, uint16_t queue, struct rte_mbuf *pkts[],
+		   uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
+
+int
 em_main_loop(__attribute__((unused)) void *dummy);
 
 int
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index f6a65d8..a2d51f0 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -42,6 +42,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <stdbool.h>
+#include <netinet/in.h>
 
 #include <rte_debug.h>
 #include <rte_ether.h>
@@ -508,6 +509,120 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h,
 	printf("Hash: Adding 0x%x keys\n", nr_flow);
 }
 
+/* Requirements:
+ * 1. IP packets without extension;
+ * 2. L4 payload should be either TCP or UDP.
+ */
+int
+em_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4_ext = 0;
+	int ptype_l3_ipv6_ext = 0;
+	int ptype_l4_tcp = 0;
+	int ptype_l4_udp = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid,
+					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
+					 NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_ptype_info(portid,
+					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
+					 ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		switch (ptypes[i]) {
+		case RTE_PTYPE_L3_IPV4_EXT:
+			ptype_l3_ipv4_ext = 1;
+			break;
+		case RTE_PTYPE_L3_IPV6_EXT:
+			ptype_l3_ipv6_ext = 1;
+			break;
+		case RTE_PTYPE_L4_TCP:
+			ptype_l4_tcp = 1;
+			break;
+		case RTE_PTYPE_L4_UDP:
+			ptype_l4_udp = 1;
+			break;
+		}
+	}
+
+	if (ptype_l3_ipv4_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
+	if (ptype_l3_ipv6_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
+	if (!ptype_l3_ipv4_ext || !ptype_l3_ipv6_ext)
+		return 0;
+
+	if (ptype_l4_tcp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
+	if (ptype_l4_udp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
+	if (ptype_l4_tcp || ptype_l4_udp)
+		return 1;
+
+	return 0;
+}
+
+static inline void
+em_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ethertype;
+	void *l3;
+	int hdr_len;
+	struct ipv4_hdr *ipv4_hdr;
+	struct ipv6_hdr *ipv6_hdr;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	l3 = (uint8_t *)eth_hdr + sizeof(struct ether_hdr);
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+		ipv4_hdr = (struct ipv4_hdr *)l3;
+		hdr_len = (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
+			  IPV4_IHL_MULTIPLIER;
+		if (hdr_len == sizeof(struct ipv4_hdr)) {
+			packet_type |= RTE_PTYPE_L3_IPV4;
+			if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
+				packet_type |= RTE_PTYPE_L4_TCP;
+			else if (ipv4_hdr->next_proto_id == IPPROTO_UDP)
+				packet_type |= RTE_PTYPE_L4_UDP;
+		} else
+			packet_type |= RTE_PTYPE_L3_IPV4_EXT;
+		break;
+	case ETHER_TYPE_IPv6:
+		ipv6_hdr = (struct ipv6_hdr *)l3;
+		if (ipv6_hdr->proto == IPPROTO_TCP)
+			packet_type |= RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
+		else if (ipv6_hdr->proto == IPPROTO_UDP)
+			packet_type |= RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
+		else
+			packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		break;
+	}
+
+	m->packet_type = packet_type;
+}
+
+uint16_t
+em_cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+		  struct rte_mbuf *pkts[], uint16_t nb_pkts,
+		  uint16_t max_pkts __rte_unused,
+		  void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		em_parse_ptype(pkts[i]);
+
+	return nb_pkts;
+}
+
 /* main processing loop */
 int
 em_main_loop(__attribute__((unused)) void *dummy)
diff --git a/examples/l3fwd/l3fwd_em.h b/examples/l3fwd/l3fwd_em.h
index 64ea7f7..2284bbd 100644
--- a/examples/l3fwd/l3fwd_em.h
+++ b/examples/l3fwd/l3fwd_em.h
@@ -41,10 +41,14 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 	struct ether_hdr *eth_hdr;
 	struct ipv4_hdr *ipv4_hdr;
 	uint8_t dst_port;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
 	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	tcp_or_udp = m->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = m->packet_type & RTE_PTYPE_L3_MASK;
 
-	if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
 						   sizeof(struct ether_hdr));
@@ -56,7 +60,7 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 			return;
 		}
 #endif
-		 dst_port = em_get_ipv4_dst_port(ipv4_hdr, portid,
+		dst_port = em_get_ipv4_dst_port(ipv4_hdr, portid,
 						qconf->ipv4_lookup_struct);
 
 		if (dst_port >= RTE_MAX_ETHPORTS ||
@@ -75,7 +79,7 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 		ether_addr_copy(&ports_eth_addr[dst_port], &eth_hdr->s_addr);
 
 		send_single_packet(qconf, m, dst_port);
-	} else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 		/* Handle IPv6 headers.*/
 		struct ipv6_hdr *ipv6_hdr;
 
diff --git a/examples/l3fwd/l3fwd_em_hlm_sse.h b/examples/l3fwd/l3fwd_em_hlm_sse.h
index d3388da..90821e6 100644
--- a/examples/l3fwd/l3fwd_em_hlm_sse.h
+++ b/examples/l3fwd/l3fwd_em_hlm_sse.h
@@ -247,8 +247,13 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	uint8_t next_hop;
 	struct ipv4_hdr *ipv4_hdr;
 	struct ipv6_hdr *ipv6_hdr;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
-	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+	tcp_or_udp = pkt->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = pkt->packet_type & RTE_PTYPE_L3_MASK;
+
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
@@ -263,7 +268,7 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 
 		return next_hop;
 
-	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 
 		/* Handle IPv6 headers.*/
 		ipv6_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv6_hdr *,
@@ -312,11 +317,15 @@ l3fwd_em_send_packets(int nb_rx, struct rte_mbuf **pkts_burst,
 			pkts_burst[j+6]->packet_type &
 			pkts_burst[j+7]->packet_type;
 
-		if (pkt_type & RTE_PTYPE_L3_IPV4) {
+		uint32_t l3_type = pkt_type & RTE_PTYPE_L3_MASK;
+		uint32_t tcp_or_udp = pkt_type &
+			(RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+
+		if (tcp_or_udp && (l3_type == RTE_PTYPE_L3_IPV4)) {
 
 			em_get_dst_port_ipv4x8(qconf, &pkts_burst[j], portid, &dst_port[j]);
 
-		} else if (pkt_type & RTE_PTYPE_L3_IPV6) {
+		} else if (tcp_or_udp && (l3_type == RTE_PTYPE_L3_IPV6)) {
 
 			em_get_dst_port_ipv6x8(qconf, &pkts_burst[j], portid, &dst_port[j]);
 
diff --git a/examples/l3fwd/l3fwd_em_sse.h b/examples/l3fwd/l3fwd_em_sse.h
index 4c6d14f..1ee3891 100644
--- a/examples/l3fwd/l3fwd_em_sse.h
+++ b/examples/l3fwd/l3fwd_em_sse.h
@@ -43,8 +43,13 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	uint8_t next_hop;
 	struct ipv4_hdr *ipv4_hdr;
 	struct ipv6_hdr *ipv6_hdr;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
-	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+	tcp_or_udp = pkt->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = pkt->packet_type & RTE_PTYPE_L3_MASK;
+
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
@@ -59,7 +64,7 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 
 		return next_hop;
 
-	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 
 		/* Handle IPv6 headers.*/
 		ipv6_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv6_hdr *,
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index e0ed3c4..8288035 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -280,6 +280,77 @@ setup_lpm(const int socketid)
 	}
 }
 
+int
+lpm_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
+					 ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+
+}
+
+static inline void
+lpm_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ethertype;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
+	switch (ethertype) {
+	case ETHER_TYPE_IPv4:
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+		break;
+	case ETHER_TYPE_IPv6:
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+		break;
+	default:
+		break;
+	}
+
+	m->packet_type = packet_type;
+}
+
+uint16_t
+lpm_cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+		   struct rte_mbuf *pkts[], uint16_t nb_pkts,
+		   uint16_t max_pkts __rte_unused,
+		   void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		lpm_parse_ptype(pkts[i]);
+
+	return nb_pkts;
+}
+
 /* Return ipv4/ipv6 lpm fwd lookup struct. */
 void *
 lpm_get_ipv4_l3fwd_lookup_struct(const int socketid)
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 0e33039..e8d053b 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -103,6 +103,8 @@ static int l3fwd_lpm_on;
 static int l3fwd_em_on;
 
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 /* Global variables. */
 
@@ -172,6 +174,8 @@ static struct rte_mempool * pktmbuf_pool[NB_SOCKETS];
 
 struct l3fwd_lkp_mode {
 	void  (*setup)(int);
+	int   (*check_ptype)(int);
+	rte_rx_callback_fn cb_parse_ptype;
 	int   (*main_loop)(void *);
 	void* (*get_ipv4_lookup_struct)(int);
 	void* (*get_ipv6_lookup_struct)(int);
@@ -181,6 +185,8 @@ static struct l3fwd_lkp_mode l3fwd_lkp;
 
 static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 	.setup                  = setup_hash,
+	.check_ptype		= em_check_ptype,
+	.cb_parse_ptype		= em_cb_parse_ptype,
 	.main_loop              = em_main_loop,
 	.get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
@@ -188,6 +194,8 @@ static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 
 static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
 	.setup                  = setup_lpm,
+	.check_ptype		= lpm_check_ptype,
+	.cb_parse_ptype		= lpm_cb_parse_ptype,
 	.main_loop              = lpm_main_loop,
 	.get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
@@ -456,6 +464,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -486,6 +495,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -612,6 +622,14 @@ parse_args(int argc, char **argv)
 					return -1;
 				}
 			}
+
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -965,6 +983,40 @@ main(int argc, char **argv)
 			rte_eth_promiscuous_enable(portid);
 	}
 
+	printf("\n");
+
+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+		if (rte_lcore_is_enabled(lcore_id) == 0)
+			continue;
+		qconf = &lcore_conf[lcore_id];
+		for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
+			portid = qconf->rx_queue_list[queue].port_id;
+			queueid = qconf->rx_queue_list[queue].queue_id;
+
+			ret = l3fwd_lkp.check_ptype(portid);
+			if (ret) {
+				printf("Port %d: built-in packet type info\n",
+				       portid);
+				continue;
+			}
+			if (!parse_ptype)
+				rte_exit(EXIT_FAILURE,
+					 "port %d cannot parse packet type, please add --%s\n",
+					 portid, CMD_LINE_OPT_PARSE_PTYPE);
+
+			printf("Port %d: softly parse packet type info\n",
+				portid);
+			if (rte_eth_add_rx_callback(portid, queueid,
+						    l3fwd_lkp.cb_parse_ptype,
+						    NULL))
+				continue;
+			rte_exit(EXIT_FAILURE,
+				 "Failed to add rx callback: port=%d\n",
+				 portid);
+		}
+	}
+
+
 	check_all_ports_link_status((uint8_t)nb_ports, enabled_port_mask);
 
 	ret = 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v2] examples/l3fwd: fix using packet type blindly
  2016-03-04  8:38   ` [PATCH v2] " Jianfeng Tan
@ 2016-03-07 18:51     ` Ananyev, Konstantin
  2016-03-08 17:11       ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-03-07 18:51 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

Hi Jianfeng,

> 
> +/* Requirements:
> + * 1. IP packets without extension;
> + * 2. L4 payload should be either TCP or UDP.
> + */
> +int
> +em_check_ptype(int portid)
> +{
> +	int i, ret;
> +	int ptype_l3_ipv4_ext = 0;
> +	int ptype_l3_ipv6_ext = 0;
> +	int ptype_l4_tcp = 0;
> +	int ptype_l4_udp = 0;
> +
> +	ret = rte_eth_dev_get_ptype_info(portid,
> +					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
> +					 NULL, 0);
> +	if (ret <= 0)
> +		return 0;
> +
> +	uint32_t ptypes[ret];
> +
> +	ret = rte_eth_dev_get_ptype_info(portid,
> +					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
> +					 ptypes, ret);
> +	for (i = 0; i < ret; ++i) {
> +		switch (ptypes[i]) {
> +		case RTE_PTYPE_L3_IPV4_EXT:
> +			ptype_l3_ipv4_ext = 1;
> +			break;
> +		case RTE_PTYPE_L3_IPV6_EXT:
> +			ptype_l3_ipv6_ext = 1;
> +			break;
> +		case RTE_PTYPE_L4_TCP:
> +			ptype_l4_tcp = 1;
> +			break;
> +		case RTE_PTYPE_L4_UDP:
> +			ptype_l4_udp = 1;
> +			break;
> +		}
> +	}
> +
> +	if (ptype_l3_ipv4_ext == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
> +	if (ptype_l3_ipv6_ext == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
> +	if (!ptype_l3_ipv4_ext || !ptype_l3_ipv6_ext)
> +		return 0;
> +
> +	if (ptype_l4_tcp == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
> +	if (ptype_l4_udp == 0)
> +		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
> +	if (ptype_l4_tcp || ptype_l4_udp)
> +		return 1;

Should probably be: if (ptype_l4_tcp && ptype_l4_udp)
?

> +
> +	return 0;
> +}
> +
> +static inline void
> +em_parse_ptype(struct rte_mbuf *m)
> +{
> +	struct ether_hdr *eth_hdr;
> +	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
> +	uint16_t ethertype;
> +	void *l3;
> +	int hdr_len;
> +	struct ipv4_hdr *ipv4_hdr;
> +	struct ipv6_hdr *ipv6_hdr;
> +
> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);

I think you can avoid bswap here, if use constants in BE format 
for comparison instead:
 
ethertype = eth_hdr->ether_type;
switch (ethertype) {
case (rte_cpu_to_be_16(ETHER_TYPE_IPv4)):
...

Same for lpm.

> 
> @@ -612,6 +622,14 @@ parse_args(int argc, char **argv)
>  					return -1;
>  				}
>  			}
> +
> +			if (!strncmp(lgopts[option_index].name,
> +				     CMD_LINE_OPT_PARSE_PTYPE,
> +				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
> +				printf("soft parse-ptype is enabled\n");
> +				parse_ptype = 1;
> +			}
> +
>  			break;
> 
>  		default:
> @@ -965,6 +983,40 @@ main(int argc, char **argv)
>  			rte_eth_promiscuous_enable(portid);
>  	}
> 
> +	printf("\n");
> +
> +	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
> +		if (rte_lcore_is_enabled(lcore_id) == 0)
> +			continue;
> +		qconf = &lcore_conf[lcore_id];
> +		for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
> +			portid = qconf->rx_queue_list[queue].port_id;
> +			queueid = qconf->rx_queue_list[queue].queue_id;
> +
> +			ret = l3fwd_lkp.check_ptype(portid);
> +			if (ret) {
> +				printf("Port %d: built-in packet type info\n",
> +				       portid);
> +				continue;
> +			}


I thought that if parse_ptype != 0 we always want to use a SW parsing,
no matter does HW support it or not, no?
So user can measure what is the performance difference between HW and SW versions?
Another thing, that I forgot to ask earlier - with ptype querying in place, would we like to set:
RTE_I40E_INC_VECTOR=y 
by default?

Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v2] examples/l3fwd: fix using packet type blindly
  2016-03-07 18:51     ` Ananyev, Konstantin
@ 2016-03-08 17:11       ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-08 17:11 UTC (permalink / raw)
  To: Ananyev, Konstantin, dev

Hi Konstantin,

On 3/8/2016 2:51 AM, Ananyev, Konstantin wrote:
> Hi Jianfeng,
>
>> +/* Requirements:
>> + * 1. IP packets without extension;
>> + * 2. L4 payload should be either TCP or UDP.
>> + */
>> +int
>> +em_check_ptype(int portid)
>> +{
>> +	int i, ret;
>> +	int ptype_l3_ipv4_ext = 0;
>> +	int ptype_l3_ipv6_ext = 0;
>> +	int ptype_l4_tcp = 0;
>> +	int ptype_l4_udp = 0;
>> +
>> +	ret = rte_eth_dev_get_ptype_info(portid,
>> +					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
>> +					 NULL, 0);
>> +	if (ret <= 0)
>> +		return 0;
>> +
>> +	uint32_t ptypes[ret];
>> +
>> +	ret = rte_eth_dev_get_ptype_info(portid,
>> +					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
>> +					 ptypes, ret);
>> +	for (i = 0; i < ret; ++i) {
>> +		switch (ptypes[i]) {
>> +		case RTE_PTYPE_L3_IPV4_EXT:
>> +			ptype_l3_ipv4_ext = 1;
>> +			break;
>> +		case RTE_PTYPE_L3_IPV6_EXT:
>> +			ptype_l3_ipv6_ext = 1;
>> +			break;
>> +		case RTE_PTYPE_L4_TCP:
>> +			ptype_l4_tcp = 1;
>> +			break;
>> +		case RTE_PTYPE_L4_UDP:
>> +			ptype_l4_udp = 1;
>> +			break;
>> +		}
>> +	}
>> +
>> +	if (ptype_l3_ipv4_ext == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
>> +	if (ptype_l3_ipv6_ext == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
>> +	if (!ptype_l3_ipv4_ext || !ptype_l3_ipv6_ext)
>> +		return 0;
>> +
>> +	if (ptype_l4_tcp == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
>> +	if (ptype_l4_udp == 0)
>> +		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
>> +	if (ptype_l4_tcp || ptype_l4_udp)
>> +		return 1;
> Should probably be: if (ptype_l4_tcp && ptype_l4_udp)
> ?

Oops, yes, we need to make it as a strict checking here.

>
>> +
>> +	return 0;
>> +}
>> +
>> +static inline void
>> +em_parse_ptype(struct rte_mbuf *m)
>> +{
>> +	struct ether_hdr *eth_hdr;
>> +	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
>> +	uint16_t ethertype;
>> +	void *l3;
>> +	int hdr_len;
>> +	struct ipv4_hdr *ipv4_hdr;
>> +	struct ipv6_hdr *ipv6_hdr;
>> +
>> +	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
>> +	ethertype = rte_be_to_cpu_16(eth_hdr->ether_type);
> I think you can avoid bswap here, if use constants in BE format
> for comparison instead:
>   
> ethertype = eth_hdr->ether_type;
> switch (ethertype) {
> case (rte_cpu_to_be_16(ETHER_TYPE_IPv4)):
> ...
>
> Same for lpm.

Great advice!

>
>> @@ -612,6 +622,14 @@ parse_args(int argc, char **argv)
>>   					return -1;
>>   				}
>>   			}
>> +
>> +			if (!strncmp(lgopts[option_index].name,
>> +				     CMD_LINE_OPT_PARSE_PTYPE,
>> +				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
>> +				printf("soft parse-ptype is enabled\n");
>> +				parse_ptype = 1;
>> +			}
>> +
>>   			break;
>>
>>   		default:
>> @@ -965,6 +983,40 @@ main(int argc, char **argv)
>>   			rte_eth_promiscuous_enable(portid);
>>   	}
>>
>> +	printf("\n");
>> +
>> +	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
>> +		if (rte_lcore_is_enabled(lcore_id) == 0)
>> +			continue;
>> +		qconf = &lcore_conf[lcore_id];
>> +		for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
>> +			portid = qconf->rx_queue_list[queue].port_id;
>> +			queueid = qconf->rx_queue_list[queue].queue_id;
>> +
>> +			ret = l3fwd_lkp.check_ptype(portid);
>> +			if (ret) {
>> +				printf("Port %d: built-in packet type info\n",
>> +				       portid);
>> +				continue;
>> +			}
>
> I thought that if parse_ptype != 0 we always want to use a SW parsing,
> no matter does HW support it or not, no?

Thanks for pointing this out. It's actually worth discussion. It depends 
on how --parse-ptype option means:
a. try best to use hw way, if fails, turns to sw way;
b. use sw way no matter hw way is workable.

Way a makes it portable to use the same cmd line of l3fwd for all devices.
Way b makes it more clear for this option.

I am actually more inclined to way b (your suggested way).

> So user can measure what is the performance difference between HW and SW versions?
> Another thing, that I forgot to ask earlier - with ptype querying in place, would we like to set:
> RTE_I40E_INC_VECTOR=y
> by default?

Thoughtful! I think you are right, and I'll double check with Tao Zhe.

Thanks,
Jianfeng

>
> Konstantin

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v7 00/11] Add API to get packet type info
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (19 preceding siblings ...)
  2016-03-01  1:23 ` [PATCH] examples/l3fwd: fix using packet type blindly Jianfeng Tan
@ 2016-03-09 19:31 ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
                     ` (11 more replies)
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
  21 siblings, 12 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

To achieve this, a new function pointer, dev_ptype_info_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it does not provide any ptype info.

v7:
  - 2.2 -> 16.04
  - Add note: this API better invoked after device is already started.
  - Update release_16_04.rst for newly added API.

v6:
  - Remove extern in function declaration.
  - Update rte_ether_version.map.

v5:
  - Exclude l3fwd change from this series, as a separated one.
  - Fix malposition of mlx4 code in mlx5 commit introduced in v4.

v4:
  - Change how to use this API: to previously agreement reached in mail.

v3:
  - Change how to use this API: api to allocate mem for storing ptype
    array; and caller to free the mem.
  - Change how to return back ptypes from PMDs: return a pointer to
    corresponding static const array of supported ptypes, terminated
    by RTE_PTYPE_UNKNOWN.
  - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
  - Fix l3fwd memory leak when calling the API.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

Jianfeng Tan (11):
  ethdev: add API to query packet type filling info
  pmd/cxgbe: add dev_ptype_info_get implementation
  pmd/e1000: add dev_ptype_info_get implementation
  pmd/enic: add dev_ptype_info_get implementation
  pmd/fm10k: add dev_ptype_info_get implementation
  pmd/i40e: add dev_ptype_info_get implementation
  pmd/ixgbe: add dev_ptype_info_get implementation
  pmd/mlx4: add dev_ptype_info_get implementation
  pmd/mlx5: add dev_ptype_info_get implementation
  pmd/nfp: add dev_ptype_info_get implementation
  pmd/vmxnet3: add dev_ptype_info_get implementation

 doc/guides/rel_notes/release_16_04.rst |  3 ++
 drivers/net/cxgbe/cxgbe_ethdev.c       | 14 ++++++++++
 drivers/net/e1000/igb_ethdev.c         | 30 ++++++++++++++++++++
 drivers/net/enic/enic_ethdev.c         | 17 ++++++++++++
 drivers/net/fm10k/fm10k_ethdev.c       | 50 ++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c         |  3 ++
 drivers/net/fm10k/fm10k_rxtx_vec.c     |  3 ++
 drivers/net/i40e/i40e_ethdev.c         |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c      |  1 +
 drivers/net/i40e/i40e_rxtx.c           | 46 ++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h           |  1 +
 drivers/net/ixgbe/ixgbe_ethdev.c       | 38 ++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h       |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c         |  4 ++-
 drivers/net/mlx4/mlx4.c                | 21 ++++++++++++++
 drivers/net/mlx5/mlx5.c                |  1 +
 drivers/net/mlx5/mlx5.h                |  1 +
 drivers/net/mlx5/mlx5_ethdev.c         | 20 ++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c           |  2 ++
 drivers/net/nfp/nfp_net.c              | 19 +++++++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c   | 16 +++++++++++
 lib/librte_ether/rte_ethdev.c          | 26 ++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 27 ++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  8 ++++++
 24 files changed, 352 insertions(+), 2 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v7 01/11] ethdev: add API to query packet type filling info
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-10 14:28     ` Bruce Richardson
  2016-03-14  9:44     ` Thomas Monjalon
  2016-03-09 19:31   ` [PATCH v7 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
                     ` (10 subsequent siblings)
  11 siblings, 2 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
type can be filled by given already started device or its pmd rx burst
function has already been decided).

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 doc/guides/rel_notes/release_16_04.rst |  3 +++
 lib/librte_ether/rte_ethdev.c          | 26 ++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 27 +++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  8 ++++++++
 4 files changed, 64 insertions(+)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index aa9eabc..376ece5 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -162,6 +162,9 @@ This section should contain API changes. Sample format:
   handlers are updated: the pipeline parameter is added,
   the packets mask parameter has been either removed or made input-only.
 
+* A new API ``rte_eth_dev_get_ptype_info`` is added to query what packet types
+  can be filled by given already started device.
+
 
 ABI Changes
 -----------
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 5c2b416..d828dcf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1576,6 +1576,32 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			   uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_ptype_info_get, -ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_ptype_info_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index d53e362..e0d2232 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_ptype_info_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get ptype info of an Ethernet device. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_ptype_info_get_t   dev_ptype_info_get; /** Get ptype info */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2268,6 +2272,29 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the packet type information of an Ethernet device.
+ *
+ * @note
+ *   Better to invoke this API after the device is already started or rx burst
+ *   function is decided, to obtain concise ptype information.
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
+			       uint32_t *ptypes, int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..a12784c 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,11 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_16.04 {
+	global:
+
+	rte_eth_dev_get_ptype_info;
+
+	local: *;
+} DPDK_2.2;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 02/11] pmd/cxgbe: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 03/11] pmd/e1000: " Jianfeng Tan
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 97ef152..33bd815 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,19 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static const uint32_t *cxgbe_dev_ptype_info_get(struct rte_eth_dev *eth_dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +790,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_ptype_info_get	= cxgbe_dev_ptype_info_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 03/11] pmd/e1000: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 04/11] pmd/enic: " Jianfeng Tan
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/e1000/igb_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 4ed5e95..b3a3ee6 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -103,6 +103,7 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static const uint32_t *eth_igb_ptype_info_get(struct rte_eth_dev *dev);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -319,6 +320,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -376,6 +378,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_ptype_info_get   = eth_igb_ptype_info_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1910,6 +1913,33 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static const uint32_t *
+eth_igb_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+	    dev->rx_pkt_burst == eth_igb_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 04/11] pmd/enic: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 03/11] pmd/e1000: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-10 14:50     ` Bruce Richardson
  2016-03-09 19:31   ` [PATCH v7 05/11] pmd/fm10k: " Jianfeng Tan
                     ` (7 subsequent siblings)
  11 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2a88043..fbeab6f 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -54,6 +54,9 @@
 #define ENICPMD_FUNC_TRACE() (void)0
 #endif
 
+static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+				  uint16_t nb_pkts);
+
 /*
  * The set of PCI devices this driver supports
  */
@@ -431,6 +434,19 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 		DEV_TX_OFFLOAD_TCP_CKSUM;
 }
 
+static const uint32_t *enicpmd_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == enicpmd_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -566,6 +582,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_ptype_info_get   = enicpmd_dev_ptype_info_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 05/11] pmd/fm10k: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 04/11] pmd/enic: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 06/11] pmd/i40e: " Jianfeng Tan
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 421266b..429cbdd 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1335,6 +1335,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		static uint32_t ptypes[] = {
+			/* refers to rx_desc_to_ol_flags() */
+			RTE_PTYPE_L2_ETHER,
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		static uint32_t ptypes_vec[] = {
+			/* refers to fm10k_desc_to_pktype_v() */
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_TUNNEL_GENEVE,
+			RTE_PTYPE_TUNNEL_NVGRE,
+			RTE_PTYPE_TUNNEL_VXLAN,
+			RTE_PTYPE_TUNNEL_GRE,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes_vec;
+	}
+
+	return NULL;
+}
+#else
+static const uint32_t *
+fm10k_dev_ptype_info_get(struct rte_eth_dev *dev __rte_unused)
+{
+	return NULL;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2423,6 +2472,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_ptype_info_get	= fm10k_dev_ptype_info_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index e958865..cbe0111 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,9 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 2a57eef..f347641 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -109,6 +109,9 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_ptype_info_get().
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 06/11] pmd/i40e: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 05/11] pmd/fm10k: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 07/11] pmd/ixgbe: " Jianfeng Tan
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 46 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7e68c61..67db2dd 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -450,6 +450,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_ptype_info_get           = i40e_dev_ptype_info_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 13c5b3d..afd436e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -196,6 +196,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_ptype_info_get   = i40e_dev_ptype_info_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 8931b8e..c5bd83a 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -188,7 +188,10 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/* For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_ptype_info_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2087,6 +2090,47 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 	return 0;
 }
 
+const uint32_t *
+i40e_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_TIMESYNC,
+		RTE_PTYPE_L2_ETHER_LLDP,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_L4_NONFRAG,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L2_ETHER_VLAN,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_ICMP,
+		RTE_PTYPE_INNER_L4_NONFRAG,
+		RTE_PTYPE_INNER_L4_SCTP,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+	    dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+	    dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..3a59d81 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,7 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+const uint32_t *i40e_dev_ptype_info_get(struct rte_eth_dev *dev);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 07/11] pmd/ixgbe: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 06/11] pmd/i40e: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 08/11] pmd/mlx4: " Jianfeng Tan
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  2 ++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  4 +++-
 3 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 3e6fe86..605d958 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -166,6 +166,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static const uint32_t *ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -428,6 +429,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -512,6 +514,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.xstats_reset         = ixgbevf_dev_stats_reset,
 	.dev_close            = ixgbevf_dev_close,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_ptype_info_get   = ixgbe_dev_ptype_info_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2829,6 +2832,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static const uint32_t *
+ixgbe_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* For non-vec functions,
+		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+		 * for vec functions,
+		 * refers to _recv_raw_pkts_vec().
+		 */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
+	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec)
+		return ptypes;
+	return NULL;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index d26771a..b07d3da 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -379,6 +379,8 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+				    uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 54278ce..5ade610 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -899,6 +899,8 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+
+/* @note: fix ixgbe_dev_ptype_info_get() if any change here. */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1247,7 +1249,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 08/11] pmd/mlx4: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 07/11] pmd/ixgbe: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 09/11] pmd/mlx5: " Jianfeng Tan
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/mlx4/mlx4.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index ee00151..58f4e1a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2835,6 +2835,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4267,6 +4269,24 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static const uint32_t *
+mlx4_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == mlx4_rx_burst ||
+	    dev->rx_pkt_burst == mlx4_rx_burst_sp)
+		return ptypes;
+	return NULL;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -4988,6 +5008,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_ptypes_info_get = mlx4_dev_ptype_info_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 09/11] pmd/mlx5: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 08/11] pmd/mlx4: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 10/11] pmd/nfp: " Jianfeng Tan
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  1 +
 drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 4 files changed, 24 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..e18b1e9 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -153,6 +153,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_ptype_info_get = mlx5_dev_ptype_info_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index b84d31d..196435d 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -156,6 +156,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+const uint32_t *mlx5_dev_ptype_info_get(struct rte_eth_dev *dev);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 1159fa3..406f8dc 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -526,6 +526,26 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+const uint32_t *
+mlx5_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+
+	};
+
+	if (dev->rx_pkt_burst == mlx5_rx_burst ||
+	    dev->rx_pkt_burst == mlx5_rx_burst_sp)
+		return ptypes;
+	return NULL;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index fa5e648..79bdf8d 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -603,6 +603,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_ptype_info_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 10/11] pmd/nfp: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 09/11] pmd/mlx5: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-09 19:31   ` [PATCH v7 11/11] pmd/vmxnet3: " Jianfeng Tan
  2016-03-10 14:55   ` [PATCH v7 00/11] Add API to get packet type info Bruce Richardson
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/nfp/nfp_net.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 9c4f218..ad6eebd 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1073,6 +1073,24 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 }
 
+static const uint32_t *
+nfp_net_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to nfp_net_set_hash() */
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_MASK,
+		RTE_PTYPE_UNKNOWN
+	};
+
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts)
+		return ptypes;
+	return num;
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2292,6 +2310,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_ptype_info_get	= nfp_net_ptype_info_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v7 11/11] pmd/vmxnet3: add dev_ptype_info_get implementation
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 10/11] pmd/nfp: " Jianfeng Tan
@ 2016-03-09 19:31   ` Jianfeng Tan
  2016-03-10 14:55   ` [PATCH v7 00/11] Add API to get packet type info Bruce Richardson
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-09 19:31 UTC (permalink / raw)
  To: dev

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index c363bf6..ac120a1 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,7 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static const uint32_t *vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -118,6 +119,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.link_update          = vmxnet3_dev_link_update,
 	.stats_get            = vmxnet3_dev_stats_get,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_ptype_info_get   = vmxnet3_dev_ptype_info_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -718,6 +720,20 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev, struct rte_
 	};
 }
 
+static const uint32_t *
+vmxnet3_dev_ptype_info_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 vmxnet3_dev_link_update(struct rte_eth_dev *dev, __attribute__((unused)) int wait_to_complete)
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 0/2] examples/l3fwd: fix using packet type blindly
  2016-03-01  1:23 ` [PATCH] examples/l3fwd: fix using packet type blindly Jianfeng Tan
  2016-03-01 13:51   ` Ananyev, Konstantin
  2016-03-04  8:38   ` [PATCH v2] " Jianfeng Tan
@ 2016-03-10  5:50   ` Jianfeng Tan
  2016-03-10  5:50     ` [PATCH v3 1/2] " Jianfeng Tan
                       ` (2 more replies)
  2016-03-25  0:47   ` [PATCH v4 0/3] packet type Jianfeng Tan
  3 siblings, 3 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-10  5:50 UTC (permalink / raw)
  To: dev

This patch will work on below patch series.
 - [PATCH v7 00/11] Add API to get packet type info

v3:
 - em ptype check: (l4_tcp || l4_udp) -> (l4_tcp && l4_udp).
 - avoid rte_be_to_cpu_16 for each packet by adding proper macros.
 - with --parse-ptype specified, use sw parser mandatorily.
 - enable i40e vector driver by default.

v2:
 - Add patchset dependence in commit log.
 - Change hardcoded 0 to RTE_PTYPE_UNKNOWN.
 - More accurate em_parse_type.
 - Add restrictions in EM forwarding functions.
 - Define cb directly to avoid too many function calls when do analyze.
 - Some typo fixed.
 - Change the position to call rte_eth_dev_get_ptype_info
   after rte_eth_dev_start().

Patch 1: add an option in l3fwd.
Patch 2: enable vector pmd in i40e by default.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Jianfeng Tan (2):
  examples/l3fwd: fix using packet type blindly
  config: enable i40e vector driver by default

 config/common_base                      |   2 +-
 doc/guides/rel_notes/release_16_04.rst  |  14 ++++
 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 examples/l3fwd/l3fwd.h                  |  14 ++++
 examples/l3fwd/l3fwd_em.c               | 112 ++++++++++++++++++++++++++++++++
 examples/l3fwd/l3fwd_em.h               |  10 ++-
 examples/l3fwd/l3fwd_em_hlm_sse.h       |  17 +++--
 examples/l3fwd/l3fwd_em_sse.h           |   9 ++-
 examples/l3fwd/l3fwd_lpm.c              |  65 ++++++++++++++++++
 examples/l3fwd/main.c                   |  55 ++++++++++++++++
 10 files changed, 293 insertions(+), 11 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v3 1/2] examples/l3fwd: fix using packet type blindly
  2016-03-10  5:50   ` [PATCH v3 0/2] " Jianfeng Tan
@ 2016-03-10  5:50     ` Jianfeng Tan
  2016-03-10  5:50     ` [PATCH v3 2/2] config: enable vector driver by default Jianfeng Tan
  2016-03-10 14:26     ` [PATCH v3 0/2] examples/l3fwd: fix using packet type blindly Ananyev, Konstantin
  2 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-10  5:50 UTC (permalink / raw)
  To: dev

As a example to use ptype info, l3fwd needs firstly to use
rte_eth_dev_get_ptype_info() API to check if device and/or
its PMD driver will parse and fill the needed packet type;
if not, use the newly added option, --parse-ptype, to
analyze it in the callback softly.

As the mode of EXACT_MATCH uses the 5 tuples to caculate
hash, so we narrow down its scope to:
  a. ip packets with no extensions, and
  b. L4 payload should be either tcp or udp.

Note: this patch does not completely solve the issue, "cannot
run l3fwd on virtio or other devices", because hw_ip_checksum
may be not supported by the devices. Currently we can:
  a. remove this requirements;
  b. wait for virtio front end (pmd) to support it.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst  |   9 +++
 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 examples/l3fwd/l3fwd.h                  |  14 ++++
 examples/l3fwd/l3fwd_em.c               | 112 ++++++++++++++++++++++++++++++++
 examples/l3fwd/l3fwd_em.h               |  10 ++-
 examples/l3fwd/l3fwd_em_hlm_sse.h       |  17 +++--
 examples/l3fwd/l3fwd_em_sse.h           |   9 ++-
 examples/l3fwd/l3fwd_lpm.c              |  65 ++++++++++++++++++
 examples/l3fwd/main.c                   |  55 ++++++++++++++++
 9 files changed, 287 insertions(+), 10 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 376ece5..f0bd3cb 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -86,6 +86,15 @@ This section should contain bug fixes added to the relevant sections. Sample for
   The title should contain the code/lib section like a commit message.
   Add the entries in alphabetic order in the relevant sections below.
 
+* **examples/vhost: Fixed frequent mbuf allocation failure.**
+
+  vhost-switch often fails to allocate mbuf when dequeue from vring because it
+  wrongly calculates the number of mbufs needed.
+
+* **examples/l3fwd: Fixed using packet type blindly.**
+
+  l3fwd makes use of packet type information without even query if devices or PMDs
+  really set it. For those don't set ptypes, add an option to parse it softly.
 
 EAL
 ~~~
diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst
index 1522650..3e070d0 100644
--- a/doc/guides/sample_app_ug/l3_forward.rst
+++ b/doc/guides/sample_app_ug/l3_forward.rst
@@ -92,7 +92,7 @@ The application has a number of command line options:
 
 .. code-block:: console
 
-    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6]
+    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6] [--parse-ptype]
 
 where,
 
@@ -113,6 +113,8 @@ where,
 
 *   --ipv6: optional, set it if running ipv6 packets
 
+*   --parse-ptype: optional, set it if use software way to analyze packet type
+
 For example, consider a dual processor socket platform where cores 0-7 and 16-23 appear on socket 0, while cores 8-15 and 24-31 appear on socket 1.
 Let's say that the programmer wants to use memory from both NUMA nodes, the platform has only two ports, one connected to each NUMA node,
 and the programmer wants to use two cores from each processor socket to do the packet processing.
@@ -334,6 +336,8 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below:
 
 The simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function.
 
+Known issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well at this mode.
+
 Packet Forwarding for LPM-based Lookups
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index da6d369..6ae2454 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -198,6 +198,20 @@ void
 setup_hash(const int socketid);
 
 int
+em_check_ptype(int portid);
+
+int
+lpm_check_ptype(int portid);
+
+uint16_t
+em_cb_parse_ptype(uint8_t port, uint16_t queue, struct rte_mbuf *pkts[],
+		  uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
+
+uint16_t
+lpm_cb_parse_ptype(uint8_t port, uint16_t queue, struct rte_mbuf *pkts[],
+		   uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
+
+int
 em_main_loop(__attribute__((unused)) void *dummy);
 
 int
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index f6a65d8..8fbdc48 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -42,6 +42,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <stdbool.h>
+#include <netinet/in.h>
 
 #include <rte_debug.h>
 #include <rte_ether.h>
@@ -508,6 +509,117 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h,
 	printf("Hash: Adding 0x%x keys\n", nr_flow);
 }
 
+/* Requirements:
+ * 1. IP packets without extension;
+ * 2. L4 payload should be either TCP or UDP.
+ */
+int
+em_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4_ext = 0;
+	int ptype_l3_ipv6_ext = 0;
+	int ptype_l4_tcp = 0;
+	int ptype_l4_udp = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid,
+					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
+					 NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_ptype_info(portid,
+					 RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK,
+					 ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		switch (ptypes[i]) {
+		case RTE_PTYPE_L3_IPV4_EXT:
+			ptype_l3_ipv4_ext = 1;
+			break;
+		case RTE_PTYPE_L3_IPV6_EXT:
+			ptype_l3_ipv6_ext = 1;
+			break;
+		case RTE_PTYPE_L4_TCP:
+			ptype_l4_tcp = 1;
+			break;
+		case RTE_PTYPE_L4_UDP:
+			ptype_l4_udp = 1;
+			break;
+		}
+	}
+
+	if (ptype_l3_ipv4_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
+	if (ptype_l3_ipv6_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
+	if (!ptype_l3_ipv4_ext || !ptype_l3_ipv6_ext)
+		return 0;
+
+	if (ptype_l4_tcp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
+	if (ptype_l4_udp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
+	if (ptype_l4_tcp && ptype_l4_udp)
+		return 1;
+
+	return 0;
+}
+
+static inline void
+em_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+	void *l3;
+	int hdr_len;
+	struct ipv4_hdr *ipv4_hdr;
+	struct ipv6_hdr *ipv6_hdr;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	l3 = (uint8_t *)eth_hdr + sizeof(struct ether_hdr);
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
+		ipv4_hdr = (struct ipv4_hdr *)l3;
+		hdr_len = (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
+			  IPV4_IHL_MULTIPLIER;
+		if (hdr_len == sizeof(struct ipv4_hdr)) {
+			packet_type |= RTE_PTYPE_L3_IPV4;
+			if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
+				packet_type |= RTE_PTYPE_L4_TCP;
+			else if (ipv4_hdr->next_proto_id == IPPROTO_UDP)
+				packet_type |= RTE_PTYPE_L4_UDP;
+		} else
+			packet_type |= RTE_PTYPE_L3_IPV4_EXT;
+	} else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
+		ipv6_hdr = (struct ipv6_hdr *)l3;
+		if (ipv6_hdr->proto == IPPROTO_TCP)
+			packet_type |= RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
+		else if (ipv6_hdr->proto == IPPROTO_UDP)
+			packet_type |= RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
+		else
+			packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+	}
+
+	m->packet_type = packet_type;
+}
+
+uint16_t
+em_cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+		  struct rte_mbuf *pkts[], uint16_t nb_pkts,
+		  uint16_t max_pkts __rte_unused,
+		  void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		em_parse_ptype(pkts[i]);
+
+	return nb_pkts;
+}
+
 /* main processing loop */
 int
 em_main_loop(__attribute__((unused)) void *dummy)
diff --git a/examples/l3fwd/l3fwd_em.h b/examples/l3fwd/l3fwd_em.h
index 64ea7f7..2284bbd 100644
--- a/examples/l3fwd/l3fwd_em.h
+++ b/examples/l3fwd/l3fwd_em.h
@@ -41,10 +41,14 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 	struct ether_hdr *eth_hdr;
 	struct ipv4_hdr *ipv4_hdr;
 	uint8_t dst_port;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
 	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	tcp_or_udp = m->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = m->packet_type & RTE_PTYPE_L3_MASK;
 
-	if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
 						   sizeof(struct ether_hdr));
@@ -56,7 +60,7 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 			return;
 		}
 #endif
-		 dst_port = em_get_ipv4_dst_port(ipv4_hdr, portid,
+		dst_port = em_get_ipv4_dst_port(ipv4_hdr, portid,
 						qconf->ipv4_lookup_struct);
 
 		if (dst_port >= RTE_MAX_ETHPORTS ||
@@ -75,7 +79,7 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 		ether_addr_copy(&ports_eth_addr[dst_port], &eth_hdr->s_addr);
 
 		send_single_packet(qconf, m, dst_port);
-	} else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 		/* Handle IPv6 headers.*/
 		struct ipv6_hdr *ipv6_hdr;
 
diff --git a/examples/l3fwd/l3fwd_em_hlm_sse.h b/examples/l3fwd/l3fwd_em_hlm_sse.h
index d3388da..90821e6 100644
--- a/examples/l3fwd/l3fwd_em_hlm_sse.h
+++ b/examples/l3fwd/l3fwd_em_hlm_sse.h
@@ -247,8 +247,13 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	uint8_t next_hop;
 	struct ipv4_hdr *ipv4_hdr;
 	struct ipv6_hdr *ipv6_hdr;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
-	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+	tcp_or_udp = pkt->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = pkt->packet_type & RTE_PTYPE_L3_MASK;
+
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
@@ -263,7 +268,7 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 
 		return next_hop;
 
-	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 
 		/* Handle IPv6 headers.*/
 		ipv6_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv6_hdr *,
@@ -312,11 +317,15 @@ l3fwd_em_send_packets(int nb_rx, struct rte_mbuf **pkts_burst,
 			pkts_burst[j+6]->packet_type &
 			pkts_burst[j+7]->packet_type;
 
-		if (pkt_type & RTE_PTYPE_L3_IPV4) {
+		uint32_t l3_type = pkt_type & RTE_PTYPE_L3_MASK;
+		uint32_t tcp_or_udp = pkt_type &
+			(RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+
+		if (tcp_or_udp && (l3_type == RTE_PTYPE_L3_IPV4)) {
 
 			em_get_dst_port_ipv4x8(qconf, &pkts_burst[j], portid, &dst_port[j]);
 
-		} else if (pkt_type & RTE_PTYPE_L3_IPV6) {
+		} else if (tcp_or_udp && (l3_type == RTE_PTYPE_L3_IPV6)) {
 
 			em_get_dst_port_ipv6x8(qconf, &pkts_burst[j], portid, &dst_port[j]);
 
diff --git a/examples/l3fwd/l3fwd_em_sse.h b/examples/l3fwd/l3fwd_em_sse.h
index d4a2a2d..7f2f373 100644
--- a/examples/l3fwd/l3fwd_em_sse.h
+++ b/examples/l3fwd/l3fwd_em_sse.h
@@ -43,8 +43,13 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	uint8_t next_hop;
 	struct ipv4_hdr *ipv4_hdr;
 	struct ipv6_hdr *ipv6_hdr;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
-	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+	tcp_or_udp = pkt->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = pkt->packet_type & RTE_PTYPE_L3_MASK;
+
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
@@ -59,7 +64,7 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 
 		return next_hop;
 
-	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 
 		/* Handle IPv6 headers.*/
 		ipv6_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv6_hdr *,
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index a354797..a53d508 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -285,6 +285,71 @@ setup_lpm(const int socketid)
 	}
 }
 
+int
+lpm_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_ptype_info(portid, RTE_PTYPE_L3_MASK,
+					 ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+
+}
+
+static inline void
+lpm_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+
+	m->packet_type = packet_type;
+}
+
+uint16_t
+lpm_cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+		   struct rte_mbuf *pkts[], uint16_t nb_pkts,
+		   uint16_t max_pkts __rte_unused,
+		   void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		lpm_parse_ptype(pkts[i]);
+
+	return nb_pkts;
+}
+
 /* Return ipv4/ipv6 lpm fwd lookup struct. */
 void *
 lpm_get_ipv4_l3fwd_lookup_struct(const int socketid)
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 0e33039..0a1a0cc 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -103,6 +103,8 @@ static int l3fwd_lpm_on;
 static int l3fwd_em_on;
 
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 /* Global variables. */
 
@@ -172,6 +174,8 @@ static struct rte_mempool * pktmbuf_pool[NB_SOCKETS];
 
 struct l3fwd_lkp_mode {
 	void  (*setup)(int);
+	int   (*check_ptype)(int);
+	rte_rx_callback_fn cb_parse_ptype;
 	int   (*main_loop)(void *);
 	void* (*get_ipv4_lookup_struct)(int);
 	void* (*get_ipv6_lookup_struct)(int);
@@ -181,6 +185,8 @@ static struct l3fwd_lkp_mode l3fwd_lkp;
 
 static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 	.setup                  = setup_hash,
+	.check_ptype		= em_check_ptype,
+	.cb_parse_ptype		= em_cb_parse_ptype,
 	.main_loop              = em_main_loop,
 	.get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
@@ -188,6 +194,8 @@ static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 
 static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
 	.setup                  = setup_lpm,
+	.check_ptype		= lpm_check_ptype,
+	.cb_parse_ptype		= lpm_cb_parse_ptype,
 	.main_loop              = lpm_main_loop,
 	.get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
@@ -456,6 +464,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -486,6 +495,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -612,6 +622,14 @@ parse_args(int argc, char **argv)
 					return -1;
 				}
 			}
+
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -779,6 +797,28 @@ signal_handler(int signum)
 	}
 }
 
+static int
+prepare_ptype_parser(uint8_t portid, uint16_t queueid)
+{
+	if (parse_ptype) {
+		printf("Port %d: softly parse packet type info\n", portid);
+		if (rte_eth_add_rx_callback(portid, queueid,
+					    l3fwd_lkp.cb_parse_ptype,
+					    NULL))
+			return 1;
+
+		printf("Failed to add rx callback: port=%d\n", portid);
+		return 0;
+	}
+
+	if (l3fwd_lkp.check_ptype(portid))
+		return 1;
+
+	printf("port %d cannot parse packet type, please add --%s\n",
+	       portid, CMD_LINE_OPT_PARSE_PTYPE);
+	return 0;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -965,6 +1005,21 @@ main(int argc, char **argv)
 			rte_eth_promiscuous_enable(portid);
 	}
 
+	printf("\n");
+
+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+		if (rte_lcore_is_enabled(lcore_id) == 0)
+			continue;
+		qconf = &lcore_conf[lcore_id];
+		for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
+			portid = qconf->rx_queue_list[queue].port_id;
+			queueid = qconf->rx_queue_list[queue].queue_id;
+			if (prepare_ptype_parser(portid, queueid) == 0)
+				rte_exit(EXIT_FAILURE, "ptype check fails\n");
+		}
+	}
+
+
 	check_all_ports_link_status((uint8_t)nb_ports, enabled_port_mask);
 
 	ret = 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v3 2/2] config: enable vector driver by default
  2016-03-10  5:50   ` [PATCH v3 0/2] " Jianfeng Tan
  2016-03-10  5:50     ` [PATCH v3 1/2] " Jianfeng Tan
@ 2016-03-10  5:50     ` Jianfeng Tan
  2016-03-10 14:26     ` [PATCH v3 0/2] examples/l3fwd: fix using packet type blindly Ananyev, Konstantin
  2 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-10  5:50 UTC (permalink / raw)
  To: dev

Previously, vector driver is not the first (default) choice for i40e,
as it cannot fill packet type info for l3fwd to work well. Now there
is an option for l3fwd to analysis packet type softly. So enable it
by default.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 config/common_base                     | 2 +-
 doc/guides/rel_notes/release_16_04.rst | 5 +++++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/config/common_base b/config/common_base
index c73f71a..e6117b3 100644
--- a/config/common_base
+++ b/config/common_base
@@ -169,7 +169,7 @@ CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
 CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
 CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
+CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=y
 CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
 CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
 CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index f0bd3cb..19913b1 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -115,6 +115,11 @@ Drivers
   This made impossible the creation of more than one aesni_mb device
   from command line.
 
+* **i40e: enable vector driver by default.**
+
+  Previously, vector driver is disabled by default as it cannot fill packet type
+  info for l3fwd to work well. Now there is an option for l3fwd to analysis packet
+  type softly, so enable vector driver by default.
 
 Libraries
 ~~~~~~~~~
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v3 0/2] examples/l3fwd: fix using packet type blindly
  2016-03-10  5:50   ` [PATCH v3 0/2] " Jianfeng Tan
  2016-03-10  5:50     ` [PATCH v3 1/2] " Jianfeng Tan
  2016-03-10  5:50     ` [PATCH v3 2/2] config: enable vector driver by default Jianfeng Tan
@ 2016-03-10 14:26     ` Ananyev, Konstantin
  2 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-03-10 14:26 UTC (permalink / raw)
  To: Tan, Jianfeng, dev


> From: Tan, Jianfeng
> Sent: Thursday, March 10, 2016 5:51 AM
> To: dev@dpdk.org
> Cc: Zhang, Helin; Ananyev, Konstantin; nelio.laranjeiro@6wind.com; adrien.mazarguil@6wind.com; rahul.lakkireddy@chelsio.com;
> pmatilai@redhat.com; Tan, Jianfeng
> Subject: [PATCH v3 0/2] examples/l3fwd: fix using packet type blindly
> 
> This patch will work on below patch series.
>  - [PATCH v7 00/11] Add API to get packet type info
> 
> v3:
>  - em ptype check: (l4_tcp || l4_udp) -> (l4_tcp && l4_udp).
>  - avoid rte_be_to_cpu_16 for each packet by adding proper macros.
>  - with --parse-ptype specified, use sw parser mandatorily.
>  - enable i40e vector driver by default.
> 
> v2:
>  - Add patchset dependence in commit log.
>  - Change hardcoded 0 to RTE_PTYPE_UNKNOWN.
>  - More accurate em_parse_type.
>  - Add restrictions in EM forwarding functions.
>  - Define cb directly to avoid too many function calls when do analyze.
>  - Some typo fixed.
>  - Change the position to call rte_eth_dev_get_ptype_info
>    after rte_eth_dev_start().
> 
> Patch 1: add an option in l3fwd.
> Patch 2: enable vector pmd in i40e by default.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> 
> Jianfeng Tan (2):
>   examples/l3fwd: fix using packet type blindly
>   config: enable i40e vector driver by default
> 
>  config/common_base                      |   2 +-
>  doc/guides/rel_notes/release_16_04.rst  |  14 ++++
>  doc/guides/sample_app_ug/l3_forward.rst |   6 +-
>  examples/l3fwd/l3fwd.h                  |  14 ++++
>  examples/l3fwd/l3fwd_em.c               | 112 ++++++++++++++++++++++++++++++++
>  examples/l3fwd/l3fwd_em.h               |  10 ++-
>  examples/l3fwd/l3fwd_em_hlm_sse.h       |  17 +++--
>  examples/l3fwd/l3fwd_em_sse.h           |   9 ++-
>  examples/l3fwd/l3fwd_lpm.c              |  65 ++++++++++++++++++
>  examples/l3fwd/main.c                   |  55 ++++++++++++++++
>  10 files changed, 293 insertions(+), 11 deletions(-)
> 

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v7 01/11] ethdev: add API to query packet type filling info
  2016-03-09 19:31   ` [PATCH v7 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
@ 2016-03-10 14:28     ` Bruce Richardson
  2016-03-14  9:44     ` Thomas Monjalon
  1 sibling, 0 replies; 202+ messages in thread
From: Bruce Richardson @ 2016-03-10 14:28 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

On Thu, Mar 10, 2016 at 03:31:25AM +0800, Jianfeng Tan wrote:
> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
> type can be filled by given already started device or its pmd rx burst
> function has already been decided).
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> ---
>  doc/guides/rel_notes/release_16_04.rst |  3 +++
>  lib/librte_ether/rte_ethdev.c          | 26 ++++++++++++++++++++++++++
>  lib/librte_ether/rte_ethdev.h          | 27 +++++++++++++++++++++++++++
>  lib/librte_ether/rte_ether_version.map |  8 ++++++++
>  4 files changed, 64 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
> index aa9eabc..376ece5 100644
> --- a/doc/guides/rel_notes/release_16_04.rst
> +++ b/doc/guides/rel_notes/release_16_04.rst
> @@ -162,6 +162,9 @@ This section should contain API changes. Sample format:
>    handlers are updated: the pipeline parameter is added,
>    the packets mask parameter has been either removed or made input-only.
>  
> +* A new API ``rte_eth_dev_get_ptype_info`` is added to query what packet types
> +  can be filled by given already started device.
> +
>  

Do we fill in API additions into this section? No other patches add such
additions here - only changes. Therefore, I think this should be dropped from
the patch.

 <snip> 
>  /**
> + * Retrieve the packet type information of an Ethernet device.
> + *
> + * @note
> + *   Better to invoke this API after the device is already started or rx burst
> + *   function is decided, to obtain concise ptype information.

s/consise/correct/ ??

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v7 04/11] pmd/enic: add dev_ptype_info_get implementation
  2016-03-09 19:31   ` [PATCH v7 04/11] pmd/enic: " Jianfeng Tan
@ 2016-03-10 14:50     ` Bruce Richardson
  2016-03-10 14:51       ` Bruce Richardson
  0 siblings, 1 reply; 202+ messages in thread
From: Bruce Richardson @ 2016-03-10 14:50 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

On Thu, Mar 10, 2016 at 03:31:28AM +0800, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> ---
>  drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
I get compile errors when I apply this patch:

== Build drivers/net/enic
  CC enic_ethdev.o
/home/bruce/next-net/dpdk-next-net/drivers/net/enic/enic_ethdev.c:57:17: error: ‘enicpmd_recv_pkts’ used but never defined [-Werror]
 static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
                    ^
 compilation terminated due to -Wfatal-errors.

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v7 04/11] pmd/enic: add dev_ptype_info_get implementation
  2016-03-10 14:50     ` Bruce Richardson
@ 2016-03-10 14:51       ` Bruce Richardson
  2016-03-10 18:23         ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Bruce Richardson @ 2016-03-10 14:51 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

On Thu, Mar 10, 2016 at 02:50:04PM +0000, Bruce Richardson wrote:
> On Thu, Mar 10, 2016 at 03:31:28AM +0800, Jianfeng Tan wrote:
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> > Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> > ---
> >  drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
> >  1 file changed, 17 insertions(+)
> > 
> I get compile errors when I apply this patch:
> 
> == Build drivers/net/enic
>   CC enic_ethdev.o
> /home/bruce/next-net/dpdk-next-net/drivers/net/enic/enic_ethdev.c:57:17: error: ‘enicpmd_recv_pkts’ used but never defined [-Werror]
>  static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>                     ^
>  compilation terminated due to -Wfatal-errors.
> 

Sorry, forgot other details to reproduce. This error I see with gcc 5.3 on Fedora 23.

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v7 00/11] Add API to get packet type info
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
                     ` (10 preceding siblings ...)
  2016-03-09 19:31   ` [PATCH v7 11/11] pmd/vmxnet3: " Jianfeng Tan
@ 2016-03-10 14:55   ` Bruce Richardson
  11 siblings, 0 replies; 202+ messages in thread
From: Bruce Richardson @ 2016-03-10 14:55 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

On Thu, Mar 10, 2016 at 03:31:24AM +0800, Jianfeng Tan wrote:
> To achieve this, a new function pointer, dev_ptype_info_get, is added
> into struct eth_dev_ops. For those devices who do not implement it, it
> means it does not provide any ptype info.
> 

FYI: If doing a V8, please remove the "pmd/" from the prefixes of the titles.
It will save me removing them manually on apply. :-)

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v7 04/11] pmd/enic: add dev_ptype_info_get implementation
  2016-03-10 14:51       ` Bruce Richardson
@ 2016-03-10 18:23         ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-10 18:23 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev

Hi Bruce,

On 3/10/2016 10:51 PM, Bruce Richardson wrote:
> On Thu, Mar 10, 2016 at 02:50:04PM +0000, Bruce Richardson wrote:
>> On Thu, Mar 10, 2016 at 03:31:28AM +0800, Jianfeng Tan wrote:
>>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>>> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
>>> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
>>> ---
>>>   drivers/net/enic/enic_ethdev.c | 17 +++++++++++++++++
>>>   1 file changed, 17 insertions(+)
>>>
>> I get compile errors when I apply this patch:
>>
>> == Build drivers/net/enic
>>    CC enic_ethdev.o
>> /home/bruce/next-net/dpdk-next-net/drivers/net/enic/enic_ethdev.c:57:17: error: ‘enicpmd_recv_pkts’ used but never defined [-Werror]
>>   static uint16_t enicpmd_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
>>                      ^
>>   compilation terminated due to -Wfatal-errors.
>>
> Sorry, forgot other details to reproduce. This error I see with gcc 5.3 on Fedora 23.

That's strange, I tested in VM + Fedora 23 + GCC 5.3.1, and I did not 
see this error. (I cannot find a GCC 5.3.0 package for now). Maybe need 
more investigation.

Thanks,
Jianfeng

>
> /Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v8 00/11] Add API to get supported packet types
  2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
                   ` (20 preceding siblings ...)
  2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
@ 2016-03-14  7:42 ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 01/11] ethdev: add API to query " Jianfeng Tan
                     ` (11 more replies)
  21 siblings, 12 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

To achieve this, a new function pointer, dev_supported_ptypes_get, is added
into struct eth_dev_ops. For those devices who do not implement it, it
means it does not support any ptypes.

v8:
  - Rebased on dpdk-next-net/rel_16_04 branch.
  - Rename ptypes_info -> supported_ptypes.
  - Abandon info about newly added API in release_16_04.rst.
  - concise -> correct.

v7:
  - 2.2 -> 16.04
  - Add note: this API better invoked after device is already started.
  - Update release_16_04.rst for newly added API.

v6:
  - Remove extern in function declaration.
  - Update rte_ether_version.map.

v5:
  - Exclude l3fwd change from this series, as a separated one.
  - Fix malposition of mlx4 code in mlx5 commit introduced in v4.

v4:
  - Change how to use this API: to previously agreement reached in mail.

v3:
  - Change how to use this API: api to allocate mem for storing ptype
    array; and caller to free the mem.
  - Change how to return back ptypes from PMDs: return a pointer to
    corresponding static const array of supported ptypes, terminated
    by RTE_PTYPE_UNKNOWN.
  - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
  - Fix l3fwd memory leak when calling the API.

v2:
  - Move ptype_mask filter function from each PMDs into ether layer.
  - Add ixgbe vPMD's ptype info.
  - Fix code style issues.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>

Jianfeng Tan (11):
  ethdev: add API to query supported packet types
  cxgbe: add dev_supported_ptypes_get implementation
  e1000: add dev_supported_ptypes_get implementation
  enic: add dev_supported_ptypes_get implementation
  fm10k: add dev_supported_ptypes_get implementation
  i40e: add dev_supported_ptypes_get implementation
  ixgbe: add dev_supported_ptypes_get implementation
  mlx4: add dev_supported_ptypes_get implementation
  mlx5: add dev_supported_ptypes_get implementation
  nfp: add dev_supported_ptypes_get implementation
  vmxnet3: add dev_supported_ptypes_get implementation

 drivers/net/cxgbe/cxgbe_ethdev.c       | 15 ++++++++++
 drivers/net/e1000/igb_ethdev.c         | 30 ++++++++++++++++++++
 drivers/net/enic/enic_ethdev.c         | 14 ++++++++++
 drivers/net/fm10k/fm10k_ethdev.c       | 50 ++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c         |  3 ++
 drivers/net/fm10k/fm10k_rxtx_vec.c     |  3 ++
 drivers/net/i40e/i40e_ethdev.c         |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c      |  1 +
 drivers/net/i40e/i40e_rxtx.c           | 46 ++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h           |  1 +
 drivers/net/ixgbe/ixgbe_ethdev.c       | 38 ++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h       |  3 ++
 drivers/net/ixgbe/ixgbe_rxtx.c         |  4 ++-
 drivers/net/mlx4/mlx4.c                | 21 ++++++++++++++
 drivers/net/mlx5/mlx5.c                |  1 +
 drivers/net/mlx5/mlx5.h                |  1 +
 drivers/net/mlx5/mlx5_ethdev.c         | 20 ++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c           |  2 ++
 drivers/net/nfp/nfp_net.c              | 19 +++++++++++++
 drivers/net/vmxnet3/vmxnet3_ethdev.c   | 17 ++++++++++++
 lib/librte_ether/rte_ethdev.c          | 27 ++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 27 ++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  5 ++++
 23 files changed, 347 insertions(+), 2 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v8 01/11] ethdev: add API to query supported packet types
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14 17:14     ` Ferruh Yigit
  2016-03-14  7:42   ` [PATCH v8 02/11] cxgbe: add dev_supported_ptypes_get implementation Jianfeng Tan
                     ` (10 subsequent siblings)
  11 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Add a new API rte_eth_dev_get_supported_ptypes to query what packet types
can be filled by given already started device (or its pmd rx burst function
has already been decided).

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 lib/librte_ether/rte_ethdev.c          | 27 +++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 27 +++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  5 +++++
 3 files changed, 59 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a6e83c1..52fb62c 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1616,6 +1616,33 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
+				 uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get,
+				-ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e2893ba..7770f24 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_supported_ptypes_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get supported ptypes of an Ethernet device. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_supported_ptypes_get_t dev_supported_ptypes_get; /** Get supported ptypes */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2270,6 +2274,29 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the supported packet types of an Ethernet device.
+ *
+ * @note
+ *   Better to invoke this API after the device is already started or rx burst
+ *   function is decided, to obtain correct supported ptypes.
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of supported ptypes. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
+				     uint32_t *ptypes, int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..0f00dcb 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,8 @@ DPDK_2.2 {
 
 	local: *;
 };
+DPDK_16.04 {
+	rte_eth_dev_get_supported_ptypes;
+
+	local: *;
+} DPDK_2.2;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 02/11] cxgbe: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 01/11] ethdev: add API to query " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 03/11] e1000: " Jianfeng Tan
                     ` (9 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/cxgbe/cxgbe_ethdev.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 8c6dd59..1ee80b0 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -767,6 +767,20 @@ static int cxgbe_flow_ctrl_set(struct rte_eth_dev *eth_dev,
 			     &pi->link_cfg);
 }
 
+static const uint32_t *
+cxgbe_dev_supported_ptypes_get(struct rte_eth_dev *eth_dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (eth_dev->rx_pkt_burst == cxgbe_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.dev_start		= cxgbe_dev_start,
 	.dev_stop		= cxgbe_dev_stop,
@@ -777,6 +791,7 @@ static struct eth_dev_ops cxgbe_eth_dev_ops = {
 	.allmulticast_disable	= cxgbe_dev_allmulticast_disable,
 	.dev_configure		= cxgbe_dev_configure,
 	.dev_infos_get		= cxgbe_dev_info_get,
+	.dev_supported_ptypes_get = cxgbe_dev_supported_ptypes_get,
 	.link_update		= cxgbe_dev_link_update,
 	.mtu_set		= cxgbe_dev_mtu_set,
 	.tx_queue_setup         = cxgbe_dev_tx_queue_setup,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 03/11] e1000: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 01/11] ethdev: add API to query " Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 02/11] cxgbe: add dev_supported_ptypes_get implementation Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 04/11] enic: " Jianfeng Tan
                     ` (8 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/e1000/igb_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index f889876..413c794 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -104,6 +104,7 @@ static void eth_igb_stats_reset(struct rte_eth_dev *dev);
 static void eth_igb_xstats_reset(struct rte_eth_dev *dev);
 static void eth_igb_infos_get(struct rte_eth_dev *dev,
 			      struct rte_eth_dev_info *dev_info);
+static const uint32_t *eth_igb_supported_ptypes_get(struct rte_eth_dev *dev);
 static void eth_igbvf_infos_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
 static int  eth_igb_flow_ctrl_get(struct rte_eth_dev *dev,
@@ -324,6 +325,7 @@ static const struct eth_dev_ops eth_igb_ops = {
 	.stats_reset          = eth_igb_stats_reset,
 	.xstats_reset         = eth_igb_xstats_reset,
 	.dev_infos_get        = eth_igb_infos_get,
+	.dev_supported_ptypes_get = eth_igb_supported_ptypes_get,
 	.mtu_set              = eth_igb_mtu_set,
 	.vlan_filter_set      = eth_igb_vlan_filter_set,
 	.vlan_tpid_set        = eth_igb_vlan_tpid_set,
@@ -385,6 +387,7 @@ static const struct eth_dev_ops igbvf_eth_dev_ops = {
 	.xstats_reset         = eth_igbvf_stats_reset,
 	.vlan_filter_set      = igbvf_vlan_filter_set,
 	.dev_infos_get        = eth_igbvf_infos_get,
+	.dev_supported_ptypes_get = eth_igb_supported_ptypes_get,
 	.rx_queue_setup       = eth_igb_rx_queue_setup,
 	.rx_queue_release     = eth_igb_rx_queue_release,
 	.tx_queue_setup       = eth_igb_tx_queue_setup,
@@ -1919,6 +1922,33 @@ eth_igb_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->tx_desc_lim = tx_desc_lim;
 }
 
+static const uint32_t *
+eth_igb_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to igb_rxd_pkt_info_to_pkt_type() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == eth_igb_recv_pkts ||
+	    dev->rx_pkt_burst == eth_igb_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void
 eth_igbvf_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 04/11] enic: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 03/11] e1000: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 05/11] fm10k: " Jianfeng Tan
                     ` (7 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/enic/enic_ethdev.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 6f2ada5..bab0f7d 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -438,6 +438,19 @@ static void enicpmd_dev_info_get(struct rte_eth_dev *eth_dev,
 	};
 }
 
+static const uint32_t *enicpmd_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == enic_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void enicpmd_dev_promiscuous_enable(struct rte_eth_dev *eth_dev)
 {
 	struct enic *enic = pmd_priv(eth_dev);
@@ -561,6 +574,7 @@ static const struct eth_dev_ops enicpmd_eth_dev_ops = {
 	.stats_reset          = enicpmd_dev_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get        = enicpmd_dev_info_get,
+	.dev_supported_ptypes_get = enicpmd_dev_supported_ptypes_get,
 	.mtu_set              = NULL,
 	.vlan_filter_set      = enicpmd_vlan_filter_set,
 	.vlan_tpid_set        = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 05/11] fm10k: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (3 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 04/11] enic: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 06/11] i40e: " Jianfeng Tan
                     ` (6 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/fm10k/fm10k_ethdev.c   | 50 ++++++++++++++++++++++++++++++++++++++
 drivers/net/fm10k/fm10k_rxtx.c     |  3 +++
 drivers/net/fm10k/fm10k_rxtx_vec.c |  3 +++
 3 files changed, 56 insertions(+)

diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 4b07a8b..b510487 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1412,6 +1412,55 @@ fm10k_dev_infos_get(struct rte_eth_dev *dev,
 	};
 }
 
+#ifdef RTE_LIBRTE_FM10K_RX_OLFLAGS_ENABLE
+static const uint32_t *
+fm10k_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	if (dev->rx_pkt_burst == fm10k_recv_pkts ||
+	    dev->rx_pkt_burst == fm10k_recv_scattered_pkts) {
+		static uint32_t ptypes[] = {
+			/* refers to rx_desc_to_ol_flags() */
+			RTE_PTYPE_L2_ETHER,
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes;
+	} else if (dev->rx_pkt_burst == fm10k_recv_pkts_vec ||
+		   dev->rx_pkt_burst == fm10k_recv_scattered_pkts_vec) {
+		static uint32_t ptypes_vec[] = {
+			/* refers to fm10k_desc_to_pktype_v() */
+			RTE_PTYPE_L3_IPV4,
+			RTE_PTYPE_L3_IPV4_EXT,
+			RTE_PTYPE_L3_IPV6,
+			RTE_PTYPE_L3_IPV6_EXT,
+			RTE_PTYPE_L4_TCP,
+			RTE_PTYPE_L4_UDP,
+			RTE_PTYPE_TUNNEL_GENEVE,
+			RTE_PTYPE_TUNNEL_NVGRE,
+			RTE_PTYPE_TUNNEL_VXLAN,
+			RTE_PTYPE_TUNNEL_GRE,
+			RTE_PTYPE_UNKNOWN
+		};
+
+		return ptypes_vec;
+	}
+
+	return NULL;
+}
+#else
+static const uint32_t *
+fm10k_dev_supported_ptypes_get(struct rte_eth_dev *dev __rte_unused)
+{
+	return NULL;
+}
+#endif
+
 static int
 fm10k_vlan_filter_set(struct rte_eth_dev *dev, uint16_t vlan_id, int on)
 {
@@ -2578,6 +2627,7 @@ static const struct eth_dev_ops fm10k_eth_dev_ops = {
 	.xstats_reset		= fm10k_stats_reset,
 	.link_update		= fm10k_link_update,
 	.dev_infos_get		= fm10k_dev_infos_get,
+	.dev_supported_ptypes_get = fm10k_dev_supported_ptypes_get,
 	.vlan_filter_set	= fm10k_vlan_filter_set,
 	.vlan_offload_set	= fm10k_vlan_offload_set,
 	.mac_addr_add		= fm10k_macaddr_add,
diff --git a/drivers/net/fm10k/fm10k_rxtx.c b/drivers/net/fm10k/fm10k_rxtx.c
index 66db5b6..81ed4e7 100644
--- a/drivers/net/fm10k/fm10k_rxtx.c
+++ b/drivers/net/fm10k/fm10k_rxtx.c
@@ -65,6 +65,9 @@ static inline void dump_rxd(union fm10k_rx_desc *rxd)
 }
 #endif
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_supported_ptypes_get()
+ */
 static inline void
 rx_desc_to_ol_flags(struct rte_mbuf *m, const union fm10k_rx_desc *d)
 {
diff --git a/drivers/net/fm10k/fm10k_rxtx_vec.c b/drivers/net/fm10k/fm10k_rxtx_vec.c
index 1c78725..f8efe8f 100644
--- a/drivers/net/fm10k/fm10k_rxtx_vec.c
+++ b/drivers/net/fm10k/fm10k_rxtx_vec.c
@@ -149,6 +149,9 @@ fm10k_desc_to_olflags_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 	rx_pkts[3]->ol_flags = vol.e[3];
 }
 
+/* @note: When this function is changed, make corresponding change to
+ * fm10k_dev_supported_ptypes_get().
+ */
 static inline void
 fm10k_desc_to_pktype_v(__m128i descs[4], struct rte_mbuf **rx_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 06/11] i40e: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (4 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 05/11] fm10k: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 07/11] ixgbe: " Jianfeng Tan
                     ` (5 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/i40e/i40e_ethdev.c    |  1 +
 drivers/net/i40e/i40e_ethdev_vf.c |  1 +
 drivers/net/i40e/i40e_rxtx.c      | 46 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_rxtx.h      |  1 +
 4 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index b05d9cd..81f1104 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -443,6 +443,7 @@ static const struct eth_dev_ops i40e_eth_dev_ops = {
 	.xstats_reset                 = i40e_dev_stats_reset,
 	.queue_stats_mapping_set      = i40e_dev_queue_stats_mapping_set,
 	.dev_infos_get                = i40e_dev_info_get,
+	.dev_supported_ptypes_get     = i40e_dev_supported_ptypes_get,
 	.vlan_filter_set              = i40e_vlan_filter_set,
 	.vlan_tpid_set                = i40e_vlan_tpid_set,
 	.vlan_offload_set             = i40e_vlan_offload_set,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 6b7b350..510191e 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -201,6 +201,7 @@ static const struct eth_dev_ops i40evf_eth_dev_ops = {
 	.xstats_reset         = i40evf_dev_xstats_reset,
 	.dev_close            = i40evf_dev_close,
 	.dev_infos_get        = i40evf_dev_info_get,
+	.dev_supported_ptypes_get = i40e_dev_supported_ptypes_get,
 	.vlan_filter_set      = i40evf_vlan_filter_set,
 	.vlan_offload_set     = i40evf_vlan_offload_set,
 	.vlan_pvid_set        = i40evf_vlan_pvid_set,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index f8efdce..8a260c5 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -194,7 +194,10 @@ i40e_get_iee15888_flags(struct rte_mbuf *mb, uint64_t qword)
 }
 #endif
 
-/* For each value it means, datasheet of hardware can tell more details */
+/* For each value it means, datasheet of hardware can tell more details
+ *
+ * @note: fix i40e_dev_supported_ptypes_get() if any change here.
+ */
 static inline uint32_t
 i40e_rxd_pkt_type_mapping(uint8_t ptype)
 {
@@ -2093,6 +2096,47 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id)
 	return 0;
 }
 
+const uint32_t *
+i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to i40e_rxd_pkt_type_mapping() */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L2_ETHER_TIMESYNC,
+		RTE_PTYPE_L2_ETHER_LLDP,
+		RTE_PTYPE_L2_ETHER_ARP,
+		RTE_PTYPE_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_L4_FRAG,
+		RTE_PTYPE_L4_ICMP,
+		RTE_PTYPE_L4_NONFRAG,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_GRENAT,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L2_ETHER,
+		RTE_PTYPE_INNER_L2_ETHER_VLAN,
+		RTE_PTYPE_INNER_L3_IPV4_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L3_IPV6_EXT_UNKNOWN,
+		RTE_PTYPE_INNER_L4_FRAG,
+		RTE_PTYPE_INNER_L4_ICMP,
+		RTE_PTYPE_INNER_L4_NONFRAG,
+		RTE_PTYPE_INNER_L4_SCTP,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == i40e_recv_pkts ||
+#ifdef RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC
+	    dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
+#endif
+	    dev->rx_pkt_burst == i40e_recv_scattered_pkts)
+		return ptypes;
+	return NULL;
+}
+
 int
 i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			uint16_t queue_idx,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 5c2f5c2..98179f0 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -200,6 +200,7 @@ int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
 int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
 int i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id);
+const uint32_t *i40e_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 int i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			    uint16_t queue_idx,
 			    uint16_t nb_desc,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 07/11] ixgbe: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (5 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 06/11] i40e: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 08/11] mlx4: " Jianfeng Tan
                     ` (4 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/ixgbe/ixgbe_ethdev.h |  3 +++
 drivers/net/ixgbe/ixgbe_rxtx.c   |  4 +++-
 3 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index afe6582..7a3b3aa 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -172,6 +172,7 @@ static int ixgbe_dev_queue_stats_mapping_set(struct rte_eth_dev *eth_dev,
 					     uint8_t is_rx);
 static void ixgbe_dev_info_get(struct rte_eth_dev *dev,
 			       struct rte_eth_dev_info *dev_info);
+static const uint32_t *ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static void ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 				 struct rte_eth_dev_info *dev_info);
 static int ixgbe_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu);
@@ -436,6 +437,7 @@ static const struct eth_dev_ops ixgbe_eth_dev_ops = {
 	.xstats_reset         = ixgbe_dev_xstats_reset,
 	.queue_stats_mapping_set = ixgbe_dev_queue_stats_mapping_set,
 	.dev_infos_get        = ixgbe_dev_info_get,
+	.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
 	.mtu_set              = ixgbe_dev_mtu_set,
 	.vlan_filter_set      = ixgbe_vlan_filter_set,
 	.vlan_tpid_set        = ixgbe_vlan_tpid_set,
@@ -522,6 +524,7 @@ static const struct eth_dev_ops ixgbevf_eth_dev_ops = {
 	.allmulticast_enable  = ixgbevf_dev_allmulticast_enable,
 	.allmulticast_disable = ixgbevf_dev_allmulticast_disable,
 	.dev_infos_get        = ixgbevf_dev_info_get,
+	.dev_supported_ptypes_get = ixgbe_dev_supported_ptypes_get,
 	.mtu_set              = ixgbevf_dev_set_mtu,
 	.vlan_filter_set      = ixgbevf_vlan_filter_set,
 	.vlan_strip_queue_set = ixgbevf_vlan_strip_queue_set,
@@ -2867,6 +2870,41 @@ ixgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->flow_type_rss_offloads = IXGBE_RSS_OFFLOAD_ALL;
 }
 
+static const uint32_t *
+ixgbe_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* For non-vec functions,
+		 * refers to ixgbe_rxd_pkt_info_to_pkt_type();
+		 * for vec functions,
+		 * refers to _recv_raw_pkts_vec().
+		 */
+		RTE_PTYPE_L2_ETHER,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_L3_IPV6_EXT,
+		RTE_PTYPE_L4_SCTP,
+		RTE_PTYPE_L4_TCP,
+		RTE_PTYPE_L4_UDP,
+		RTE_PTYPE_TUNNEL_IP,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_TCP,
+		RTE_PTYPE_INNER_L4_UDP,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == ixgbe_recv_pkts ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_single_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_lro_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_bulk_alloc ||
+	    dev->rx_pkt_burst == ixgbe_recv_pkts_vec ||
+	    dev->rx_pkt_burst == ixgbe_recv_scattered_pkts_vec)
+		return ptypes;
+	return NULL;
+}
+
 static void
 ixgbevf_dev_info_get(struct rte_eth_dev *dev,
 		     struct rte_eth_dev_info *dev_info)
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.h b/drivers/net/ixgbe/ixgbe_ethdev.h
index 5c3aa16..b75e795 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.h
+++ b/drivers/net/ixgbe/ixgbe_ethdev.h
@@ -380,6 +380,9 @@ void ixgbevf_dev_rxtx_start(struct rte_eth_dev *dev);
 uint16_t ixgbe_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		uint16_t nb_pkts);
 
+uint16_t ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
+				    uint16_t nb_pkts);
+
 uint16_t ixgbe_recv_pkts_lro_single_alloc(void *rx_queue,
 		struct rte_mbuf **rx_pkts, uint16_t nb_pkts);
 uint16_t ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue,
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index fd98f62..655fa05 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -907,6 +907,8 @@ end_of_tx:
 #define IXGBE_PACKET_TYPE_MAX               0X80
 #define IXGBE_PACKET_TYPE_MASK              0X7F
 #define IXGBE_PACKET_TYPE_SHIFT             0X04
+
+/* @note: fix ixgbe_dev_supported_ptypes_get() if any change here. */
 static inline uint32_t
 ixgbe_rxd_pkt_info_to_pkt_type(uint16_t pkt_info)
 {
@@ -1255,7 +1257,7 @@ rx_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 }
 
 /* split requests into chunks of size RTE_PMD_IXGBE_RX_MAX_BURST */
-static uint16_t
+uint16_t
 ixgbe_recv_pkts_bulk_alloc(void *rx_queue, struct rte_mbuf **rx_pkts,
 			   uint16_t nb_pkts)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 08/11] mlx4: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (6 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 07/11] ixgbe: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 09/11] mlx5: " Jianfeng Tan
                     ` (3 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/mlx4/mlx4.c | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 67025c7..61ecf08 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -2876,6 +2876,8 @@ rxq_cleanup(struct rxq *rxq)
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx4_dev_supported_ptypes_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
@@ -4304,6 +4306,24 @@ mlx4_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+static const uint32_t *
+mlx4_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == mlx4_rx_burst ||
+	    dev->rx_pkt_burst == mlx4_rx_burst_sp)
+		return ptypes;
+	return NULL;
+}
+
 /**
  * DPDK callback to get device statistics.
  *
@@ -5041,6 +5061,7 @@ static const struct eth_dev_ops mlx4_dev_ops = {
 	.stats_reset = mlx4_stats_reset,
 	.queue_stats_mapping_set = NULL,
 	.dev_infos_get = mlx4_dev_infos_get,
+	.dev_supported_ptypes_get = mlx4_dev_supported_ptypes_get,
 	.vlan_filter_set = mlx4_vlan_filter_set,
 	.vlan_tpid_set = NULL,
 	.vlan_strip_queue_set = NULL,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 09/11] mlx5: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (7 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 08/11] mlx4: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 10/11] nfp: " Jianfeng Tan
                     ` (2 subsequent siblings)
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/mlx5/mlx5.c        |  1 +
 drivers/net/mlx5/mlx5.h        |  1 +
 drivers/net/mlx5/mlx5_ethdev.c | 20 ++++++++++++++++++++
 drivers/net/mlx5/mlx5_rxtx.c   |  2 ++
 4 files changed, 24 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index ad69ec2..8e2c909 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -157,6 +157,7 @@ static const struct eth_dev_ops mlx5_dev_ops = {
 	.stats_get = mlx5_stats_get,
 	.stats_reset = mlx5_stats_reset,
 	.dev_infos_get = mlx5_dev_infos_get,
+	.dev_supported_ptypes_get = mlx5_dev_supported_ptypes_get,
 	.vlan_filter_set = mlx5_vlan_filter_set,
 	.rx_queue_setup = mlx5_rx_queue_setup,
 	.tx_queue_setup = mlx5_tx_queue_setup,
diff --git a/drivers/net/mlx5/mlx5.h b/drivers/net/mlx5/mlx5.h
index 43b24fb..8b9b96e 100644
--- a/drivers/net/mlx5/mlx5.h
+++ b/drivers/net/mlx5/mlx5.h
@@ -158,6 +158,7 @@ int priv_get_mtu(struct priv *, uint16_t *);
 int priv_set_flags(struct priv *, unsigned int, unsigned int);
 int mlx5_dev_configure(struct rte_eth_dev *);
 void mlx5_dev_infos_get(struct rte_eth_dev *, struct rte_eth_dev_info *);
+const uint32_t *mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 int mlx5_link_update(struct rte_eth_dev *, int);
 int mlx5_dev_set_mtu(struct rte_eth_dev *, uint16_t);
 int mlx5_dev_get_flow_ctrl(struct rte_eth_dev *, struct rte_eth_fc_conf *);
diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 6704382..50551ea 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -525,6 +525,26 @@ mlx5_dev_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *info)
 	priv_unlock(priv);
 }
 
+const uint32_t *
+mlx5_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to rxq_cq_to_pkt_type() */
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_UNKNOWN
+
+	};
+
+	if (dev->rx_pkt_burst == mlx5_rx_burst ||
+	    dev->rx_pkt_burst == mlx5_rx_burst_sp)
+		return ptypes;
+	return NULL;
+
+}
+
 /**
  * DPDK callback to retrieve physical link information (unlocked version).
  *
diff --git a/drivers/net/mlx5/mlx5_rxtx.c b/drivers/net/mlx5/mlx5_rxtx.c
index 4919189..0128139 100644
--- a/drivers/net/mlx5/mlx5_rxtx.c
+++ b/drivers/net/mlx5/mlx5_rxtx.c
@@ -670,6 +670,8 @@ stop:
  * @param flags
  *   RX completion flags returned by poll_length_flags().
  *
+ * @note: fix mlx5_dev_supported_ptypes_get() if any change here.
+ *
  * @return
  *   Packet type for struct rte_mbuf.
  */
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 10/11] nfp: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (8 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 09/11] mlx5: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-14  7:42   ` [PATCH v8 11/11] vmxnet3: " Jianfeng Tan
  2016-03-18 16:21   ` [PATCH v8 00/11] Add API to get supported packet types Bruce Richardson
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/nfp/nfp_net.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 573b6bc..163cac8 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -1063,6 +1063,24 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->hash_key_size = NFP_NET_CFG_RSS_KEY_SZ;
 }
 
+static const uint32_t *
+nfp_net_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		/* refers to nfp_net_set_hash() */
+		RTE_PTYPE_INNER_L3_IPV4,
+		RTE_PTYPE_INNER_L3_IPV6,
+		RTE_PTYPE_INNER_L3_IPV6_EXT,
+		RTE_PTYPE_INNER_L4_MASK,
+		RTE_PTYPE_UNKNOWN
+	};
+
+
+	if (dev->rx_pkt_burst == nfp_net_recv_pkts)
+		return ptypes;
+	return num;
+}
+
 static uint32_t
 nfp_net_rx_queue_count(struct rte_eth_dev *dev, uint16_t queue_idx)
 {
@@ -2283,6 +2301,7 @@ static struct eth_dev_ops nfp_net_eth_dev_ops = {
 	.stats_get		= nfp_net_stats_get,
 	.stats_reset		= nfp_net_stats_reset,
 	.dev_infos_get		= nfp_net_infos_get,
+	.dev_supported_ptypes_get = nfp_net_supported_ptypes_get,
 	.mtu_set		= nfp_net_dev_mtu_set,
 	.vlan_offload_set	= nfp_net_vlan_offload_set,
 	.reta_update		= nfp_net_reta_update,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v8 11/11] vmxnet3: add dev_supported_ptypes_get implementation
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (9 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 10/11] nfp: " Jianfeng Tan
@ 2016-03-14  7:42   ` Jianfeng Tan
  2016-03-18 16:21   ` [PATCH v8 00/11] Add API to get supported packet types Bruce Richardson
  11 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14  7:42 UTC (permalink / raw)
  To: dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
 drivers/net/vmxnet3/vmxnet3_ethdev.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index a5c9ba5..f2b6b92 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -86,6 +86,8 @@ static void vmxnet3_dev_stats_get(struct rte_eth_dev *dev,
 				struct rte_eth_stats *stats);
 static void vmxnet3_dev_info_get(struct rte_eth_dev *dev,
 				struct rte_eth_dev_info *dev_info);
+static const uint32_t *
+vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev);
 static int vmxnet3_dev_vlan_filter_set(struct rte_eth_dev *dev,
 				       uint16_t vid, int on);
 static void vmxnet3_dev_vlan_offload_set(struct rte_eth_dev *dev, int mask);
@@ -119,6 +121,7 @@ static const struct eth_dev_ops vmxnet3_eth_dev_ops = {
 	.stats_get            = vmxnet3_dev_stats_get,
 	.mac_addr_set	      = vmxnet3_mac_addr_set,
 	.dev_infos_get        = vmxnet3_dev_info_get,
+	.dev_supported_ptypes_get = vmxnet3_dev_supported_ptypes_get,
 	.vlan_filter_set      = vmxnet3_dev_vlan_filter_set,
 	.vlan_offload_set     = vmxnet3_dev_vlan_offload_set,
 	.rx_queue_setup       = vmxnet3_dev_rx_queue_setup,
@@ -734,6 +737,20 @@ vmxnet3_dev_info_get(__attribute__((unused))struct rte_eth_dev *dev,
 		DEV_TX_OFFLOAD_TCP_TSO;
 }
 
+static const uint32_t *
+vmxnet3_dev_supported_ptypes_get(struct rte_eth_dev *dev)
+{
+	static const uint32_t ptypes[] = {
+		RTE_PTYPE_L3_IPV4_EXT,
+		RTE_PTYPE_L3_IPV4,
+		RTE_PTYPE_UNKNOWN
+	};
+
+	if (dev->rx_pkt_burst == vmxnet3_recv_pkts)
+		return ptypes;
+	return NULL;
+}
+
 static void
 vmxnet3_mac_addr_set(struct rte_eth_dev *dev, struct ether_addr *mac_addr)
 {
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v7 01/11] ethdev: add API to query packet type filling info
  2016-03-09 19:31   ` [PATCH v7 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
  2016-03-10 14:28     ` Bruce Richardson
@ 2016-03-14  9:44     ` Thomas Monjalon
  2016-03-14  9:48       ` Bruce Richardson
  1 sibling, 1 reply; 202+ messages in thread
From: Thomas Monjalon @ 2016-03-14  9:44 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev

2016-03-10 03:31, Jianfeng Tan:
> Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
> type can be filled by given already started device or its pmd rx burst
> function has already been decided).
[...]
>  /**
> + * Retrieve the packet type information of an Ethernet device.
> + *
> + * @note
> + *   Better to invoke this API after the device is already started or rx burst
> + *   function is decided, to obtain concise ptype information.
> + * @param port_id
> + *   The port identifier of the Ethernet device.
> + * @param ptype_mask
> + *   A hint of what kind of packet type which the caller is interested in.
> + * @param ptypes
> + *   An array pointer to store adequent packet types, allocated by caller.
> + * @param num
> + *  Size of the array pointed by param ptypes.
> + * @return
> + *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
> + *          packet types will not be filled in the given array.
> + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> + *   - (-ENODEV) if *port_id* invalid.
> + */
> +int rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> +			       uint32_t *ptypes, int num);

I think the word info is too vague.
What do you think of these names?
- rte_eth_dev_get_ptype_capa
- rte_eth_dev_get_supported_ptypes

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v7 01/11] ethdev: add API to query packet type filling info
  2016-03-14  9:44     ` Thomas Monjalon
@ 2016-03-14  9:48       ` Bruce Richardson
  0 siblings, 0 replies; 202+ messages in thread
From: Bruce Richardson @ 2016-03-14  9:48 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Jianfeng Tan, dev

On Mon, Mar 14, 2016 at 10:44:30AM +0100, Thomas Monjalon wrote:
> 2016-03-10 03:31, Jianfeng Tan:
> > Add a new API rte_eth_dev_get_ptype_info to query whether/what packet
> > type can be filled by given already started device or its pmd rx burst
> > function has already been decided).
> [...]
> >  /**
> > + * Retrieve the packet type information of an Ethernet device.
> > + *
> > + * @note
> > + *   Better to invoke this API after the device is already started or rx burst
> > + *   function is decided, to obtain concise ptype information.
> > + * @param port_id
> > + *   The port identifier of the Ethernet device.
> > + * @param ptype_mask
> > + *   A hint of what kind of packet type which the caller is interested in.
> > + * @param ptypes
> > + *   An array pointer to store adequent packet types, allocated by caller.
> > + * @param num
> > + *  Size of the array pointed by param ptypes.
> > + * @return
> > + *   - (>0) Number of ptypes supported. If it exceeds param num, exceeding
> > + *          packet types will not be filled in the given array.
> > + *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> > + *   - (-ENODEV) if *port_id* invalid.
> > + */
> > +int rte_eth_dev_get_ptype_info(uint8_t port_id, uint32_t ptype_mask,
> > +			       uint32_t *ptypes, int num);
> 
> I think the word info is too vague.
> What do you think of these names?
> - rte_eth_dev_get_ptype_capa
> - rte_eth_dev_get_supported_ptypes
> 
+1 for supported_ptypes

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v8 01/11] ethdev: add API to query supported packet types
  2016-03-14  7:42   ` [PATCH v8 01/11] ethdev: add API to query " Jianfeng Tan
@ 2016-03-14 17:14     ` Ferruh Yigit
  2016-03-14 20:50       ` [PATCH v9 " Jianfeng Tan
  2016-03-15  1:42       ` [PATCH v8 " Tan, Jianfeng
  0 siblings, 2 replies; 202+ messages in thread
From: Ferruh Yigit @ 2016-03-14 17:14 UTC (permalink / raw)
  To: Jianfeng Tan, dev; +Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil

On 3/14/2016 7:42 AM, Jianfeng Tan wrote:
> Add a new API rte_eth_dev_get_supported_ptypes to query what packet types
> can be filled by given already started device (or its pmd rx burst function
> has already been decided).
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> ---

<...>

> +DPDK_16.04 {
> +	rte_eth_dev_get_supported_ptypes;
Other script files tends to put a blank line before function names.

> +
> +	local: *;
This line is not required.

> +} DPDK_2.2;
> 

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v9 01/11] ethdev: add API to query supported packet types
  2016-03-14 17:14     ` Ferruh Yigit
@ 2016-03-14 20:50       ` Jianfeng Tan
  2016-03-18  9:17         ` Tan, Jianfeng
  2016-03-15  1:42       ` [PATCH v8 " Tan, Jianfeng
  1 sibling, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-14 20:50 UTC (permalink / raw)
  To: dev
  Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, ferruh.yigit,
	Jianfeng Tan

Add a new API rte_eth_dev_get_supported_ptypes to query what packet types
can be filled by given already started device (or its pmd rx burst function
has already been decided).

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
---
v9:
 - Fix rte_ether_version.map as Ferruh Yigit sugguests.
 lib/librte_ether/rte_ethdev.c          | 27 +++++++++++++++++++++++++++
 lib/librte_ether/rte_ethdev.h          | 27 +++++++++++++++++++++++++++
 lib/librte_ether/rte_ether_version.map |  7 +++++++
 3 files changed, 61 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a6e83c1..52fb62c 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1616,6 +1616,33 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
 	dev_info->driver_name = dev->data->drv_name;
 }
 
+int
+rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
+				 uint32_t *ptypes, int num)
+{
+	int i, j;
+	struct rte_eth_dev *dev;
+	const uint32_t *all_ptypes;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+	dev = &rte_eth_devices[port_id];
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get,
+				-ENOTSUP);
+	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
+
+	if (!all_ptypes)
+		return 0;
+
+	for (i = 0, j = 0; all_ptypes[i] != RTE_PTYPE_UNKNOWN; ++i)
+		if (all_ptypes[i] & ptype_mask) {
+			if (j < num)
+				ptypes[j] = all_ptypes[i];
+			j++;
+		}
+
+	return j;
+}
+
 void
 rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr)
 {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e2893ba..7770f24 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1021,6 +1021,9 @@ typedef void (*eth_dev_infos_get_t)(struct rte_eth_dev *dev,
 				    struct rte_eth_dev_info *dev_info);
 /**< @internal Get specific informations of an Ethernet device. */
 
+typedef const uint32_t *(*eth_dev_supported_ptypes_get_t)(struct rte_eth_dev *dev);
+/**< @internal Get supported ptypes of an Ethernet device. */
+
 typedef int (*eth_queue_start_t)(struct rte_eth_dev *dev,
 				    uint16_t queue_id);
 /**< @internal Start rx and tx of a queue of an Ethernet device. */
@@ -1347,6 +1350,7 @@ struct eth_dev_ops {
 	eth_queue_stats_mapping_set_t queue_stats_mapping_set;
 	/**< Configure per queue stat counter mapping. */
 	eth_dev_infos_get_t        dev_infos_get; /**< Get device info. */
+	eth_dev_supported_ptypes_get_t dev_supported_ptypes_get; /** Get supported ptypes */
 	mtu_set_t                  mtu_set; /**< Set MTU. */
 	vlan_filter_set_t          vlan_filter_set;  /**< Filter VLAN Setup. */
 	vlan_tpid_set_t            vlan_tpid_set;      /**< Outer VLAN TPID Setup. */
@@ -2270,6 +2274,29 @@ void rte_eth_macaddr_get(uint8_t port_id, struct ether_addr *mac_addr);
 void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
 
 /**
+ * Retrieve the supported packet types of an Ethernet device.
+ *
+ * @note
+ *   Better to invoke this API after the device is already started or rx burst
+ *   function is decided, to obtain correct supported ptypes.
+ * @param port_id
+ *   The port identifier of the Ethernet device.
+ * @param ptype_mask
+ *   A hint of what kind of packet type which the caller is interested in.
+ * @param ptypes
+ *   An array pointer to store adequent packet types, allocated by caller.
+ * @param num
+ *  Size of the array pointed by param ptypes.
+ * @return
+ *   - (>0) Number of supported ptypes. If it exceeds param num, exceeding
+ *          packet types will not be filled in the given array.
+ *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (-ENODEV) if *port_id* invalid.
+ */
+int rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
+				     uint32_t *ptypes, int num);
+
+/**
  * Retrieve the MTU of an Ethernet device.
  *
  * @param port_id
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index d8db24d..c242e71 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -117,3 +117,10 @@ DPDK_2.2 {
 
 	local: *;
 };
+
+DPDK_16.04 {
+	global:
+
+	rte_eth_dev_get_supported_ptypes;
+
+} DPDK_2.2;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v8 01/11] ethdev: add API to query supported packet types
  2016-03-14 17:14     ` Ferruh Yigit
  2016-03-14 20:50       ` [PATCH v9 " Jianfeng Tan
@ 2016-03-15  1:42       ` Tan, Jianfeng
  1 sibling, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-15  1:42 UTC (permalink / raw)
  To: Ferruh Yigit, dev, Richardson, Bruce
  Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil

Hi,

On 3/15/2016 1:14 AM, Ferruh Yigit wrote:
> On 3/14/2016 7:42 AM, Jianfeng Tan wrote:
>> Add a new API rte_eth_dev_get_supported_ptypes to query what packet types
>> can be filled by given already started device (or its pmd rx burst function
>> has already been decided).
>>
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
>> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
>> ---
> <...>
>
>> +DPDK_16.04 {
>> +	rte_eth_dev_get_supported_ptypes;
> Other script files tends to put a blank line before function names.

Thank you for reminding.

>
>> +
>> +	local: *;
> This line is not required.

Yes, actually, this leads to compiling error when 
CONFIG_RTE_BUILD_SHARED_LIB=y.

Bruce, do you mind fix these two issues when applying the code (if 
there's no other issue)? Thanks.

Jianfeng

>
>> +} DPDK_2.2;
>>

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v9 01/11] ethdev: add API to query supported packet types
  2016-03-14 20:50       ` [PATCH v9 " Jianfeng Tan
@ 2016-03-18  9:17         ` Tan, Jianfeng
  0 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-18  9:17 UTC (permalink / raw)
  To: dev, Thomas Monjalon
  Cc: helin.zhang, konstantin.ananyev, adrien.mazarguil, ferruh.yigit

Hi Thomas,

On 3/15/2016 4:50 AM, Jianfeng Tan wrote:
> Add a new API rte_eth_dev_get_supported_ptypes to query what packet types
> can be filled by given already started device (or its pmd rx burst function
> has already been decided).
>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> ---
> v9:
>   - Fix rte_ether_version.map as Ferruh Yigit sugguests.
>   lib/librte_ether/rte_ethdev.c          | 27 +++++++++++++++++++++++++++
>   lib/librte_ether/rte_ethdev.h          | 27 +++++++++++++++++++++++++++
>   lib/librte_ether/rte_ether_version.map |  7 +++++++
>   3 files changed, 61 insertions(+)
...
> diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
> index d8db24d..c242e71 100644
> --- a/lib/librte_ether/rte_ether_version.map
> +++ b/lib/librte_ether/rte_ether_version.map
> @@ -117,3 +117,10 @@ DPDK_2.2 {
>   
>   	local: *;
>   };
> +
> +DPDK_16.04 {
> +	global:
> +
> +	rte_eth_dev_get_supported_ptypes;
> +
> +} DPDK_2.2;

Although this series is rebased on dpdk-next-net/rel_16_04, but applying 
this into v16.04-rc1 only needs to remove change in 
rte_ether_version.map. Shall I send a new version? Or this series will 
simply be deferred?

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v8 00/11] Add API to get supported packet types
  2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
                     ` (10 preceding siblings ...)
  2016-03-14  7:42   ` [PATCH v8 11/11] vmxnet3: " Jianfeng Tan
@ 2016-03-18 16:21   ` Bruce Richardson
  11 siblings, 0 replies; 202+ messages in thread
From: Bruce Richardson @ 2016-03-18 16:21 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, helin.zhang, konstantin.ananyev, adrien.mazarguil

On Mon, Mar 14, 2016 at 03:42:45PM +0800, Jianfeng Tan wrote:
> To achieve this, a new function pointer, dev_supported_ptypes_get, is added
> into struct eth_dev_ops. For those devices who do not implement it, it
> means it does not support any ptypes.
> 
> v8:
>   - Rebased on dpdk-next-net/rel_16_04 branch.
>   - Rename ptypes_info -> supported_ptypes.
>   - Abandon info about newly added API in release_16_04.rst.
>   - concise -> correct.
> 
> v7:
>   - 2.2 -> 16.04
>   - Add note: this API better invoked after device is already started.
>   - Update release_16_04.rst for newly added API.
> 
> v6:
>   - Remove extern in function declaration.
>   - Update rte_ether_version.map.
> 
> v5:
>   - Exclude l3fwd change from this series, as a separated one.
>   - Fix malposition of mlx4 code in mlx5 commit introduced in v4.
> 
> v4:
>   - Change how to use this API: to previously agreement reached in mail.
> 
> v3:
>   - Change how to use this API: api to allocate mem for storing ptype
>     array; and caller to free the mem.
>   - Change how to return back ptypes from PMDs: return a pointer to
>     corresponding static const array of supported ptypes, terminated
>     by RTE_PTYPE_UNKNOWN.
>   - Fix l3fwd parse_packet_type() when EXACT_MATCH is enabled.
>   - Fix l3fwd memory leak when calling the API.
> 
> v2:
>   - Move ptype_mask filter function from each PMDs into ether layer.
>   - Add ixgbe vPMD's ptype info.
>   - Fix code style issues.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
>
Applied to dpdk-next-net/rel_16_04, using v9 of patch 1 and v8 of all others.

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v4 0/3] packet type
  2016-03-01  1:23 ` [PATCH] examples/l3fwd: fix using packet type blindly Jianfeng Tan
                     ` (2 preceding siblings ...)
  2016-03-10  5:50   ` [PATCH v3 0/2] " Jianfeng Tan
@ 2016-03-25  0:47   ` Jianfeng Tan
  2016-03-25  0:47     ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Jianfeng Tan
                       ` (3 more replies)
  3 siblings, 4 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-25  0:47 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan, konstantin.ananyev, helin.zhang, bruce.richardson

This patch will work on below patch series.
 - [PATCH v9 01/11] Add API to get packet type info

v4:
 - refine the API to return 0 intead of ENOTSUP, and doc and note updated.
 - rte_eth_dev_get_ptype_info -> rte_eth_dev_get_supported_ptypes

v3:
 - em ptype check: (l4_tcp || l4_udp) -> (l4_tcp && l4_udp).
 - avoid rte_be_to_cpu_16 for each packet by adding proper macros.
 - with --parse-ptype specified, use sw parser mandatorily.
 - enable i40e vector driver by default.

v2:
 - Add patchset dependence in commit log.
 - Change hardcoded 0 to RTE_PTYPE_UNKNOWN.
 - More accurate em_parse_type.
 - Add restrictions in EM forwarding functions.
 - Define cb directly to avoid too many function calls when do analyze.
 - Some typo fixed.
 - Change the position to call rte_eth_dev_get_ptype_info
   after rte_eth_dev_start().

Patch 1: refine rte_eth_dev_get_supported_ptypes.
Patch 2: add an option in l3fwd.
Patch 3: enable vector pmd in i40e by default.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>


Jianfeng Tan (3):
  ethdev: refine API to query supported packet types
  examples/l3fwd: fix using packet type blindly
  config: enable vector driver by default

 config/common_base                      |   2 +-
 doc/guides/nics/overview.rst            |   2 +-
 doc/guides/rel_notes/release_16_04.rst  |  15 +++++
 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 examples/l3fwd/l3fwd.h                  |  14 ++++
 examples/l3fwd/l3fwd_em.c               | 109 ++++++++++++++++++++++++++++++++
 examples/l3fwd/l3fwd_em.h               |  10 ++-
 examples/l3fwd/l3fwd_em_hlm_sse.h       |  17 +++--
 examples/l3fwd/l3fwd_em_sse.h           |   9 ++-
 examples/l3fwd/l3fwd_lpm.c              |  65 +++++++++++++++++++
 examples/l3fwd/main.c                   |  55 ++++++++++++++++
 lib/librte_ether/rte_ethdev.c           |   3 +-
 lib/librte_ether/rte_ethdev.h           |   9 ++-
 13 files changed, 299 insertions(+), 17 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v4 1/3] ethdev: refine API to query supported packet types
  2016-03-25  0:47   ` [PATCH v4 0/3] packet type Jianfeng Tan
@ 2016-03-25  0:47     ` Jianfeng Tan
  2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
                         ` (2 more replies)
  2016-03-25  0:47     ` [PATCH v4 2/3] examples/l3fwd: fix using packet type blindly Jianfeng Tan
                       ` (2 subsequent siblings)
  3 siblings, 3 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-25  0:47 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan, konstantin.ananyev, helin.zhang, bruce.richardson

Return 0 instead of -ENOTSUP for those which do not fill any packet types,
with some note and doc updated.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 doc/guides/nics/overview.rst  | 2 +-
 lib/librte_ether/rte_ethdev.c | 3 +--
 lib/librte_ether/rte_ethdev.h | 9 ++++++---
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index 542479a..e7504da 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -124,7 +124,7 @@ Most of these differences are summarized below.
    L4 checksum offload          X   X   X   X
    inner L3 checksum                X   X   X
    inner L4 checksum                X   X   X
-   packet type parsing          X       X   X
+   packet type parsing  X X X X     X     X   X                     X   X X X X X X   X
    timesync                             X X
    basic stats                  X   X   X X X X                               X X
    extended stats                   X   X X X X
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a328027..1ee79d2 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1636,8 +1636,7 @@ rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get,
-				-ENOTSUP);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
 	if (!all_ptypes)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e7de34a..5167750 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -2326,6 +2326,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
  * @note
  *   Better to invoke this API after the device is already started or rx burst
  *   function is decided, to obtain correct supported ptypes.
+ * @note
+ *   if a given PMD does not report what ptypes it supports, then the supported
+ *   ptype count is reported as 0.
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param ptype_mask
@@ -2335,9 +2338,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
  * @param num
  *  Size of the array pointed by param ptypes.
  * @return
- *   - (>0) Number of supported ptypes. If it exceeds param num, exceeding
- *          packet types will not be filled in the given array.
- *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (>=0) Number of supported ptypes. If the number of types exceeds num,
+             only num entries will be filled into the ptypes array, but the full
+             count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
  */
 int rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 2/3] examples/l3fwd: fix using packet type blindly
  2016-03-25  0:47   ` [PATCH v4 0/3] packet type Jianfeng Tan
  2016-03-25  0:47     ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Jianfeng Tan
@ 2016-03-25  0:47     ` Jianfeng Tan
  2016-03-25 18:24       ` Thomas Monjalon
  2016-03-25  0:47     ` [PATCH v4 3/3] config: enable vector driver by default Jianfeng Tan
  2016-03-25 18:34     ` [PATCH v4 0/3] packet type Thomas Monjalon
  3 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-25  0:47 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan, konstantin.ananyev, helin.zhang, bruce.richardson

As a example to use ptype info, l3fwd needs firstly to use
rte_eth_dev_get_supported_ptypes() API to check if device and/or
its PMD driver will parse and fill the needed packet type; if not,
use the newly added option, --parse-ptype, to analyze it in the
callback softly.

As the mode of EXACT_MATCH uses the 5 tuples to caculate hash, so
we narrow down its scope to:
  a. ip packets with no extensions, and
  b. L4 payload should be either tcp or udp.

Note: this patch does not completely solve the issue, "cannot run
l3fwd on virtio or other devices", because hw_ip_checksum may be
not supported by the devices. Currently we can:
  a. remove this requirements, or
  b. wait for virtio front end (pmd) to support it.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 doc/guides/rel_notes/release_16_04.rst  |   9 +++
 doc/guides/sample_app_ug/l3_forward.rst |   6 +-
 examples/l3fwd/l3fwd.h                  |  14 ++++
 examples/l3fwd/l3fwd_em.c               | 109 ++++++++++++++++++++++++++++++++
 examples/l3fwd/l3fwd_em.h               |  10 ++-
 examples/l3fwd/l3fwd_em_hlm_sse.h       |  17 +++--
 examples/l3fwd/l3fwd_em_sse.h           |   9 ++-
 examples/l3fwd/l3fwd_lpm.c              |  65 +++++++++++++++++++
 examples/l3fwd/main.c                   |  55 ++++++++++++++++
 9 files changed, 284 insertions(+), 10 deletions(-)

diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 76e4f3d..26e985b 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -299,6 +299,15 @@ This section should contain bug fixes added to the relevant sections. Sample for
   The title should contain the code/lib section like a commit message.
   Add the entries in alphabetic order in the relevant sections below.
 
+* **examples/vhost: Fixed frequent mbuf allocation failure.**
+
+  vhost-switch often fails to allocate mbuf when dequeue from vring because it
+  wrongly calculates the number of mbufs needed.
+
+* **examples/l3fwd: Fixed using packet type blindly.**
+
+  l3fwd makes use of packet type information without even query if devices or PMDs
+  really set it. For those don't set ptypes, add an option to parse it softly.
 
 EAL
 ~~~
diff --git a/doc/guides/sample_app_ug/l3_forward.rst b/doc/guides/sample_app_ug/l3_forward.rst
index 1522650..3e070d0 100644
--- a/doc/guides/sample_app_ug/l3_forward.rst
+++ b/doc/guides/sample_app_ug/l3_forward.rst
@@ -92,7 +92,7 @@ The application has a number of command line options:
 
 .. code-block:: console
 
-    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6]
+    ./build/l3fwd [EAL options] -- -p PORTMASK [-P]  --config(port,queue,lcore)[,(port,queue,lcore)] [--enable-jumbo [--max-pkt-len PKTLEN]]  [--no-numa][--hash-entry-num][--ipv6] [--parse-ptype]
 
 where,
 
@@ -113,6 +113,8 @@ where,
 
 *   --ipv6: optional, set it if running ipv6 packets
 
+*   --parse-ptype: optional, set it if use software way to analyze packet type
+
 For example, consider a dual processor socket platform where cores 0-7 and 16-23 appear on socket 0, while cores 8-15 and 24-31 appear on socket 1.
 Let's say that the programmer wants to use memory from both NUMA nodes, the platform has only two ports, one connected to each NUMA node,
 and the programmer wants to use two cores from each processor socket to do the packet processing.
@@ -334,6 +336,8 @@ The key code snippet of simple_ipv4_fwd_4pkts() is shown below:
 
 The simple_ipv6_fwd_4pkts() function is similar to the simple_ipv4_fwd_4pkts() function.
 
+Known issue: IP packets with extensions or IP packets which are not TCP/UDP cannot work well at this mode.
+
 Packet Forwarding for LPM-based Lookups
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index 726e8cc..d8798b7 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -206,6 +206,20 @@ void
 setup_hash(const int socketid);
 
 int
+em_check_ptype(int portid);
+
+int
+lpm_check_ptype(int portid);
+
+uint16_t
+em_cb_parse_ptype(uint8_t port, uint16_t queue, struct rte_mbuf *pkts[],
+		  uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
+
+uint16_t
+lpm_cb_parse_ptype(uint8_t port, uint16_t queue, struct rte_mbuf *pkts[],
+		   uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
+
+int
 em_main_loop(__attribute__((unused)) void *dummy);
 
 int
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index 526b485..fc59243 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -42,6 +42,7 @@
 #include <errno.h>
 #include <getopt.h>
 #include <stdbool.h>
+#include <netinet/in.h>
 
 #include <rte_debug.h>
 #include <rte_ether.h>
@@ -519,6 +520,114 @@ populate_ipv6_many_flow_into_table(const struct rte_hash *h,
 	printf("Hash: Adding 0x%x keys\n", nr_flow);
 }
 
+/* Requirements:
+ * 1. IP packets without extension;
+ * 2. L4 payload should be either TCP or UDP.
+ */
+int
+em_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4_ext = 0;
+	int ptype_l3_ipv6_ext = 0;
+	int ptype_l4_tcp = 0;
+	int ptype_l4_udp = 0;
+	uint32_t ptype_mask = RTE_PTYPE_L3_MASK | RTE_PTYPE_L4_MASK;
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		switch (ptypes[i]) {
+		case RTE_PTYPE_L3_IPV4_EXT:
+			ptype_l3_ipv4_ext = 1;
+			break;
+		case RTE_PTYPE_L3_IPV6_EXT:
+			ptype_l3_ipv6_ext = 1;
+			break;
+		case RTE_PTYPE_L4_TCP:
+			ptype_l4_tcp = 1;
+			break;
+		case RTE_PTYPE_L4_UDP:
+			ptype_l4_udp = 1;
+			break;
+		}
+	}
+
+	if (ptype_l3_ipv4_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4_EXT\n", portid);
+	if (ptype_l3_ipv6_ext == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6_EXT\n", portid);
+	if (!ptype_l3_ipv4_ext || !ptype_l3_ipv6_ext)
+		return 0;
+
+	if (ptype_l4_tcp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_TCP\n", portid);
+	if (ptype_l4_udp == 0)
+		printf("port %d cannot parse RTE_PTYPE_L4_UDP\n", portid);
+	if (ptype_l4_tcp && ptype_l4_udp)
+		return 1;
+
+	return 0;
+}
+
+static inline void
+em_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+	void *l3;
+	int hdr_len;
+	struct ipv4_hdr *ipv4_hdr;
+	struct ipv6_hdr *ipv6_hdr;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	l3 = (uint8_t *)eth_hdr + sizeof(struct ether_hdr);
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
+		ipv4_hdr = (struct ipv4_hdr *)l3;
+		hdr_len = (ipv4_hdr->version_ihl & IPV4_HDR_IHL_MASK) *
+			  IPV4_IHL_MULTIPLIER;
+		if (hdr_len == sizeof(struct ipv4_hdr)) {
+			packet_type |= RTE_PTYPE_L3_IPV4;
+			if (ipv4_hdr->next_proto_id == IPPROTO_TCP)
+				packet_type |= RTE_PTYPE_L4_TCP;
+			else if (ipv4_hdr->next_proto_id == IPPROTO_UDP)
+				packet_type |= RTE_PTYPE_L4_UDP;
+		} else
+			packet_type |= RTE_PTYPE_L3_IPV4_EXT;
+	} else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4)) {
+		ipv6_hdr = (struct ipv6_hdr *)l3;
+		if (ipv6_hdr->proto == IPPROTO_TCP)
+			packet_type |= RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_TCP;
+		else if (ipv6_hdr->proto == IPPROTO_UDP)
+			packet_type |= RTE_PTYPE_L3_IPV6 | RTE_PTYPE_L4_UDP;
+		else
+			packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+	}
+
+	m->packet_type = packet_type;
+}
+
+uint16_t
+em_cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+		  struct rte_mbuf *pkts[], uint16_t nb_pkts,
+		  uint16_t max_pkts __rte_unused,
+		  void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		em_parse_ptype(pkts[i]);
+
+	return nb_pkts;
+}
+
 /* main processing loop */
 int
 em_main_loop(__attribute__((unused)) void *dummy)
diff --git a/examples/l3fwd/l3fwd_em.h b/examples/l3fwd/l3fwd_em.h
index 64ea7f7..2284bbd 100644
--- a/examples/l3fwd/l3fwd_em.h
+++ b/examples/l3fwd/l3fwd_em.h
@@ -41,10 +41,14 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 	struct ether_hdr *eth_hdr;
 	struct ipv4_hdr *ipv4_hdr;
 	uint8_t dst_port;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
 	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	tcp_or_udp = m->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = m->packet_type & RTE_PTYPE_L3_MASK;
 
-	if (RTE_ETH_IS_IPV4_HDR(m->packet_type)) {
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *,
 						   sizeof(struct ether_hdr));
@@ -56,7 +60,7 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 			return;
 		}
 #endif
-		 dst_port = em_get_ipv4_dst_port(ipv4_hdr, portid,
+		dst_port = em_get_ipv4_dst_port(ipv4_hdr, portid,
 						qconf->ipv4_lookup_struct);
 
 		if (dst_port >= RTE_MAX_ETHPORTS ||
@@ -75,7 +79,7 @@ l3fwd_em_simple_forward(struct rte_mbuf *m, uint8_t portid,
 		ether_addr_copy(&ports_eth_addr[dst_port], &eth_hdr->s_addr);
 
 		send_single_packet(qconf, m, dst_port);
-	} else if (RTE_ETH_IS_IPV6_HDR(m->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 		/* Handle IPv6 headers.*/
 		struct ipv6_hdr *ipv6_hdr;
 
diff --git a/examples/l3fwd/l3fwd_em_hlm_sse.h b/examples/l3fwd/l3fwd_em_hlm_sse.h
index 7faf04a..ee0211f 100644
--- a/examples/l3fwd/l3fwd_em_hlm_sse.h
+++ b/examples/l3fwd/l3fwd_em_hlm_sse.h
@@ -239,8 +239,13 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	uint8_t next_hop;
 	struct ipv4_hdr *ipv4_hdr;
 	struct ipv6_hdr *ipv6_hdr;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
-	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+	tcp_or_udp = pkt->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = pkt->packet_type & RTE_PTYPE_L3_MASK;
+
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
@@ -255,7 +260,7 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 
 		return next_hop;
 
-	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 
 		/* Handle IPv6 headers.*/
 		ipv6_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv6_hdr *,
@@ -304,11 +309,15 @@ l3fwd_em_send_packets(int nb_rx, struct rte_mbuf **pkts_burst,
 			pkts_burst[j+6]->packet_type &
 			pkts_burst[j+7]->packet_type;
 
-		if (pkt_type & RTE_PTYPE_L3_IPV4) {
+		uint32_t l3_type = pkt_type & RTE_PTYPE_L3_MASK;
+		uint32_t tcp_or_udp = pkt_type &
+			(RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+
+		if (tcp_or_udp && (l3_type == RTE_PTYPE_L3_IPV4)) {
 
 			em_get_dst_port_ipv4x8(qconf, &pkts_burst[j], portid, &dst_port[j]);
 
-		} else if (pkt_type & RTE_PTYPE_L3_IPV6) {
+		} else if (tcp_or_udp && (l3_type == RTE_PTYPE_L3_IPV6)) {
 
 			em_get_dst_port_ipv6x8(qconf, &pkts_burst[j], portid, &dst_port[j]);
 
diff --git a/examples/l3fwd/l3fwd_em_sse.h b/examples/l3fwd/l3fwd_em_sse.h
index 8bd150a..e2fe932 100644
--- a/examples/l3fwd/l3fwd_em_sse.h
+++ b/examples/l3fwd/l3fwd_em_sse.h
@@ -52,8 +52,13 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 	uint8_t next_hop;
 	struct ipv4_hdr *ipv4_hdr;
 	struct ipv6_hdr *ipv6_hdr;
+	uint32_t tcp_or_udp;
+	uint32_t l3_ptypes;
 
-	if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
+	tcp_or_udp = pkt->packet_type & (RTE_PTYPE_L4_TCP | RTE_PTYPE_L4_UDP);
+	l3_ptypes = pkt->packet_type & RTE_PTYPE_L3_MASK;
+
+	if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV4)) {
 
 		/* Handle IPv4 headers.*/
 		ipv4_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv4_hdr *,
@@ -68,7 +73,7 @@ em_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
 
 		return next_hop;
 
-	} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
+	} else if (tcp_or_udp && (l3_ptypes == RTE_PTYPE_L3_IPV6)) {
 
 		/* Handle IPv6 headers.*/
 		ipv6_hdr = rte_pktmbuf_mtod_offset(pkt, struct ipv6_hdr *,
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index 3767923..d941bdf 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -277,6 +277,71 @@ setup_lpm(const int socketid)
 	}
 }
 
+int
+lpm_check_ptype(int portid)
+{
+	int i, ret;
+	int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
+	uint32_t ptype_mask = RTE_PTYPE_L3_MASK;
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, NULL, 0);
+	if (ret <= 0)
+		return 0;
+
+	uint32_t ptypes[ret];
+
+	ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, ptypes, ret);
+	for (i = 0; i < ret; ++i) {
+		if (ptypes[i] & RTE_PTYPE_L3_IPV4)
+			ptype_l3_ipv4 = 1;
+		if (ptypes[i] & RTE_PTYPE_L3_IPV6)
+			ptype_l3_ipv6 = 1;
+	}
+
+	if (ptype_l3_ipv4 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
+
+	if (ptype_l3_ipv6 == 0)
+		printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
+
+	if (ptype_l3_ipv4 && ptype_l3_ipv6)
+		return 1;
+
+	return 0;
+
+}
+
+static inline void
+lpm_parse_ptype(struct rte_mbuf *m)
+{
+	struct ether_hdr *eth_hdr;
+	uint32_t packet_type = RTE_PTYPE_UNKNOWN;
+	uint16_t ether_type;
+
+	eth_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
+	ether_type = eth_hdr->ether_type;
+	if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv4))
+		packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
+	else if (ether_type == rte_cpu_to_be_16(ETHER_TYPE_IPv6))
+		packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
+
+	m->packet_type = packet_type;
+}
+
+uint16_t
+lpm_cb_parse_ptype(uint8_t port __rte_unused, uint16_t queue __rte_unused,
+		   struct rte_mbuf *pkts[], uint16_t nb_pkts,
+		   uint16_t max_pkts __rte_unused,
+		   void *user_param __rte_unused)
+{
+	unsigned i;
+
+	for (i = 0; i < nb_pkts; ++i)
+		lpm_parse_ptype(pkts[i]);
+
+	return nb_pkts;
+}
+
 /* Return ipv4/ipv6 lpm fwd lookup struct. */
 void *
 lpm_get_ipv4_l3fwd_lookup_struct(const int socketid)
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index 792894f..658d2d4 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -103,6 +103,8 @@ static int l3fwd_lpm_on;
 static int l3fwd_em_on;
 
 static int numa_on = 1; /**< NUMA is enabled by default. */
+static int parse_ptype; /**< Parse packet type using rx callback, and */
+			/**< disabled by default */
 
 /* Global variables. */
 
@@ -172,6 +174,8 @@ static struct rte_mempool * pktmbuf_pool[NB_SOCKETS];
 
 struct l3fwd_lkp_mode {
 	void  (*setup)(int);
+	int   (*check_ptype)(int);
+	rte_rx_callback_fn cb_parse_ptype;
 	int   (*main_loop)(void *);
 	void* (*get_ipv4_lookup_struct)(int);
 	void* (*get_ipv6_lookup_struct)(int);
@@ -181,6 +185,8 @@ static struct l3fwd_lkp_mode l3fwd_lkp;
 
 static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 	.setup                  = setup_hash,
+	.check_ptype		= em_check_ptype,
+	.cb_parse_ptype		= em_cb_parse_ptype,
 	.main_loop              = em_main_loop,
 	.get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
@@ -188,6 +194,8 @@ static struct l3fwd_lkp_mode l3fwd_em_lkp = {
 
 static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
 	.setup                  = setup_lpm,
+	.check_ptype		= lpm_check_ptype,
+	.cb_parse_ptype		= lpm_cb_parse_ptype,
 	.main_loop              = lpm_main_loop,
 	.get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
 	.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
@@ -456,6 +464,7 @@ parse_eth_dest(const char *optarg)
 #define CMD_LINE_OPT_IPV6 "ipv6"
 #define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
 #define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
+#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
 
 /*
  * This expression is used to calculate the number of mbufs needed
@@ -486,6 +495,7 @@ parse_args(int argc, char **argv)
 		{CMD_LINE_OPT_IPV6, 0, 0, 0},
 		{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, 0},
 		{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, 0},
+		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
 		{NULL, 0, 0, 0}
 	};
 
@@ -612,6 +622,14 @@ parse_args(int argc, char **argv)
 					return -1;
 				}
 			}
+
+			if (!strncmp(lgopts[option_index].name,
+				     CMD_LINE_OPT_PARSE_PTYPE,
+				     sizeof(CMD_LINE_OPT_PARSE_PTYPE))) {
+				printf("soft parse-ptype is enabled\n");
+				parse_ptype = 1;
+			}
+
 			break;
 
 		default:
@@ -779,6 +797,28 @@ signal_handler(int signum)
 	}
 }
 
+static int
+prepare_ptype_parser(uint8_t portid, uint16_t queueid)
+{
+	if (parse_ptype) {
+		printf("Port %d: softly parse packet type info\n", portid);
+		if (rte_eth_add_rx_callback(portid, queueid,
+					    l3fwd_lkp.cb_parse_ptype,
+					    NULL))
+			return 1;
+
+		printf("Failed to add rx callback: port=%d\n", portid);
+		return 0;
+	}
+
+	if (l3fwd_lkp.check_ptype(portid))
+		return 1;
+
+	printf("port %d cannot parse packet type, please add --%s\n",
+	       portid, CMD_LINE_OPT_PARSE_PTYPE);
+	return 0;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -972,6 +1012,21 @@ main(int argc, char **argv)
 			rte_eth_promiscuous_enable(portid);
 	}
 
+	printf("\n");
+
+	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
+		if (rte_lcore_is_enabled(lcore_id) == 0)
+			continue;
+		qconf = &lcore_conf[lcore_id];
+		for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
+			portid = qconf->rx_queue_list[queue].port_id;
+			queueid = qconf->rx_queue_list[queue].queue_id;
+			if (prepare_ptype_parser(portid, queueid) == 0)
+				rte_exit(EXIT_FAILURE, "ptype check fails\n");
+		}
+	}
+
+
 	check_all_ports_link_status((uint8_t)nb_ports, enabled_port_mask);
 
 	ret = 0;
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH v4 3/3] config: enable vector driver by default
  2016-03-25  0:47   ` [PATCH v4 0/3] packet type Jianfeng Tan
  2016-03-25  0:47     ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Jianfeng Tan
  2016-03-25  0:47     ` [PATCH v4 2/3] examples/l3fwd: fix using packet type blindly Jianfeng Tan
@ 2016-03-25  0:47     ` Jianfeng Tan
  2016-03-25 18:34     ` [PATCH v4 0/3] packet type Thomas Monjalon
  3 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-25  0:47 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan, konstantin.ananyev, helin.zhang, bruce.richardson

Previously, vector driver is not the first (default) choice for i40e,
as it cannot fill packet type info for l3fwd to work well. Now there
is an option for l3fwd to analysis packet type softly. So enable it
by default.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 config/common_base                     | 2 +-
 doc/guides/rel_notes/release_16_04.rst | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/config/common_base b/config/common_base
index d98a82c..abd6a64 100644
--- a/config/common_base
+++ b/config/common_base
@@ -179,7 +179,7 @@ CONFIG_RTE_LIBRTE_I40E_DEBUG_TX=n
 CONFIG_RTE_LIBRTE_I40E_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_I40E_DEBUG_DRIVER=n
 CONFIG_RTE_LIBRTE_I40E_RX_ALLOW_BULK_ALLOC=y
-CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=n
+CONFIG_RTE_LIBRTE_I40E_INC_VECTOR=y
 CONFIG_RTE_LIBRTE_I40E_RX_OLFLAGS_ENABLE=y
 CONFIG_RTE_LIBRTE_I40E_16BYTE_RX_DESC=n
 CONFIG_RTE_LIBRTE_I40E_QUEUE_NUM_PER_PF=64
diff --git a/doc/guides/rel_notes/release_16_04.rst b/doc/guides/rel_notes/release_16_04.rst
index 26e985b..7359604 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -390,6 +390,12 @@ Drivers
   Allowed AES GCM on the cryptodev API, but in some cases gave invalid results
   due to incorrect IV setting.
 
+* **i40e: enable vector driver by default.**
+
+  Previously, vector driver is disabled by default as it cannot fill packet type
+  info for l3fwd to work well. Now there is an option for l3fwd to analysis
+  packet type softly, so enable vector driver by default.
+
 
 Libraries
 ~~~~~~~~~
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 0/2] ethdev: refine new API to query supported ptypes
  2016-03-25  0:47     ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Jianfeng Tan
@ 2016-03-25  3:15       ` Jianfeng Tan
  2016-03-25  3:15         ` [PATCH 1/2] " Jianfeng Tan
                           ` (3 more replies)
  2016-03-25 10:01       ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Tan, Jianfeng
  2016-03-25 10:13       ` Bruce Richardson
  2 siblings, 4 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-25  3:15 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan, konstantin.ananyev, helin.zhang, bruce.richardson

patch 0: return 0 instead of -ENOTSUP.
patch 1: update doc/guides/nics/overview.rst.

Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Jianfeng Tan (2):
  ethdev: refine new API to query supported ptypes
  doc: update which PMDs can parse packet type

 doc/guides/nics/overview.rst  | 2 +-
 lib/librte_ether/rte_ethdev.c | 3 +--
 lib/librte_ether/rte_ethdev.h | 9 ++++++---
 3 files changed, 8 insertions(+), 6 deletions(-)

-- 
2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH 1/2] ethdev: refine new API to query supported ptypes
  2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
@ 2016-03-25  3:15         ` Jianfeng Tan
  2016-03-25  3:15         ` [PATCH 2/2] doc: update which PMDs can parse packet type Jianfeng Tan
                           ` (2 subsequent siblings)
  3 siblings, 0 replies; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-25  3:15 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan, konstantin.ananyev, helin.zhang, bruce.richardson

This change is to  make user code simpler. For PMDs which do not fill any
packet types, return 0 instead of -ENOTSUP as suggested by Bruce.

Usually, users only care if the required (by ptype_mask) ptypes can be
filled by the specified PMD. If the PMD implements dev_supported_ptypes_get
func is not important. And the introduce of another return value (-ENOTSUP)
would increase the complexity of user programs to check it.

Besides, there are ways to know if a PMD implements the func:
  a. see doc/guides/nics/overview.rst.
  b. use (~1) as parameter ptype_mask, then check if return 0.

Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 lib/librte_ether/rte_ethdev.c | 3 +--
 lib/librte_ether/rte_ethdev.h | 9 ++++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a328027..1ee79d2 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1636,8 +1636,7 @@ rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get,
-				-ENOTSUP);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
 	if (!all_ptypes)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index e7de34a..2d76849 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -2326,6 +2326,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
  * @note
  *   Better to invoke this API after the device is already started or rx burst
  *   function is decided, to obtain correct supported ptypes.
+ * @note
+ *   if a given PMD does not report what ptypes it supports, then the supported
+ *   ptype count is reported as 0.
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param ptype_mask
@@ -2335,9 +2338,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
  * @param num
  *  Size of the array pointed by param ptypes.
  * @return
- *   - (>0) Number of supported ptypes. If it exceeds param num, exceeding
- *          packet types will not be filled in the given array.
- *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (>=0) Number of supported ptypes. If the number of types exceeds num,
+ *           only num entries will be filled into the ptypes array, but the full
+ *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
  */
 int rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* [PATCH 2/2] doc: update which PMDs can parse packet type
  2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
  2016-03-25  3:15         ` [PATCH 1/2] " Jianfeng Tan
@ 2016-03-25  3:15         ` Jianfeng Tan
  2016-03-25 14:21           ` Bruce Richardson
  2016-03-25 10:57         ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Ananyev, Konstantin
  2016-04-06  3:51         ` [PATCH v2] " Jianfeng Tan
  3 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-03-25  3:15 UTC (permalink / raw)
  To: dev; +Cc: Jianfeng Tan, konstantin.ananyev, helin.zhang, bruce.richardson

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/nics/overview.rst | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index 542479a..e7504da 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -124,7 +124,7 @@ Most of these differences are summarized below.
    L4 checksum offload          X   X   X   X
    inner L3 checksum                X   X   X
    inner L4 checksum                X   X   X
-   packet type parsing          X       X   X
+   packet type parsing  X X X X     X     X   X                     X   X X X X X X   X
    timesync                             X X
    basic stats                  X   X   X X X X                               X X
    extended stats                   X   X X X X
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 1/3] ethdev: refine API to query supported packet types
  2016-03-25  0:47     ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Jianfeng Tan
  2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
@ 2016-03-25 10:01       ` Tan, Jianfeng
  2016-03-25 10:13       ` Bruce Richardson
  2 siblings, 0 replies; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-25 10:01 UTC (permalink / raw)
  To: dev; +Cc: Ananyev, Konstantin, Zhang, Helin, Richardson, Bruce

NACK.

I'll send an independent patchset for this.

Thanks,
Jianfeng

> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, March 25, 2016 8:48 AM
> To: dev@dpdk.org
> Cc: Tan, Jianfeng; Ananyev, Konstantin; Zhang, Helin; Richardson, Bruce
> Subject: [PATCH v4 1/3] ethdev: refine API to query supported packet types
> 
> Return 0 instead of -ENOTSUP for those which do not fill any packet types,
> with some note and doc updated.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
>  doc/guides/nics/overview.rst  | 2 +-
>  lib/librte_ether/rte_ethdev.c | 3 +--
>  lib/librte_ether/rte_ethdev.h | 9 ++++++---
>  3 files changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
> index 542479a..e7504da 100644
> --- a/doc/guides/nics/overview.rst
> +++ b/doc/guides/nics/overview.rst
> @@ -124,7 +124,7 @@ Most of these differences are summarized below.
>     L4 checksum offload          X   X   X   X
>     inner L3 checksum                X   X   X
>     inner L4 checksum                X   X   X
> -   packet type parsing          X       X   X
> +   packet type parsing  X X X X     X     X   X                     X   X X X X X X   X
>     timesync                             X X
>     basic stats                  X   X   X X X X                               X X
>     extended stats                   X   X X X X
> diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
> index a328027..1ee79d2 100644
> --- a/lib/librte_ether/rte_ethdev.c
> +++ b/lib/librte_ether/rte_ethdev.c
> @@ -1636,8 +1636,7 @@ rte_eth_dev_get_supported_ptypes(uint8_t
> port_id, uint32_t ptype_mask,
> 
>  	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
>  	dev = &rte_eth_devices[port_id];
> -	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >dev_supported_ptypes_get,
> -				-ENOTSUP);
> +	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops-
> >dev_supported_ptypes_get, 0);
>  	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
> 
>  	if (!all_ptypes)
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index e7de34a..5167750 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -2326,6 +2326,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct
> rte_eth_dev_info *dev_info);
>   * @note
>   *   Better to invoke this API after the device is already started or rx burst
>   *   function is decided, to obtain correct supported ptypes.
> + * @note
> + *   if a given PMD does not report what ptypes it supports, then the
> supported
> + *   ptype count is reported as 0.
>   * @param port_id
>   *   The port identifier of the Ethernet device.
>   * @param ptype_mask
> @@ -2335,9 +2338,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct
> rte_eth_dev_info *dev_info);
>   * @param num
>   *  Size of the array pointed by param ptypes.
>   * @return
> - *   - (>0) Number of supported ptypes. If it exceeds param num, exceeding
> - *          packet types will not be filled in the given array.
> - *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
> + *   - (>=0) Number of supported ptypes. If the number of types exceeds
> num,
> +             only num entries will be filled into the ptypes array, but the full
> +             count of supported ptypes will be returned.
>   *   - (-ENODEV) if *port_id* invalid.
>   */
>  int rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t
> ptype_mask,
> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 1/3] ethdev: refine API to query supported packet types
  2016-03-25  0:47     ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Jianfeng Tan
  2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
  2016-03-25 10:01       ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Tan, Jianfeng
@ 2016-03-25 10:13       ` Bruce Richardson
  2 siblings, 0 replies; 202+ messages in thread
From: Bruce Richardson @ 2016-03-25 10:13 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, konstantin.ananyev, helin.zhang

On Fri, Mar 25, 2016 at 08:47:45AM +0800, Jianfeng Tan wrote:
> Return 0 instead of -ENOTSUP for those which do not fill any packet types,
> with some note and doc updated.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

Hi Jianfeng,

I think this is a good change to the API, as it should simplify app code - as
any driver which doesn't tell us what ptypes it supports should be counted as
not supporting any. It also eliminates the need for the vdevs to see about
exporting this function to say they don't support any types.

However, two comments:
1. I think the commit message for this change should include information as to
why we want to tweak the API of this new function i.e. put in the above reasons
plus any others.
2. Please separate out the doc change from the API change as they are unrelated.

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 0/2] ethdev: refine new API to query supported ptypes
  2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
  2016-03-25  3:15         ` [PATCH 1/2] " Jianfeng Tan
  2016-03-25  3:15         ` [PATCH 2/2] doc: update which PMDs can parse packet type Jianfeng Tan
@ 2016-03-25 10:57         ` Ananyev, Konstantin
  2016-04-06  3:51         ` [PATCH v2] " Jianfeng Tan
  3 siblings, 0 replies; 202+ messages in thread
From: Ananyev, Konstantin @ 2016-03-25 10:57 UTC (permalink / raw)
  To: Tan, Jianfeng, dev; +Cc: Zhang, Helin, Richardson, Bruce



> -----Original Message-----
> From: Tan, Jianfeng
> Sent: Friday, March 25, 2016 3:16 AM
> To: dev@dpdk.org
> Cc: Tan, Jianfeng; Ananyev, Konstantin; Zhang, Helin; Richardson, Bruce
> Subject: [PATCH 0/2] ethdev: refine new API to query supported ptypes
> 
> patch 0: return 0 instead of -ENOTSUP.
> patch 1: update doc/guides/nics/overview.rst.
> 
> Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> 
> Jianfeng Tan (2):
>   ethdev: refine new API to query supported ptypes
>   doc: update which PMDs can parse packet type
> 
>  doc/guides/nics/overview.rst  | 2 +-
>  lib/librte_ether/rte_ethdev.c | 3 +--
>  lib/librte_ether/rte_ethdev.h | 9 ++++++---
>  3 files changed, 8 insertions(+), 6 deletions(-)
> 

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> --
> 2.1.4

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 2/2] doc: update which PMDs can parse packet type
  2016-03-25  3:15         ` [PATCH 2/2] doc: update which PMDs can parse packet type Jianfeng Tan
@ 2016-03-25 14:21           ` Bruce Richardson
  2016-03-25 16:10             ` Tan, Jianfeng
  0 siblings, 1 reply; 202+ messages in thread
From: Bruce Richardson @ 2016-03-25 14:21 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, konstantin.ananyev, helin.zhang

On Fri, Mar 25, 2016 at 11:15:36AM +0800, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  doc/guides/nics/overview.rst | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
> index 542479a..e7504da 100644
> --- a/doc/guides/nics/overview.rst
> +++ b/doc/guides/nics/overview.rst
> @@ -124,7 +124,7 @@ Most of these differences are summarized below.
>     L4 checksum offload          X   X   X   X
>     inner L3 checksum                X   X   X
>     inner L4 checksum                X   X   X
> -   packet type parsing          X       X   X
> +   packet type parsing  X X X X     X     X   X                     X   X X X X X X   X

This diff does not look right. How come some entries are being removed from some drivers?
Are you sure the line has correct whitespace on it?

/Bruce

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 2/2] doc: update which PMDs can parse packet type
  2016-03-25 14:21           ` Bruce Richardson
@ 2016-03-25 16:10             ` Tan, Jianfeng
  2016-04-01 15:55               ` Thomas Monjalon
  0 siblings, 1 reply; 202+ messages in thread
From: Tan, Jianfeng @ 2016-03-25 16:10 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, konstantin.ananyev, helin.zhang

Hi Bruce,

On 3/25/2016 10:21 PM, Bruce Richardson wrote:
> On Fri, Mar 25, 2016 at 11:15:36AM +0800, Jianfeng Tan wrote:
>> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
>> ---
>>   doc/guides/nics/overview.rst | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
>> index 542479a..e7504da 100644
>> --- a/doc/guides/nics/overview.rst
>> +++ b/doc/guides/nics/overview.rst
>> @@ -124,7 +124,7 @@ Most of these differences are summarized below.
>>      L4 checksum offload          X   X   X   X
>>      inner L3 checksum                X   X   X
>>      inner L4 checksum                X   X   X
>> -   packet type parsing          X       X   X
>> +   packet type parsing  X X X X     X     X   X                     X   X X X X X X   X
> This diff does not look right. How come some entries are being removed from some drivers?
> Are you sure the line has correct whitespace on it?
>
> /Bruce

Thank you for checking this, actually I forget to rebase on rel_16_04. 
There's newly added vhost-pmd.

-   packet type parsing  X X X X     X     X   X X   X X X X X X   X
+   packet type parsing  X X X X     X     X   X X   X X X X X X X   X

Besides, I use thunderbird to see it, seems whilespace occupies less 
width than characters.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 2/3] examples/l3fwd: fix using packet type blindly
  2016-03-25  0:47     ` [PATCH v4 2/3] examples/l3fwd: fix using packet type blindly Jianfeng Tan
@ 2016-03-25 18:24       ` Thomas Monjalon
  0 siblings, 0 replies; 202+ messages in thread
From: Thomas Monjalon @ 2016-03-25 18:24 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, konstantin.ananyev, helin.zhang, bruce.richardson

2016-03-25 08:47, Jianfeng Tan:
> +* **examples/vhost: Fixed frequent mbuf allocation failure.**
> +
> +  vhost-switch often fails to allocate mbuf when dequeue from vring because it
> +  wrongly calculates the number of mbufs needed.

Wrong rebase here ;)

> +* **examples/l3fwd: Fixed using packet type blindly.**
> +
> +  l3fwd makes use of packet type information without even query if devices or PMDs
> +  really set it. For those don't set ptypes, add an option to parse it softly.

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH v4 0/3] packet type
  2016-03-25  0:47   ` [PATCH v4 0/3] packet type Jianfeng Tan
                       ` (2 preceding siblings ...)
  2016-03-25  0:47     ` [PATCH v4 3/3] config: enable vector driver by default Jianfeng Tan
@ 2016-03-25 18:34     ` Thomas Monjalon
  3 siblings, 0 replies; 202+ messages in thread
From: Thomas Monjalon @ 2016-03-25 18:34 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, konstantin.ananyev, helin.zhang, bruce.richardson

2016-03-25 08:47, Jianfeng Tan:
> Patch 1: refine rte_eth_dev_get_supported_ptypes.

This patch has been split in another series.

> Patch 2: add an option in l3fwd.
> Patch 3: enable vector pmd in i40e by default.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> 
> 
> Jianfeng Tan (3):
>   ethdev: refine API to query supported packet types
>   examples/l3fwd: fix using packet type blindly
>   config: enable vector driver by default

Applied patches 2 & 3 with release notes fixes.

^ permalink raw reply	[flat|nested] 202+ messages in thread

* Re: [PATCH 2/2] doc: update which PMDs can parse packet type
  2016-03-25 16:10             ` Tan, Jianfeng
@ 2016-04-01 15:55               ` Thomas Monjalon
  0 siblings, 0 replies; 202+ messages in thread
From: Thomas Monjalon @ 2016-04-01 15:55 UTC (permalink / raw)
  To: Tan, Jianfeng; +Cc: dev, Bruce Richardson, konstantin.ananyev, helin.zhang

2016-03-26 00:10, Tan, Jianfeng:
> On 3/25/2016 10:21 PM, Bruce Richardson wrote:
> > On Fri, Mar 25, 2016 at 11:15:36AM +0800, Jianfeng Tan wrote:
> >> --- a/doc/guides/nics/overview.rst
> >> +++ b/doc/guides/nics/overview.rst
> >> @@ -124,7 +124,7 @@ Most of these differences are summarized below.
> >>      L4 checksum offload          X   X   X   X
> >>      inner L3 checksum                X   X   X
> >>      inner L4 checksum                X   X   X
> >> -   packet type parsing          X       X   X
> >> +   packet type parsing  X X X X     X     X   X                     X   X X X X X X   X
> > This diff does not look right. How come some entries are being removed from some drivers?
> > Are you sure the line has correct whitespace on it?
> >
> > /Bruce
> 
> Thank you for checking this, actually I forget to rebase on rel_16_04. 
> There's newly added vhost-pmd.
> 
> -   packet type parsing  X X X X     X     X   X X   X X X X X X   X
> +   packet type parsing  X X X X     X     X   X X   X X X X X X X   X

Sorry I don't understand what you want to fill.
Please rebase and re-send.

^ permalink raw reply	[flat|nested] 202+ messages in thread

* [PATCH v2] ethdev: refine new API to query supported ptypes
  2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
                           ` (2 preceding siblings ...)
  2016-03-25 10:57         ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Ananyev, Konstantin
@ 2016-04-06  3:51         ` Jianfeng Tan
  2016-04-06 14:32           ` Thomas Monjalon
  3 siblings, 1 reply; 202+ messages in thread
From: Jianfeng Tan @ 2016-04-06  3:51 UTC (permalink / raw)
  To: dev; +Cc: konstantin.ananyev, bruce.richardson, thomas.monjalon, Jianfeng Tan

This change is to  make user code simpler. For PMDs which do not fill any
packet types, return 0 instead of -ENOTSUP as suggested by Bruce.

Usually, users only care if the required (by ptype_mask) ptypes can be
filled by the specified PMD. If the PMD implements dev_supported_ptypes_get
func is not important. And the introduce of another return value (-ENOTSUP)
would increase the complexity of user programs to check it.

Besides, there are ways to know if a PMD implements the func:
  a. see doc/guides/nics/overview.rst.
  b. use (~1) as parameter ptype_mask, then check if return 0.

Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
 v2: exclude the commit of updating doc/guides/nics/overview.rst.

 lib/librte_ether/rte_ethdev.c | 3 +--
 lib/librte_ether/rte_ethdev.h | 9 ++++++---
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fd49b26..5a16d5e 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -1670,8 +1670,7 @@ rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
 
 	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
 	dev = &rte_eth_devices[port_id];
-	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get,
-				-ENOTSUP);
+	RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_supported_ptypes_get, 0);
 	all_ptypes = (*dev->dev_ops->dev_supported_ptypes_get)(dev);
 
 	if (!all_ptypes)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 37ddd51..022733e 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -2379,6 +2379,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
  * @note
  *   Better to invoke this API after the device is already started or rx burst
  *   function is decided, to obtain correct supported ptypes.
+ * @note
+ *   if a given PMD does not report what ptypes it supports, then the supported
+ *   ptype count is reported as 0.
  * @param port_id
  *   The port identifier of the Ethernet device.
  * @param ptype_mask
@@ -2388,9 +2391,9 @@ void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info);
  * @param num
  *  Size of the array pointed by param ptypes.
  * @return
- *   - (>0) Number of supported ptypes. If it exceeds param num, exceeding
- *          packet types will not be filled in the given array.
- *   - (0 or -ENOTSUP) if PMD does not fill the specified ptype.
+ *   - (>=0) Number of supported ptypes. If the number of types exceeds num,
+ *           only num entries will be filled into the ptypes array, but the full
+ *           count of supported ptypes will be returned.
  *   - (-ENODEV) if *port_id* invalid.
  */
 int rte_eth_dev_get_supported_ptypes(uint8_t port_id, uint32_t ptype_mask,
-- 
2.1.4

^ permalink raw reply related	[flat|nested] 202+ messages in thread

* Re: [PATCH v2] ethdev: refine new API to query supported ptypes
  2016-04-06  3:51         ` [PATCH v2] " Jianfeng Tan
@ 2016-04-06 14:32           ` Thomas Monjalon
  0 siblings, 0 replies; 202+ messages in thread
From: Thomas Monjalon @ 2016-04-06 14:32 UTC (permalink / raw)
  To: Jianfeng Tan; +Cc: dev, konstantin.ananyev, bruce.richardson

2016-04-06 11:51, Jianfeng Tan:
> This change is to  make user code simpler. For PMDs which do not fill any
> packet types, return 0 instead of -ENOTSUP as suggested by Bruce.
> 
> Usually, users only care if the required (by ptype_mask) ptypes can be
> filled by the specified PMD. If the PMD implements dev_supported_ptypes_get
> func is not important. And the introduce of another return value (-ENOTSUP)
> would increase the complexity of user programs to check it.
> 
> Besides, there are ways to know if a PMD implements the func:
>   a. see doc/guides/nics/overview.rst.
>   b. use (~1) as parameter ptype_mask, then check if return 0.
> 
> Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

Applied, thanks

^ permalink raw reply	[flat|nested] 202+ messages in thread

end of thread, other threads:[~2016-04-06 14:34 UTC | newest]

Thread overview: 202+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-31  6:53 [PATCH 00/12] Add API to get packet type info Jianfeng Tan
2015-12-31  6:53 ` [PATCH 01/12] ethdev: add API to query what/if packet type is set Jianfeng Tan
2016-01-04 11:38   ` Adrien Mazarguil
2016-01-04 14:36     ` Ananyev, Konstantin
2016-01-05 16:14       ` Nélio Laranjeiro
2016-01-05 16:50         ` Ananyev, Konstantin
2016-01-06 10:00           ` Adrien Mazarguil
2016-01-06 14:29             ` Ananyev, Konstantin
2016-01-06 15:44               ` Adrien Mazarguil
2016-01-06 16:44                 ` Ananyev, Konstantin
2016-01-06 17:22                   ` Adrien Mazarguil
2016-01-07 10:24                     ` Ananyev, Konstantin
2016-01-07 13:32                       ` Adrien Mazarguil
2016-01-11  7:39                         ` Tan, Jianfeng
2016-01-11 10:26                           ` Ananyev, Konstantin
2015-12-31  6:53 ` [PATCH 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
2016-01-06  7:11   ` Rahul Lakkireddy
2016-01-06  8:23     ` Tan, Jianfeng
2015-12-31  6:53 ` [PATCH 03/12] pmd/e1000: " Jianfeng Tan
2015-12-31  6:53 ` [PATCH 04/12] pmd/enic: " Jianfeng Tan
2015-12-31  6:53 ` [PATCH 05/12] pmd/fm10k: " Jianfeng Tan
2015-12-31  6:53 ` [PATCH 06/12] pmd/i40e: " Jianfeng Tan
2015-12-31  6:53 ` [PATCH 07/12] pmd/ixgbe: " Jianfeng Tan
2016-01-04 18:12   ` Ananyev, Konstantin
2016-01-05  1:25     ` Tan, Jianfeng
2015-12-31  6:53 ` [PATCH 08/12] pmd/mlx4: " Jianfeng Tan
2016-01-04 11:11   ` Adrien Mazarguil
2016-01-05  3:08     ` Tan, Jianfeng
2016-01-05 16:18       ` Adrien Mazarguil
2016-01-11  5:07         ` Tan, Jianfeng
2015-12-31  6:53 ` [PATCH 09/12] pmd/mlx5: " Jianfeng Tan
2015-12-31  6:53 ` [PATCH 10/12] pmd/nfp: " Jianfeng Tan
2015-12-31  6:53 ` [PATCH 11/12] pmd/vmxnet3: " Jianfeng Tan
2015-12-31  6:53 ` [PATCH 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
2016-01-04 18:32   ` Ananyev, Konstantin
2016-01-05  2:44     ` Tan, Jianfeng
2016-01-05 16:49       ` Ananyev, Konstantin
2016-01-07  1:20         ` Tan, Jianfeng
2016-01-07  9:44           ` Ananyev, Konstantin
2016-01-13  1:52 ` [PATCH 00/12] Add API to get packet type info Qiu, Michael
2016-01-15  5:45 ` [PATCH v2 " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
2016-01-15 13:58     ` Adrien Mazarguil
2016-01-15 15:11       ` Ananyev, Konstantin
2016-01-15 15:33         ` Adrien Mazarguil
2016-01-15 15:03     ` Ananyev, Konstantin
2016-02-25  6:53       ` Tan, Jianfeng
2016-02-25 11:17         ` Ananyev, Konstantin
2016-02-25 14:57           ` Tan, Jianfeng
2016-01-15  5:45   ` [PATCH v2 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 03/12] pmd/e1000: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 04/12] pmd/enic: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 05/12] pmd/fm10k: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 06/12] pmd/i40e: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 07/12] pmd/ixgbe: " Jianfeng Tan
2016-01-15 14:50     ` Ananyev, Konstantin
2016-02-25  6:43       ` Tan, Jianfeng
2016-02-25 11:10         ` Ananyev, Konstantin
2016-01-15  5:45   ` [PATCH v2 08/12] pmd/mlx4: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 09/12] pmd/mlx5: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 10/12] pmd/nfp: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 11/12] pmd/vmxnet3: " Jianfeng Tan
2016-01-15  5:45   ` [PATCH v2 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
2016-01-15 14:47     ` Ananyev, Konstantin
2016-02-25 10:41       ` Tan, Jianfeng
2016-02-25 10:57         ` Ananyev, Konstantin
2016-02-23 17:31   ` [PATCH v2 00/12] Add API to get packet type info Bruce Richardson
2016-02-25  7:53 ` [PATCH v3 " Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
2016-02-25 15:46     ` Ananyev, Konstantin
2016-02-25 16:36       ` Tan, Jianfeng
2016-02-25 17:16         ` Ananyev, Konstantin
2016-02-26  1:42           ` Tan, Jianfeng
2016-02-25  7:53   ` [PATCH v3 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 03/12] pmd/e1000: " Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 04/12] pmd/enic: " Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 05/12] pmd/fm10k: " Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 06/12] pmd/i40e: " Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 07/12] pmd/ixgbe: " Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 08/12] pmd/mlx4: " Jianfeng Tan
2016-02-25  7:53   ` [PATCH v3 09/12] pmd/mlx5: " Jianfeng Tan
2016-02-25  7:54   ` [PATCH v3 10/12] pmd/nfp: " Jianfeng Tan
2016-02-25  7:54   ` [PATCH v3 11/12] pmd/vmxnet3: " Jianfeng Tan
2016-02-25  7:54   ` [PATCH v3 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
2016-02-26  0:04 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
2016-02-26  0:04   ` [PATCH v4 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
2016-02-26  0:09 ` [PATCH v4 00/12] Add API to get packet type info Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 01/12] ethdev: add API to query packet type filling info Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 02/12] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 03/12] pmd/e1000: " Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 04/12] pmd/enic: " Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 05/12] pmd/fm10k: " Jianfeng Tan
2016-03-02 20:11     ` Chen, Jing D
2016-03-03  6:03       ` Tan, Jianfeng
2016-03-03 15:47         ` Ananyev, Konstantin
2016-02-26  0:09   ` [PATCH v4 06/12] pmd/i40e: " Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 07/12] pmd/ixgbe: " Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 08/12] pmd/mlx4: " Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 09/12] pmd/mlx5: " Jianfeng Tan
2016-02-26  8:26     ` Adrien Mazarguil
2016-02-26  8:36       ` Tan, Jianfeng
2016-02-26  0:09   ` [PATCH v4 10/12] pmd/nfp: " Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 11/12] pmd/vmxnet3: " Jianfeng Tan
2016-02-26  0:09   ` [PATCH v4 12/12] examples/l3fwd: add option to parse ptype Jianfeng Tan
2016-02-26 13:14     ` Ananyev, Konstantin
2016-02-26 14:21       ` Tan, Jianfeng
2016-02-26 14:27         ` Ananyev, Konstantin
2016-02-26  7:34 ` [PATCH v5 00/11] Add API to get packet type info Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
2016-02-29 11:34     ` Panu Matilainen
2016-02-29 16:41       ` Tan, Jianfeng
2016-03-01  6:29         ` Panu Matilainen
2016-03-01  7:59           ` Thomas Monjalon
2016-03-01  8:00           ` Tan, Jianfeng
2016-02-26  7:34   ` [PATCH v5 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 03/11] pmd/e1000: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 04/11] pmd/enic: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 05/11] pmd/fm10k: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 06/11] pmd/i40e: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 07/11] pmd/ixgbe: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 08/11] pmd/mlx4: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 09/11] pmd/mlx5: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 10/11] pmd/nfp: " Jianfeng Tan
2016-02-26  7:34   ` [PATCH v5 11/11] pmd/vmxnet3: " Jianfeng Tan
2016-02-29 16:54   ` [PATCH v5 00/11] Add API to get packet type info Ananyev, Konstantin
2016-02-29 17:01     ` Adrien Mazarguil
2016-02-29 20:30 ` [PATCH v6 " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 03/11] pmd/e1000: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 04/11] pmd/enic: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 05/11] pmd/fm10k: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 06/11] pmd/i40e: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 07/11] pmd/ixgbe: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 08/11] pmd/mlx4: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 09/11] pmd/mlx5: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 10/11] pmd/nfp: " Jianfeng Tan
2016-02-29 20:30   ` [PATCH v6 11/11] pmd/vmxnet3: " Jianfeng Tan
2016-03-01  1:23 ` [PATCH] examples/l3fwd: fix using packet type blindly Jianfeng Tan
2016-03-01 13:51   ` Ananyev, Konstantin
2016-03-01 14:17     ` Tan, Jianfeng
2016-03-01 14:30       ` Ananyev, Konstantin
2016-03-04  8:38   ` [PATCH v2] " Jianfeng Tan
2016-03-07 18:51     ` Ananyev, Konstantin
2016-03-08 17:11       ` Tan, Jianfeng
2016-03-10  5:50   ` [PATCH v3 0/2] " Jianfeng Tan
2016-03-10  5:50     ` [PATCH v3 1/2] " Jianfeng Tan
2016-03-10  5:50     ` [PATCH v3 2/2] config: enable vector driver by default Jianfeng Tan
2016-03-10 14:26     ` [PATCH v3 0/2] examples/l3fwd: fix using packet type blindly Ananyev, Konstantin
2016-03-25  0:47   ` [PATCH v4 0/3] packet type Jianfeng Tan
2016-03-25  0:47     ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Jianfeng Tan
2016-03-25  3:15       ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Jianfeng Tan
2016-03-25  3:15         ` [PATCH 1/2] " Jianfeng Tan
2016-03-25  3:15         ` [PATCH 2/2] doc: update which PMDs can parse packet type Jianfeng Tan
2016-03-25 14:21           ` Bruce Richardson
2016-03-25 16:10             ` Tan, Jianfeng
2016-04-01 15:55               ` Thomas Monjalon
2016-03-25 10:57         ` [PATCH 0/2] ethdev: refine new API to query supported ptypes Ananyev, Konstantin
2016-04-06  3:51         ` [PATCH v2] " Jianfeng Tan
2016-04-06 14:32           ` Thomas Monjalon
2016-03-25 10:01       ` [PATCH v4 1/3] ethdev: refine API to query supported packet types Tan, Jianfeng
2016-03-25 10:13       ` Bruce Richardson
2016-03-25  0:47     ` [PATCH v4 2/3] examples/l3fwd: fix using packet type blindly Jianfeng Tan
2016-03-25 18:24       ` Thomas Monjalon
2016-03-25  0:47     ` [PATCH v4 3/3] config: enable vector driver by default Jianfeng Tan
2016-03-25 18:34     ` [PATCH v4 0/3] packet type Thomas Monjalon
2016-03-09 19:31 ` [PATCH v7 00/11] Add API to get packet type info Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 01/11] ethdev: add API to query packet type filling info Jianfeng Tan
2016-03-10 14:28     ` Bruce Richardson
2016-03-14  9:44     ` Thomas Monjalon
2016-03-14  9:48       ` Bruce Richardson
2016-03-09 19:31   ` [PATCH v7 02/11] pmd/cxgbe: add dev_ptype_info_get implementation Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 03/11] pmd/e1000: " Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 04/11] pmd/enic: " Jianfeng Tan
2016-03-10 14:50     ` Bruce Richardson
2016-03-10 14:51       ` Bruce Richardson
2016-03-10 18:23         ` Tan, Jianfeng
2016-03-09 19:31   ` [PATCH v7 05/11] pmd/fm10k: " Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 06/11] pmd/i40e: " Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 07/11] pmd/ixgbe: " Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 08/11] pmd/mlx4: " Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 09/11] pmd/mlx5: " Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 10/11] pmd/nfp: " Jianfeng Tan
2016-03-09 19:31   ` [PATCH v7 11/11] pmd/vmxnet3: " Jianfeng Tan
2016-03-10 14:55   ` [PATCH v7 00/11] Add API to get packet type info Bruce Richardson
2016-03-14  7:42 ` [PATCH v8 00/11] Add API to get supported packet types Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 01/11] ethdev: add API to query " Jianfeng Tan
2016-03-14 17:14     ` Ferruh Yigit
2016-03-14 20:50       ` [PATCH v9 " Jianfeng Tan
2016-03-18  9:17         ` Tan, Jianfeng
2016-03-15  1:42       ` [PATCH v8 " Tan, Jianfeng
2016-03-14  7:42   ` [PATCH v8 02/11] cxgbe: add dev_supported_ptypes_get implementation Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 03/11] e1000: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 04/11] enic: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 05/11] fm10k: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 06/11] i40e: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 07/11] ixgbe: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 08/11] mlx4: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 09/11] mlx5: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 10/11] nfp: " Jianfeng Tan
2016-03-14  7:42   ` [PATCH v8 11/11] vmxnet3: " Jianfeng Tan
2016-03-18 16:21   ` [PATCH v8 00/11] Add API to get supported packet types Bruce Richardson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.