From: Gagandeep Singh <[email protected]> Add rte_flow pattern support for MPLS and PPPoE items in the dpaa2 PMD flow engine.
For a pattern with no spec/mask, the frame is identified by its Frame Attribute Flag (FAF_MPLS_FRAM / FAF_PPPOE_PPP_FRAM) for both the QoS and flow steering tables. When a spec is present, the MPLS label (NH_FLD_MPLS_MPLSL_1) or the PPPoE session id (NH_FLD_PPPOE_SID) is added as a header extract rule for both tables. Signed-off-by: Gagandeep Singh <[email protected]> --- drivers/net/dpaa2/dpaa2_flow.c | 196 +++++++++++++++++++++++++++++++++ 1 file changed, 196 insertions(+) diff --git a/drivers/net/dpaa2/dpaa2_flow.c b/drivers/net/dpaa2/dpaa2_flow.c index 2e44bff766..90e0b66258 100644 --- a/drivers/net/dpaa2/dpaa2_flow.c +++ b/drivers/net/dpaa2/dpaa2_flow.c @@ -80,6 +80,8 @@ enum rte_flow_item_type dpaa2_hp_supported_pattern_type[] = { RTE_FLOW_ITEM_TYPE_GTP, RTE_FLOW_ITEM_TYPE_ESP, RTE_FLOW_ITEM_TYPE_AH, + RTE_FLOW_ITEM_TYPE_MPLS, + RTE_FLOW_ITEM_TYPE_PPPOES, RTE_FLOW_ITEM_TYPE_RAW }; @@ -180,8 +182,17 @@ static const struct rte_flow_item_gtp dpaa2_flow_item_gtp_mask = { .teid = RTE_BE32(0xffffffff), }; +static const struct rte_flow_item_mpls dpaa2_flow_item_mpls_mask = { + .label_tc_s = { 0xff, 0xff, 0xff }, +}; + +static const struct rte_flow_item_pppoe dpaa2_flow_item_pppoe_mask = { + .session_id = RTE_BE16(0xffff), +}; + #endif + #define DPAA2_FLOW_DUMP printf static inline void @@ -1764,6 +1775,14 @@ dpaa2_flow_extract_support(const uint8_t *mask_src, mask_support = (const char *)&dpaa2_flow_item_gtp_mask; size = sizeof(struct rte_flow_item_gtp); break; + case RTE_FLOW_ITEM_TYPE_MPLS: + mask_support = (const char *)&dpaa2_flow_item_mpls_mask; + size = sizeof(struct rte_flow_item_mpls); + break; + case RTE_FLOW_ITEM_TYPE_PPPOES: + mask_support = (const char *)&dpaa2_flow_item_pppoe_mask; + size = sizeof(struct rte_flow_item_pppoe); + break; default: return -EINVAL; } @@ -4041,6 +4060,163 @@ dpaa2_configure_flow_gtp(struct dpaa2_dev_flow *flow, return 0; } +static int +dpaa2_configure_flow_mpls(struct dpaa2_dev_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_dpaa2_flow_item *dpaa2_pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused, + int *device_configured) +{ + int ret, local_cfg = 0; + uint32_t group; + const struct rte_flow_item_mpls *spec, *mask; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + const struct rte_flow_item *pattern = + &dpaa2_pattern->generic_item; + + group = attr->group; + + /* Parse pattern list to get the matching parameters */ + spec = pattern->spec; + mask = pattern->mask ? + pattern->mask : &dpaa2_flow_item_mpls_mask; + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->tc_index = attr->priority; + + if (dpaa2_pattern->in_tunnel) { + DPAA2_PMD_ERR("Tunnel-MPLS distribution not support"); + return -ENOTSUP; + } + + if (!spec) { + ret = dpaa2_flow_identify_by_faf(priv, flow, + FAF_MPLS_FRAM, DPAA2_FLOW_QOS_TYPE, + group, &local_cfg); + if (ret) + return ret; + + ret = dpaa2_flow_identify_by_faf(priv, flow, + FAF_MPLS_FRAM, DPAA2_FLOW_FS_TYPE, + group, &local_cfg); + if (ret) + return ret; + + (*device_configured) |= local_cfg; + return 0; + } + + ret = dpaa2_flow_extract_support((const uint8_t *)mask, + RTE_FLOW_ITEM_TYPE_MPLS); + if (ret) { + DPAA2_PMD_WARN("Extract field(s) of MPLS not support."); + return ret; + } + + if (!mask->label_tc_s[0] && !mask->label_tc_s[1] && + !mask->label_tc_s[2]) + return 0; + + ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_MPLS, + NH_FLD_MPLS_MPLSL_1, spec->label_tc_s, + mask->label_tc_s, sizeof(mask->label_tc_s), + priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); + if (ret) + return ret; + + ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_MPLS, + NH_FLD_MPLS_MPLSL_1, spec->label_tc_s, + mask->label_tc_s, sizeof(mask->label_tc_s), + priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); + if (ret) + return ret; + + (*device_configured) |= local_cfg; + + return 0; +} + +static int +dpaa2_configure_flow_pppoe(struct dpaa2_dev_flow *flow, + struct rte_eth_dev *dev, + const struct rte_flow_attr *attr, + const struct rte_dpaa2_flow_item *dpaa2_pattern, + const struct rte_flow_action actions[] __rte_unused, + struct rte_flow_error *error __rte_unused, + int *device_configured) +{ + int ret, local_cfg = 0; + uint32_t group; + const struct rte_flow_item_pppoe *spec, *mask; + struct dpaa2_dev_priv *priv = dev->data->dev_private; + const struct rte_flow_item *pattern = + &dpaa2_pattern->generic_item; + + group = attr->group; + + /* Parse pattern list to get the matching parameters */ + spec = pattern->spec; + mask = pattern->mask ? + pattern->mask : &dpaa2_flow_item_pppoe_mask; + + /* Get traffic class index and flow id to be configured */ + flow->tc_id = group; + flow->tc_index = attr->priority; + + if (dpaa2_pattern->in_tunnel) { + DPAA2_PMD_ERR("Tunnel-PPPoE distribution not support"); + return -ENOTSUP; + } + + if (!spec) { + ret = dpaa2_flow_identify_by_faf(priv, flow, + FAF_PPPOE_PPP_FRAM, DPAA2_FLOW_QOS_TYPE, + group, &local_cfg); + if (ret) + return ret; + + ret = dpaa2_flow_identify_by_faf(priv, flow, + FAF_PPPOE_PPP_FRAM, DPAA2_FLOW_FS_TYPE, + group, &local_cfg); + if (ret) + return ret; + + (*device_configured) |= local_cfg; + return 0; + } + + ret = dpaa2_flow_extract_support((const uint8_t *)mask, + RTE_FLOW_ITEM_TYPE_PPPOES); + if (ret) { + DPAA2_PMD_WARN("Extract field(s) of PPPoE not support."); + return ret; + } + + if (!mask->session_id) + return 0; + + ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_PPPOE, + NH_FLD_PPPOE_SID, &spec->session_id, + &mask->session_id, sizeof(rte_be16_t), + priv, group, &local_cfg, DPAA2_FLOW_QOS_TYPE); + if (ret) + return ret; + + ret = dpaa2_flow_add_hdr_extract_rule(flow, NET_PROT_PPPOE, + NH_FLD_PPPOE_SID, &spec->session_id, + &mask->session_id, sizeof(rte_be16_t), + priv, group, &local_cfg, DPAA2_FLOW_FS_TYPE); + if (ret) + return ret; + + (*device_configured) |= local_cfg; + + return 0; +} + static int dpaa2_configure_flow_raw(struct dpaa2_dev_flow *flow, struct rte_eth_dev *dev, @@ -4712,6 +4888,26 @@ dpaa2_generic_flow_set(struct dpaa2_dev_flow *flow, goto end_flow_set; } break; + case RTE_FLOW_ITEM_TYPE_MPLS: + ret = dpaa2_configure_flow_mpls(flow, + dev, attr, &dpaa2_pattern[i], + actions, error, + &is_keycfg_configured); + if (ret) { + DPAA2_PMD_ERR("MPLS flow config failed!"); + goto end_flow_set; + } + break; + case RTE_FLOW_ITEM_TYPE_PPPOES: + ret = dpaa2_configure_flow_pppoe(flow, + dev, attr, &dpaa2_pattern[i], + actions, error, + &is_keycfg_configured); + if (ret) { + DPAA2_PMD_ERR("PPPoE flow config failed!"); + goto end_flow_set; + } + break; case RTE_FLOW_ITEM_TYPE_RAW: ret = dpaa2_configure_flow_raw(flow, dev, attr, &dpaa2_pattern[i], -- 2.43.0

