[v4,02/13] net/ice: support for more PPPoE input set

Message ID 20200403044609.27512-3-wei.zhao1@intel.com (mailing list archive)
State Accepted, archived
Delegated to: xiaolong ye
Headers
Series add switch filter support for intel DCF |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Zhao1, Wei April 3, 2020, 4:45 a.m. UTC
  This patch add more support for PPPoE packet,
it enable swicth filter to direct PPPoE packet base on
session id and PPP protocol type.

Signed-off-by: Wei Zhao <wei.zhao1@intel.com>
---
 drivers/net/ice/ice_generic_flow.c  | 13 +++++
 drivers/net/ice/ice_generic_flow.h  |  9 ++++
 drivers/net/ice/ice_switch_filter.c | 82 +++++++++++++++++++++++++++--
 3 files changed, 99 insertions(+), 5 deletions(-)
  

Patch

diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c
index c0420797e..0fdc7e617 100644
--- a/drivers/net/ice/ice_generic_flow.c
+++ b/drivers/net/ice/ice_generic_flow.c
@@ -1122,12 +1122,25 @@  enum rte_flow_item_type pattern_eth_pppoes[] = {
 	RTE_FLOW_ITEM_TYPE_PPPOES,
 	RTE_FLOW_ITEM_TYPE_END,
 };
+enum rte_flow_item_type pattern_eth_pppoes_proto[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_PPPOES,
+	RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID,
+	RTE_FLOW_ITEM_TYPE_END,
+};
 enum rte_flow_item_type pattern_eth_vlan_pppoes[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
 	RTE_FLOW_ITEM_TYPE_VLAN,
 	RTE_FLOW_ITEM_TYPE_PPPOES,
 	RTE_FLOW_ITEM_TYPE_END,
 };
+enum rte_flow_item_type pattern_eth_vlan_pppoes_proto[] = {
+	RTE_FLOW_ITEM_TYPE_ETH,
+	RTE_FLOW_ITEM_TYPE_VLAN,
+	RTE_FLOW_ITEM_TYPE_PPPOES,
+	RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID,
+	RTE_FLOW_ITEM_TYPE_END,
+};
 enum rte_flow_item_type pattern_eth_qinq_pppoes[] = {
 	RTE_FLOW_ITEM_TYPE_ETH,
 	RTE_FLOW_ITEM_TYPE_VLAN,
diff --git a/drivers/net/ice/ice_generic_flow.h b/drivers/net/ice/ice_generic_flow.h
index ede6ec824..3361ecbd9 100644
--- a/drivers/net/ice/ice_generic_flow.h
+++ b/drivers/net/ice/ice_generic_flow.h
@@ -30,6 +30,7 @@ 
 #define ICE_PROT_VXLAN             (1ULL << 19)
 #define ICE_PROT_NVGRE             (1ULL << 20)
 #define ICE_PROT_GTPU              (1ULL << 21)
+#define ICE_PROT_PPPOE_S           (1ULL << 22)
 
 /* field */
 
@@ -49,6 +50,8 @@ 
 #define ICE_NVGRE_TNI              (1ULL << 50)
 #define ICE_GTPU_TEID              (1ULL << 49)
 #define ICE_GTPU_QFI               (1ULL << 48)
+#define ICE_PPPOE_SESSION          (1ULL << 47)
+#define ICE_PPPOE_PROTO            (1ULL << 46)
 
 /* input set */
 
@@ -177,6 +180,10 @@ 
 	(ICE_PROT_GTPU | ICE_GTPU_TEID)
 #define ICE_INSET_GTPU_QFI \
 	(ICE_PROT_GTPU | ICE_GTPU_QFI)
+#define ICE_INSET_PPPOE_SESSION \
+	(ICE_PROT_PPPOE_S | ICE_PPPOE_SESSION)
+#define ICE_INSET_PPPOE_PROTO \
+	(ICE_PROT_PPPOE_S | ICE_PPPOE_PROTO)
 
 /* empty pattern */
 extern enum rte_flow_item_type pattern_empty[];
@@ -349,7 +356,9 @@  extern enum rte_flow_item_type pattern_eth_pppoed[];
 extern enum rte_flow_item_type pattern_eth_vlan_pppoed[];
 extern enum rte_flow_item_type pattern_eth_qinq_pppoed[];
 extern enum rte_flow_item_type pattern_eth_pppoes[];
+extern enum rte_flow_item_type pattern_eth_pppoes_proto[];
 extern enum rte_flow_item_type pattern_eth_vlan_pppoes[];
+extern enum rte_flow_item_type pattern_eth_vlan_pppoes_proto[];
 extern enum rte_flow_item_type pattern_eth_qinq_pppoes[];
 extern enum rte_flow_item_type pattern_eth_pppoes_ipv4[];
 extern enum rte_flow_item_type pattern_eth_vlan_pppoes_ipv4[];
diff --git a/drivers/net/ice/ice_switch_filter.c b/drivers/net/ice/ice_switch_filter.c
index 4db8f1471..add66e683 100644
--- a/drivers/net/ice/ice_switch_filter.c
+++ b/drivers/net/ice/ice_switch_filter.c
@@ -87,7 +87,11 @@ 
 	ICE_INSET_TUN_IPV4_TOS)
 #define ICE_SW_INSET_MAC_PPPOE  ( \
 	ICE_INSET_VLAN_OUTER | ICE_INSET_VLAN_INNER | \
-	ICE_INSET_DMAC | ICE_INSET_ETHERTYPE)
+	ICE_INSET_DMAC | ICE_INSET_ETHERTYPE | ICE_INSET_PPPOE_SESSION)
+#define ICE_SW_INSET_MAC_PPPOE_PROTO  ( \
+	ICE_INSET_VLAN_OUTER | ICE_INSET_VLAN_INNER | \
+	ICE_INSET_DMAC | ICE_INSET_ETHERTYPE | ICE_INSET_PPPOE_SESSION | \
+	ICE_INSET_PPPOE_PROTO)
 
 struct sw_meta {
 	struct ice_adv_lkup_elem *list;
@@ -135,6 +139,10 @@  ice_pattern_match_item ice_switch_pattern_dist_comms[] = {
 			ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
 	{pattern_eth_vlan_pppoes,
 			ICE_SW_INSET_MAC_PPPOE, ICE_INSET_NONE},
+	{pattern_eth_pppoes_proto,
+			ICE_SW_INSET_MAC_PPPOE_PROTO, ICE_INSET_NONE},
+	{pattern_eth_vlan_pppoes_proto,
+			ICE_SW_INSET_MAC_PPPOE_PROTO, ICE_INSET_NONE},
 };
 
 static struct
@@ -316,12 +324,15 @@  ice_switch_inset_get(const struct rte_flow_item pattern[],
 	const struct rte_flow_item_vxlan *vxlan_spec, *vxlan_mask;
 	const struct rte_flow_item_vlan *vlan_spec, *vlan_mask;
 	const struct rte_flow_item_pppoe *pppoe_spec, *pppoe_mask;
+	const struct rte_flow_item_pppoe_proto_id *pppoe_proto_spec,
+				*pppoe_proto_mask;
 	uint8_t  ipv6_addr_mask[16] = {
 		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
 		0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
 	uint64_t input_set = ICE_INSET_NONE;
 	uint16_t j, t = 0;
 	uint16_t tunnel_valid = 0;
+	uint16_t pppoe_valid = 0;
 
 
 	for (item = pattern; item->type !=
@@ -885,14 +896,75 @@  ice_switch_inset_get(const struct rte_flow_item pattern[],
 			pppoe_mask = item->mask;
 			/* Check if PPPoE item is used to describe protocol.
 			 * If yes, both spec and mask should be NULL.
+			 * If no, both spec and mask shouldn't be NULL.
 			 */
-			if (pppoe_spec || pppoe_mask) {
+			if ((!pppoe_spec && pppoe_mask) ||
+				(pppoe_spec && !pppoe_mask)) {
 				rte_flow_error_set(error, EINVAL,
-					   RTE_FLOW_ERROR_TYPE_ITEM,
-					   item,
-					   "Invalid pppoe item");
+					RTE_FLOW_ERROR_TYPE_ITEM,
+					item,
+					"Invalid pppoe item");
 				return 0;
 			}
+			if (pppoe_spec && pppoe_mask) {
+				/* Check pppoe mask and update input set */
+				if (pppoe_mask->length ||
+					pppoe_mask->code ||
+					pppoe_mask->version_type) {
+					rte_flow_error_set(error, EINVAL,
+						RTE_FLOW_ERROR_TYPE_ITEM,
+						item,
+						"Invalid pppoe mask");
+					return 0;
+				}
+				list[t].type = ICE_PPPOE;
+				if (pppoe_mask->session_id == UINT16_MAX) {
+					list[t].h_u.pppoe_hdr.session_id =
+						pppoe_spec->session_id;
+					list[t].m_u.pppoe_hdr.session_id =
+						UINT16_MAX;
+					input_set |= ICE_INSET_PPPOE_SESSION;
+				}
+				t++;
+				pppoe_valid = 1;
+			} else if (!pppoe_spec && !pppoe_mask) {
+				list[t].type = ICE_PPPOE;
+			}
+
+			break;
+
+		case RTE_FLOW_ITEM_TYPE_PPPOE_PROTO_ID:
+			pppoe_proto_spec = item->spec;
+			pppoe_proto_mask = item->mask;
+			/* Check if PPPoE optional proto_id item
+			 * is used to describe protocol.
+			 * If yes, both spec and mask should be NULL.
+			 * If no, both spec and mask shouldn't be NULL.
+			 */
+			if ((!pppoe_proto_spec && pppoe_proto_mask) ||
+				(pppoe_proto_spec && !pppoe_proto_mask)) {
+				rte_flow_error_set(error, EINVAL,
+					RTE_FLOW_ERROR_TYPE_ITEM,
+					item,
+					"Invalid pppoe proto item");
+				return 0;
+			}
+			if (pppoe_proto_spec && pppoe_proto_mask) {
+				if (pppoe_valid)
+					t--;
+				list[t].type = ICE_PPPOE;
+				if (pppoe_proto_mask->proto_id == UINT16_MAX) {
+					list[t].h_u.pppoe_hdr.ppp_prot_id =
+						pppoe_proto_spec->proto_id;
+					list[t].m_u.pppoe_hdr.ppp_prot_id =
+						UINT16_MAX;
+					input_set |= ICE_INSET_PPPOE_PROTO;
+				}
+				t++;
+			} else if (!pppoe_proto_spec && !pppoe_proto_mask) {
+				list[t].type = ICE_PPPOE;
+			}
+
 			break;
 
 		case RTE_FLOW_ITEM_TYPE_VOID: