diff mbox

[dpdk-dev,v4,05/12] i40e: extend flow director to filter by IP Header

Message ID 1457580346-18550-6-git-send-email-jingjing.wu@intel.com (mailing list archive)
State Superseded, archived
Delegated to: Bruce Richardson
Headers show

Commit Message

Wu, Jingjing March 10, 2016, 3:25 a.m. UTC
This patch extended flow director to select more IP Header fields
as filter input set.

Signed-off-by: Jingjing Wu <jingjing.wu@intel.com>
Acked-by: Helin Zhang <helin.zhang@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 69 ++++++++++++++++++++++++++++++++++--------
 drivers/net/i40e/i40e_fdir.c   | 26 +++++++++++-----
 2 files changed, 75 insertions(+), 20 deletions(-)
diff mbox

Patch

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 1c672c1..e24b026 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -211,6 +211,8 @@ 
 #define I40E_REG_INSET_L3_IP4_TOS                0x0040000000000000ULL
 /* IPv4 Protocol */
 #define I40E_REG_INSET_L3_IP4_PROTO              0x0004000000000000ULL
+/* IPv4 Time to Live */
+#define I40E_REG_INSET_L3_IP4_TTL                0x0004000000000000ULL
 /* Source IPv6 address */
 #define I40E_REG_INSET_L3_SRC_IP6                0x0007F80000000000ULL
 /* Destination IPv6 address */
@@ -219,6 +221,8 @@ 
 #define I40E_REG_INSET_L3_IP6_TC                 0x0040000000000000ULL
 /* IPv6 Next Header */
 #define I40E_REG_INSET_L3_IP6_NEXT_HDR           0x0008000000000000ULL
+/* IPv6 Hop Limitr */
+#define I40E_REG_INSET_L3_IP6_HOP_LIMIT          0x0008000000000000ULL
 /* Source L4 port */
 #define I40E_REG_INSET_L4_SRC_PORT               0x0000000400000000ULL
 /* Destination L4 port */
@@ -262,10 +266,12 @@ 
 #define I40E_TRANSLATE_INSET 0
 #define I40E_TRANSLATE_REG   1
 
-#define I40E_INSET_IPV4_TOS_MASK      0x0009FF00UL
-#define I40E_INSET_IPV4_PROTO_MASK    0x000DFF00UL
-#define I40E_INSET_IPV6_TC_MASK       0x0009F00FUL
-#define I40E_INSET_IPV6_NEXT_HDR_MASK 0x000C00FFUL
+#define I40E_INSET_IPV4_TOS_MASK        0x0009FF00UL
+#define I40E_INSET_IPv4_TTL_MASK        0x000D00FFUL
+#define I40E_INSET_IPV4_PROTO_MASK      0x000DFF00UL
+#define I40E_INSET_IPV6_TC_MASK         0x0009F00FUL
+#define I40E_INSET_IPV6_HOP_LIMIT_MASK  0x000CFF00UL
+#define I40E_INSET_IPV6_NEXT_HDR_MASK   0x000C00FFUL
 
 static int eth_i40e_dev_init(struct rte_eth_dev *eth_dev);
 static int eth_i40e_dev_uninit(struct rte_eth_dev *eth_dev);
@@ -6610,30 +6616,47 @@  i40e_get_valid_input_set(enum i40e_filter_pctype pctype,
 	 */
 	static const uint64_t valid_fdir_inset_table[] = {
 		[I40E_FILTER_PCTYPE_FRAG_IPV4] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_UDP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_TCP] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_SCTP] =
 		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_TTL |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV4_OTHER] =
-		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST,
+		I40E_INSET_IPV4_SRC | I40E_INSET_IPV4_DST |
+		I40E_INSET_IPV4_TOS | I40E_INSET_IPV4_PROTO |
+		I40E_INSET_IPV4_TTL,
 		[I40E_FILTER_PCTYPE_FRAG_IPV6] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_UDP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_TCP] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
+		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_SCTP] =
 		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_HOP_LIMIT |
 		I40E_INSET_SRC_PORT | I40E_INSET_DST_PORT |
 		I40E_INSET_SCTP_VT,
 		[I40E_FILTER_PCTYPE_NONF_IPV6_OTHER] =
-		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST,
+		I40E_INSET_IPV6_SRC | I40E_INSET_IPV6_DST |
+		I40E_INSET_IPV6_TC | I40E_INSET_IPV6_NEXT_HDR |
+		I40E_INSET_IPV6_HOP_LIMIT,
 		[I40E_FILTER_PCTYPE_L2_PAYLOAD] =
 		I40E_INSET_LAST_ETHER_TYPE,
 	};
@@ -6733,11 +6756,14 @@  i40e_parse_input_set(uint64_t *inset,
 		{RTE_ETH_INPUT_SET_L3_DST_IP4, I40E_INSET_IPV4_DST},
 		{RTE_ETH_INPUT_SET_L3_IP4_TOS, I40E_INSET_IPV4_TOS},
 		{RTE_ETH_INPUT_SET_L3_IP4_PROTO, I40E_INSET_IPV4_PROTO},
+		{RTE_ETH_INPUT_SET_L3_IP4_TTL, I40E_INSET_IPV4_TTL},
 		{RTE_ETH_INPUT_SET_L3_SRC_IP6, I40E_INSET_IPV6_SRC},
 		{RTE_ETH_INPUT_SET_L3_DST_IP6, I40E_INSET_IPV6_DST},
 		{RTE_ETH_INPUT_SET_L3_IP6_TC, I40E_INSET_IPV6_TC},
 		{RTE_ETH_INPUT_SET_L3_IP6_NEXT_HEADER,
 			I40E_INSET_IPV6_NEXT_HDR},
+		{RTE_ETH_INPUT_SET_L3_IP6_HOP_LIMITS,
+			I40E_INSET_IPV6_HOP_LIMIT},
 		{RTE_ETH_INPUT_SET_L4_UDP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_TCP_SRC_PORT, I40E_INSET_SRC_PORT},
 		{RTE_ETH_INPUT_SET_L4_SCTP_SRC_PORT, I40E_INSET_SRC_PORT},
@@ -6824,10 +6850,12 @@  i40e_translate_input_set_reg(uint64_t input)
 		{I40E_INSET_IPV4_DST, I40E_REG_INSET_L3_DST_IP4},
 		{I40E_INSET_IPV4_TOS, I40E_REG_INSET_L3_IP4_TOS},
 		{I40E_INSET_IPV4_PROTO, I40E_REG_INSET_L3_IP4_PROTO},
+		{I40E_INSET_IPV4_TTL, I40E_REG_INSET_L3_IP4_TTL},
 		{I40E_INSET_IPV6_SRC, I40E_REG_INSET_L3_SRC_IP6},
 		{I40E_INSET_IPV6_DST, I40E_REG_INSET_L3_DST_IP6},
 		{I40E_INSET_IPV6_TC, I40E_REG_INSET_L3_IP6_TC},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_REG_INSET_L3_IP6_NEXT_HDR},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_REG_INSET_L3_IP6_HOP_LIMIT},
 		{I40E_INSET_SRC_PORT, I40E_REG_INSET_L4_SRC_PORT},
 		{I40E_INSET_DST_PORT, I40E_REG_INSET_L4_DST_PORT},
 		{I40E_INSET_SCTP_VT, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG},
@@ -6867,23 +6895,38 @@  static int
 i40e_generate_inset_mask_reg(uint64_t inset, uint32_t *mask, uint8_t nb_elem)
 {
 	uint8_t i, idx = 0;
+	uint64_t inset_need_mask = inset;
 
 	static const struct {
 		uint64_t inset;
 		uint32_t mask;
 	} inset_mask_map[] = {
 		{I40E_INSET_IPV4_TOS, I40E_INSET_IPV4_TOS_MASK},
+		{I40E_INSET_IPV4_PROTO | I40E_INSET_IPV4_TTL, 0},
 		{I40E_INSET_IPV4_PROTO, I40E_INSET_IPV4_PROTO_MASK},
+		{I40E_INSET_IPV4_TTL, I40E_INSET_IPv4_TTL_MASK},
 		{I40E_INSET_IPV6_TC, I40E_INSET_IPV6_TC_MASK},
+		{I40E_INSET_IPV6_NEXT_HDR | I40E_INSET_IPV6_HOP_LIMIT, 0},
 		{I40E_INSET_IPV6_NEXT_HDR, I40E_INSET_IPV6_NEXT_HDR_MASK},
+		{I40E_INSET_IPV6_HOP_LIMIT, I40E_INSET_IPV6_HOP_LIMIT_MASK}
 	};
 
 	if (!inset || !mask || !nb_elem)
 		return 0;
 
-
 	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
-		if ((inset & inset_mask_map[i].inset) == inset_mask_map[i].inset) {
+		/* Clear the inset bit, if no MASK is required,
+		 * for example proto + ttl
+		 */
+		if ((inset & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset && inset_mask_map[i].mask == 0)
+			inset_need_mask &= ~inset_mask_map[i].inset;
+		if (!inset_need_mask)
+			return 0;
+	}
+	for (i = 0, idx = 0; i < RTE_DIM(inset_mask_map); i++) {
+		if ((inset_need_mask & inset_mask_map[i].inset) ==
+		     inset_mask_map[i].inset) {
 			if (idx >= nb_elem) {
 				PMD_DRV_LOG(ERR, "exceed maximal number of bitmasks");
 				return -EINVAL;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index f8055e7..ebbe612 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -66,7 +66,9 @@ 
 #define I40E_FDIR_IP_DEFAULT_TTL            0x40
 #define I40E_FDIR_IP_DEFAULT_VERSION_IHL    0x45
 #define I40E_FDIR_TCP_DEFAULT_DATAOFF       0x50
-#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60300000
+#define I40E_FDIR_IPv6_DEFAULT_VTC_FLOW     0x60000000
+#define I40E_FDIR_IPv6_TC_OFFSET            20
+
 #define I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS   0xFF
 #define I40E_FDIR_IPv6_PAYLOAD_LEN          380
 #define I40E_FDIR_UDP_DEFAULT_LEN           400
@@ -720,7 +722,13 @@  i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		ip->version_ihl = I40E_FDIR_IP_DEFAULT_VERSION_IHL;
 		/* set len to by default */
 		ip->total_length = rte_cpu_to_be_16(I40E_FDIR_IP_DEFAULT_LEN);
-		ip->time_to_live = I40E_FDIR_IP_DEFAULT_TTL;
+		ip->next_proto_id = fdir_input->flow.ip4_flow.proto ?
+					fdir_input->flow.ip4_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip->time_to_live = fdir_input->flow.ip4_flow.ttl ?
+					fdir_input->flow.ip4_flow.ttl :
+					I40E_FDIR_IP_DEFAULT_TTL;
+		ip->type_of_service = fdir_input->flow.ip4_flow.tos;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -728,7 +736,6 @@  i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		 */
 		ip->src_addr = fdir_input->flow.ip4_flow.dst_ip;
 		ip->dst_addr = fdir_input->flow.ip4_flow.src_ip;
-		ip->next_proto_id = next_proto[fdir_input->flow_type];
 		break;
 	case RTE_ETH_FLOW_NONFRAG_IPV6_TCP:
 	case RTE_ETH_FLOW_NONFRAG_IPV6_UDP:
@@ -739,11 +746,17 @@  i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 
 		ether->ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv6);
 		ip6->vtc_flow =
-			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW);
+			rte_cpu_to_be_32(I40E_FDIR_IPv6_DEFAULT_VTC_FLOW |
+					 (fdir_input->flow.ipv6_flow.tc <<
+					  I40E_FDIR_IPv6_TC_OFFSET));
 		ip6->payload_len =
 			rte_cpu_to_be_16(I40E_FDIR_IPv6_PAYLOAD_LEN);
-		ip6->hop_limits = I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
-
+		ip6->proto = fdir_input->flow.ipv6_flow.proto ?
+					fdir_input->flow.ipv6_flow.proto :
+					next_proto[fdir_input->flow_type];
+		ip6->hop_limits = fdir_input->flow.ipv6_flow.hop_limits ?
+					fdir_input->flow.ipv6_flow.hop_limits :
+					I40E_FDIR_IPv6_DEFAULT_HOP_LIMITS;
 		/*
 		 * The source and destination fields in the transmitted packet
 		 * need to be presented in a reversed order with respect
@@ -755,7 +768,6 @@  i40e_fdir_fill_eth_ip_head(const struct rte_eth_fdir_input *fdir_input,
 		rte_memcpy(&(ip6->dst_addr),
 			   &(fdir_input->flow.ipv6_flow.src_ip),
 			   IPV6_ADDR_LEN);
-		ip6->proto = next_proto[fdir_input->flow_type];
 		break;
 	default:
 		PMD_DRV_LOG(ERR, "unknown flow type %u.",