From e6c0f28f3ffcfeea9dceb8720d757d8601340ad3 Mon Sep 17 00:00:00 2001 From: Wei Zhao Date: Fri, 3 Apr 2020 12:45:58 +0800 Subject: [PATCH] net/ice: support more PPPoE input set This patch add more support for PPPoE packet, it enable switch filter to direct PPPoE packet base on session id and PPP protocol type. Signed-off-by: Wei Zhao Acked-by: Qi Zhang --- 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(-) diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c index c0420797eb..0fdc7e617d 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 ede6ec8242..3361ecbd91 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 4db8f1471b..add66e683b 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.20.1