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.zh...@intel.com>
---
 config/common_linux                 |  1 +
 drivers/net/ice/ice_generic_flow.c  | 13 +++++
 drivers/net/ice/ice_generic_flow.h  |  9 ++++
 drivers/net/ice/ice_switch_filter.c | 82 +++++++++++++++++++++++++++--
 4 files changed, 100 insertions(+), 5 deletions(-)

diff --git a/config/common_linux b/config/common_linux
index 816810671..c6630d2bd 100644
--- a/config/common_linux
+++ b/config/common_linux
@@ -8,6 +8,7 @@ CONFIG_RTE_EXEC_ENV_LINUX=y
 CONFIG_RTE_EXEC_ENV_LINUXAPP=y
 
 CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=y
+CONFIG_RTE_EAL_IGB_UIO=y
 CONFIG_RTE_EAL_VFIO=y
 CONFIG_RTE_LIBRTE_KNI=y
 CONFIG_RTE_LIBRTE_PMD_KNI=y
diff --git a/drivers/net/ice/ice_generic_flow.c 
b/drivers/net/ice/ice_generic_flow.c
index 38ac799d8..af0fff814 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 adc30ee2a..f1139c690 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             (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 | ICE_PPPOE_SESSION)
+#define ICE_INSET_PPPOE_PROTO \
+       (ICE_PROT_PPPoE | 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 c55e44e1a..39b5c7266 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:
-- 
2.19.1

Reply via email to