These filters are mashed together even though they almost do not share any code at all between each other. Separate security filter from ntuple filter and parse it separately.
Signed-off-by: Anatoly Burakov <[email protected]> --- drivers/net/intel/ixgbe/ixgbe_flow.c | 194 ++++++++++++++++----------- 1 file changed, 114 insertions(+), 80 deletions(-) diff --git a/drivers/net/intel/ixgbe/ixgbe_flow.c b/drivers/net/intel/ixgbe/ixgbe_flow.c index 491e8bccc5..78f40b5c37 100644 --- a/drivers/net/intel/ixgbe/ixgbe_flow.c +++ b/drivers/net/intel/ixgbe/ixgbe_flow.c @@ -214,74 +214,6 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr, memset(ð_null, 0, sizeof(struct rte_flow_item_eth)); memset(&vlan_null, 0, sizeof(struct rte_flow_item_vlan)); - /** - * Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY - */ - act = next_no_void_action(actions, NULL); - if (act->type == RTE_FLOW_ACTION_TYPE_SECURITY) { - const void *conf = act->conf; - const struct rte_flow_action_security *sec_act; - struct rte_security_session *session; - struct ip_spec spec; - - if (conf == NULL) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION_CONF, - act, "NULL security conf."); - return -rte_errno; - } - /* check if the next not void item is END */ - act = next_no_void_action(actions, act); - if (act->type != RTE_FLOW_ACTION_TYPE_END) { - memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, - act, "Not supported action."); - return -rte_errno; - } - - /* get the IP pattern*/ - item = next_no_void_pattern(pattern, NULL); - while (item->type != RTE_FLOW_ITEM_TYPE_IPV4 && - item->type != RTE_FLOW_ITEM_TYPE_IPV6) { - if (item->last || - item->type == RTE_FLOW_ITEM_TYPE_END) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM, - item, "IP pattern missing."); - return -rte_errno; - } - item = next_no_void_pattern(pattern, item); - } - if (item->spec == NULL) { - rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ITEM_SPEC, item, - "NULL IP pattern."); - return -rte_errno; - } - - filter->proto = IPPROTO_ESP; - sec_act = (const struct rte_flow_action_security *)conf; - spec.is_ipv6 = item->type == RTE_FLOW_ITEM_TYPE_IPV6; - if (spec.is_ipv6) { - const struct rte_flow_item_ipv6 *ipv6 = item->spec; - spec.spec.ipv6 = *ipv6; - } else { - const struct rte_flow_item_ipv4 *ipv4 = item->spec; - spec.spec.ipv4 = *ipv4; - } - - /* - * we get pointer to security session from security action, - * which is const. however, we do need to act on the session, so - * either we do some kind of pointer based lookup to get session - * pointer internally (which quickly gets unwieldy for lots of - * flows case), or we simply cast away constness. - */ - session = RTE_CAST_PTR(struct rte_security_session *, sec_act->security_session); - return ixgbe_crypto_add_ingress_sa_from_flow(session, &spec); - } - /* the first not void item can be MAC or IPv4 */ item = next_no_void_pattern(pattern, NULL); @@ -640,6 +572,104 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr, return 0; } +static int +ixgbe_parse_security_filter(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, + const struct rte_flow_item pattern[], const struct rte_flow_action actions[], + struct rte_flow_error *error) +{ + struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private); + const struct rte_flow_action_security *security; + struct rte_security_session *session; + const struct rte_flow_item *item; + const struct rte_flow_action *act; + struct ip_spec spec; + + if (hw->mac.type != ixgbe_mac_82599EB && + hw->mac.type != ixgbe_mac_X540 && + hw->mac.type != ixgbe_mac_X550 && + hw->mac.type != ixgbe_mac_X550EM_x && + hw->mac.type != ixgbe_mac_X550EM_a && + hw->mac.type != ixgbe_mac_E610) + return -ENOTSUP; + + if (pattern == NULL) { + rte_flow_error_set(error, + EINVAL, RTE_FLOW_ERROR_TYPE_ITEM_NUM, + NULL, "NULL pattern."); + return -rte_errno; + } + if (actions == NULL) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION_NUM, + NULL, "NULL action."); + return -rte_errno; + } + if (attr == NULL) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ATTR, + NULL, "NULL attribute."); + return -rte_errno; + } + + /* check if next non-void action is security */ + act = next_no_void_action(actions, NULL); + if (act->type != RTE_FLOW_ACTION_TYPE_SECURITY) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, "Not supported action."); + } + security = act->conf; + if (security == NULL) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, act, + "NULL security action config."); + } + /* check if the next not void item is END */ + act = next_no_void_action(actions, act); + if (act->type != RTE_FLOW_ACTION_TYPE_END) { + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + act, "Not supported action."); + } + + /* get the IP pattern*/ + item = next_no_void_pattern(pattern, NULL); + while (item->type != RTE_FLOW_ITEM_TYPE_IPV4 && + item->type != RTE_FLOW_ITEM_TYPE_IPV6) { + if (item->last || item->type == RTE_FLOW_ITEM_TYPE_END) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, "IP pattern missing."); + return -rte_errno; + } + item = next_no_void_pattern(pattern, item); + } + if (item->spec == NULL) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM_SPEC, item, + "NULL IP pattern."); + return -rte_errno; + } + spec.is_ipv6 = item->type == RTE_FLOW_ITEM_TYPE_IPV6; + if (spec.is_ipv6) { + const struct rte_flow_item_ipv6 *ipv6 = item->spec; + spec.spec.ipv6 = *ipv6; + } else { + const struct rte_flow_item_ipv4 *ipv4 = item->spec; + spec.spec.ipv4 = *ipv4; + } + + /* + * we get pointer to security session from security action, + * which is const. however, we do need to act on the session, so + * either we do some kind of pointer based lookup to get session + * pointer internally (which quickly gets unwieldy for lots of + * flows case), or we simply cast away constness. + */ + session = RTE_CAST_PTR(struct rte_security_session *, security->security_session); + return ixgbe_crypto_add_ingress_sa_from_flow(session, &spec); +} + /* a specific function for ixgbe because the flags is specific */ static int ixgbe_parse_ntuple_filter(struct rte_eth_dev *dev, @@ -661,10 +691,6 @@ ixgbe_parse_ntuple_filter(struct rte_eth_dev *dev, if (ret) return ret; - /* ESP flow not really a flow*/ - if (filter->proto == IPPROTO_ESP) - return 0; - /* Ixgbe doesn't support tcp flags. */ if (filter->flags & RTE_NTUPLE_FLAGS_TCP_FLAG) { memset(filter, 0, sizeof(struct rte_eth_ntuple_filter)); @@ -3099,18 +3125,19 @@ ixgbe_flow_create(struct rte_eth_dev *dev, TAILQ_INSERT_TAIL(&ixgbe_flow_list, ixgbe_flow_mem_ptr, entries); - memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter)); - ret = ixgbe_parse_ntuple_filter(dev, attr, pattern, - actions, &ntuple_filter, error); - - /* ESP flow not really a flow*/ - if (ntuple_filter.proto == IPPROTO_ESP) { - if (ret != 0) - goto out; + /** + * Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY + */ + ret = ixgbe_parse_security_filter(dev, attr, pattern, actions, error); + if (!ret) { flow->is_security = true; return flow; } + memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter)); + ret = ixgbe_parse_ntuple_filter(dev, attr, pattern, + actions, &ntuple_filter, error); + if (!ret) { ret = ixgbe_add_del_ntuple_filter(dev, &ntuple_filter, TRUE); if (!ret) { @@ -3334,6 +3361,13 @@ ixgbe_flow_validate(struct rte_eth_dev *dev, struct ixgbe_rte_flow_rss_conf rss_conf; int ret; + /** + * Special case for flow action type RTE_FLOW_ACTION_TYPE_SECURITY + */ + ret = ixgbe_parse_security_filter(dev, attr, pattern, actions, error); + if (!ret) + return 0; + memset(&ntuple_filter, 0, sizeof(struct rte_eth_ntuple_filter)); ret = ixgbe_parse_ntuple_filter(dev, attr, pattern, actions, &ntuple_filter, error); -- 2.47.3

