X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fmlx5%2Fmlx5_flow_dv.c;h=223a7d0e365bde2506955f8c9191f4026ccb81a4;hb=b59d4d5502dcb1b57be81eb21b5e8bcb80de49e7;hp=76696b7b6209f5f9770a84c31d0b52394a144f5f;hpb=ae8fdc8067c77496bc07680d42f8aa7f6be34a5b;p=dpdk.git diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c index 76696b7b62..223a7d0e36 100644 --- a/drivers/net/mlx5/mlx5_flow_dv.c +++ b/drivers/net/mlx5/mlx5_flow_dv.c @@ -1345,11 +1345,13 @@ mlx5_flow_field_id_to_modify_info if (data->offset < 32) { info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_DMAC_47_16}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1358,10 +1360,8 @@ mlx5_flow_field_id_to_modify_info } info[idx] = (struct field_modify_info){2, 4 * idx, MLX5_MODI_OUT_DMAC_15_0}; - mask[idx] = (width) ? 0x0000ffff : 0x0; - if (width < 16) - mask[idx] = (mask[idx] << (16 - width)) & - 0x0000ffff; + mask[idx] = rte_cpu_to_be_32(0x0000ffff >> + (16 - width)); } else { if (data->offset < 32) info[idx++] = (struct field_modify_info){4, 0, @@ -1375,11 +1375,13 @@ mlx5_flow_field_id_to_modify_info if (data->offset < 32) { info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_SMAC_47_16}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1388,10 +1390,8 @@ mlx5_flow_field_id_to_modify_info } info[idx] = (struct field_modify_info){2, 4 * idx, MLX5_MODI_OUT_SMAC_15_0}; - mask[idx] = (width) ? 0x0000ffff : 0x0; - if (width < 16) - mask[idx] = (mask[idx] << (16 - width)) & - 0x0000ffff; + mask[idx] = rte_cpu_to_be_32(0x0000ffff >> + (16 - width)); } else { if (data->offset < 32) info[idx++] = (struct field_modify_info){4, 0, @@ -1406,91 +1406,71 @@ mlx5_flow_field_id_to_modify_info case RTE_FLOW_FIELD_VLAN_ID: info[idx] = (struct field_modify_info){2, 0, MLX5_MODI_OUT_FIRST_VID}; - if (mask) { - mask[idx] = 0x00000fff; - if (width < 12) - mask[idx] = (mask[idx] << (12 - width)) & - 0x00000fff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x00000fff >> + (12 - width)); break; case RTE_FLOW_FIELD_MAC_TYPE: info[idx] = (struct field_modify_info){2, 0, MLX5_MODI_OUT_ETHERTYPE}; - if (mask) { - mask[idx] = 0x0000ffff; - if (width < 16) - mask[idx] = (mask[idx] << (16 - width)) & - 0x0000ffff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000ffff >> + (16 - width)); break; case RTE_FLOW_FIELD_IPV4_DSCP: info[idx] = (struct field_modify_info){1, 0, MLX5_MODI_OUT_IP_DSCP}; - if (mask) { - mask[idx] = 0x0000003f; - if (width < 6) - mask[idx] = (mask[idx] << (6 - width)) & - 0x0000003f; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000003f >> + (6 - width)); break; case RTE_FLOW_FIELD_IPV4_TTL: info[idx] = (struct field_modify_info){1, 0, MLX5_MODI_OUT_IPV4_TTL}; - if (mask) { - mask[idx] = 0x000000ff; - if (width < 8) - mask[idx] = (mask[idx] << (8 - width)) & - 0x000000ff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x000000ff >> + (8 - width)); break; case RTE_FLOW_FIELD_IPV4_SRC: info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_SIPV4}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0xffffffff >> + (32 - width)); break; case RTE_FLOW_FIELD_IPV4_DST: info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_DIPV4}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0xffffffff >> + (32 - width)); break; case RTE_FLOW_FIELD_IPV6_DSCP: info[idx] = (struct field_modify_info){1, 0, MLX5_MODI_OUT_IP_DSCP}; - if (mask) { - mask[idx] = 0x0000003f; - if (width < 6) - mask[idx] = (mask[idx] << (6 - width)) & - 0x0000003f; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000003f >> + (6 - width)); break; case RTE_FLOW_FIELD_IPV6_HOPLIMIT: info[idx] = (struct field_modify_info){1, 0, MLX5_MODI_OUT_IPV6_HOPLIMIT}; - if (mask) { - mask[idx] = 0x000000ff; - if (width < 8) - mask[idx] = (mask[idx] << (8 - width)) & - 0x000000ff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x000000ff >> + (8 - width)); break; case RTE_FLOW_FIELD_IPV6_SRC: if (mask) { if (data->offset < 32) { info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_SIPV6_127_96}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1501,11 +1481,13 @@ mlx5_flow_field_id_to_modify_info info[idx] = (struct field_modify_info){4, 4 * idx, MLX5_MODI_OUT_SIPV6_95_64}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1516,11 +1498,13 @@ mlx5_flow_field_id_to_modify_info info[idx] = (struct field_modify_info){4, 8 * idx, MLX5_MODI_OUT_SIPV6_63_32}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1529,9 +1513,8 @@ mlx5_flow_field_id_to_modify_info } info[idx] = (struct field_modify_info){4, 12 * idx, MLX5_MODI_OUT_SIPV6_31_0}; - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); + mask[idx] = rte_cpu_to_be_32(0xffffffff >> + (32 - width)); } else { if (data->offset < 32) info[idx++] = (struct field_modify_info){4, 0, @@ -1552,11 +1535,13 @@ mlx5_flow_field_id_to_modify_info if (data->offset < 32) { info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_DIPV6_127_96}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1567,11 +1552,13 @@ mlx5_flow_field_id_to_modify_info info[idx] = (struct field_modify_info){4, 4 * idx, MLX5_MODI_OUT_DIPV6_95_64}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1582,11 +1569,13 @@ mlx5_flow_field_id_to_modify_info info[idx] = (struct field_modify_info){4, 8 * idx, MLX5_MODI_OUT_DIPV6_63_32}; - mask[idx] = 0xffffffff; if (width < 32) { - mask[idx] = mask[idx] << (32 - width); + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); width = 0; } else { + mask[idx] = RTE_BE32(0xffffffff); width -= 32; } if (!width) @@ -1595,9 +1584,8 @@ mlx5_flow_field_id_to_modify_info } info[idx] = (struct field_modify_info){4, 12 * idx, MLX5_MODI_OUT_DIPV6_31_0}; - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); + mask[idx] = rte_cpu_to_be_32(0xffffffff >> + (32 - width)); } else { if (data->offset < 32) info[idx++] = (struct field_modify_info){4, 0, @@ -1616,70 +1604,51 @@ mlx5_flow_field_id_to_modify_info case RTE_FLOW_FIELD_TCP_PORT_SRC: info[idx] = (struct field_modify_info){2, 0, MLX5_MODI_OUT_TCP_SPORT}; - if (mask) { - mask[idx] = 0x0000ffff; - if (width < 16) - mask[idx] = (mask[idx] << (16 - width)) & - 0x0000ffff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000ffff >> + (16 - width)); break; case RTE_FLOW_FIELD_TCP_PORT_DST: info[idx] = (struct field_modify_info){2, 0, MLX5_MODI_OUT_TCP_DPORT}; - if (mask) { - mask[idx] = 0x0000ffff; - if (width < 16) - mask[idx] = (mask[idx] << (16 - width)) & - 0x0000ffff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000ffff >> + (16 - width)); break; case RTE_FLOW_FIELD_TCP_SEQ_NUM: info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_TCP_SEQ_NUM}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = (mask[idx] << (32 - width)); - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0xffffffff >> + (32 - width)); break; case RTE_FLOW_FIELD_TCP_ACK_NUM: info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_OUT_TCP_ACK_NUM}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = (mask[idx] << (32 - width)); - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0xffffffff >> + (32 - width)); break; case RTE_FLOW_FIELD_TCP_FLAGS: info[idx] = (struct field_modify_info){1, 0, - MLX5_MODI_IN_TCP_FLAGS}; - if (mask) { - mask[idx] = 0x0000003f; - if (width < 6) - mask[idx] = (mask[idx] << (6 - width)) & - 0x0000003f; - } + MLX5_MODI_OUT_TCP_FLAGS}; + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000003f >> + (6 - width)); break; case RTE_FLOW_FIELD_UDP_PORT_SRC: info[idx] = (struct field_modify_info){2, 0, MLX5_MODI_OUT_UDP_SPORT}; - if (mask) { - mask[idx] = 0x0000ffff; - if (width < 16) - mask[idx] = (mask[idx] << (16 - width)) & - 0x0000ffff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000ffff >> + (16 - width)); break; case RTE_FLOW_FIELD_UDP_PORT_DST: info[idx] = (struct field_modify_info){2, 0, MLX5_MODI_OUT_UDP_DPORT}; - if (mask) { - mask[idx] = 0x0000ffff; - if (width < 16) - mask[idx] = (mask[idx] << (16 - width)) & - 0x0000ffff; - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0x0000ffff >> + (16 - width)); break; case RTE_FLOW_FIELD_VXLAN_VNI: /* not supported yet */ @@ -1690,11 +1659,9 @@ mlx5_flow_field_id_to_modify_info case RTE_FLOW_FIELD_GTP_TEID: info[idx] = (struct field_modify_info){4, 0, MLX5_MODI_GTP_TEID}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); - } + if (mask) + mask[idx] = rte_cpu_to_be_32(0xffffffff >> + (32 - width)); break; case RTE_FLOW_FIELD_TAG: { @@ -1706,11 +1673,10 @@ mlx5_flow_field_id_to_modify_info MLX5_ASSERT((unsigned int)reg < RTE_DIM(reg_to_field)); info[idx] = (struct field_modify_info){4, 0, reg_to_field[reg]}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); - } + if (mask) + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); } break; case RTE_FLOW_FIELD_MARK: @@ -1723,11 +1689,10 @@ mlx5_flow_field_id_to_modify_info MLX5_ASSERT((unsigned int)reg < RTE_DIM(reg_to_field)); info[idx] = (struct field_modify_info){4, 0, reg_to_field[reg]}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); - } + if (mask) + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); } break; case RTE_FLOW_FIELD_META: @@ -1739,11 +1704,10 @@ mlx5_flow_field_id_to_modify_info MLX5_ASSERT((unsigned int)reg < RTE_DIM(reg_to_field)); info[idx] = (struct field_modify_info){4, 0, reg_to_field[reg]}; - if (mask) { - mask[idx] = 0xffffffff; - if (width < 32) - mask[idx] = mask[idx] << (32 - width); - } + if (mask) + mask[idx] = + rte_cpu_to_be_32(0xffffffff >> + (32 - width)); } break; case RTE_FLOW_FIELD_POINTER: @@ -1751,7 +1715,7 @@ mlx5_flow_field_id_to_modify_info if (mask[idx]) { memcpy(&value[idx], (void *)(uintptr_t)data->value, 32); - value[idx] = RTE_BE32(value[idx]); + value[idx] = rte_cpu_to_be_32(value[idx]); break; } } @@ -1759,7 +1723,8 @@ mlx5_flow_field_id_to_modify_info case RTE_FLOW_FIELD_VALUE: for (idx = 0; idx < MLX5_ACT_MAX_MOD_FIELDS; idx++) { if (mask[idx]) { - value[idx] = RTE_BE32((uint32_t)data->value); + value[idx] = + rte_cpu_to_be_32((uint32_t)data->value); break; } } @@ -1960,13 +1925,20 @@ flow_dv_validate_item_meta(struct rte_eth_dev *dev __rte_unused, "isn't supported"); if (reg != REG_A) nic_mask.data = priv->sh->dv_meta_mask; - } else if (attr->transfer) { - return rte_flow_error_set(error, ENOTSUP, + } else { + if (attr->transfer) + return rte_flow_error_set(error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, item, "extended metadata feature " "should be enabled when " "meta item is requested " "with e-switch mode "); + if (attr->ingress) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "match on metadata for ingress " + "is not supported in legacy " + "metadata mode"); } if (!mask) mask = &rte_flow_item_meta_mask; @@ -3605,6 +3577,7 @@ flow_dv_port_id_create_cb(struct mlx5_cache_list *list, "cannot create action"); return NULL; } + cache->idx = idx; return &cache->entry; } @@ -3696,6 +3669,7 @@ flow_dv_push_vlan_create_cb(struct mlx5_cache_list *list, "cannot create push vlan action"); return NULL; } + cache->idx = idx; return &cache->entry; } @@ -4568,13 +4542,14 @@ mlx5_flow_item_field_width(enum rte_flow_field_id field) /** * Validate the generic modify field actions. - * + * @param[in] dev + * Pointer to the rte_eth_dev structure. * @param[in] action_flags * Holds the actions detected until now. * @param[in] action * Pointer to the modify action. - * @param[in] item_flags - * Holds the items detected. + * @param[in] attr + * Pointer to the flow attributes. * @param[out] error * Pointer to error structure. * @@ -4583,11 +4558,15 @@ mlx5_flow_item_field_width(enum rte_flow_field_id field) * a negative errno value otherwise and rte_errno is set. */ static int -flow_dv_validate_action_modify_field(const uint64_t action_flags, +flow_dv_validate_action_modify_field(struct rte_eth_dev *dev, + const uint64_t action_flags, const struct rte_flow_action *action, + const struct rte_flow_attr *attr, struct rte_flow_error *error) { int ret = 0; + struct mlx5_priv *priv = dev->data->dev_private; + struct mlx5_dev_config *config = &priv->config; const struct rte_flow_action_modify_field *action_modify_field = action->conf; uint32_t dst_width = @@ -4599,9 +4578,22 @@ flow_dv_validate_action_modify_field(const uint64_t action_flags, if (ret) return ret; + if (action_modify_field->width == 0) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "no bits are requested to be modified"); + else if (action_modify_field->width > dst_width || + action_modify_field->width > src_width) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "cannot modify more bits than" + " the width of a field"); if (action_modify_field->dst.field != RTE_FLOW_FIELD_VALUE && action_modify_field->dst.field != RTE_FLOW_FIELD_POINTER) { - if (action_modify_field->dst.offset >= dst_width || + if ((action_modify_field->dst.offset + + action_modify_field->width > dst_width) || (action_modify_field->dst.offset % 32)) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, @@ -4617,7 +4609,13 @@ flow_dv_validate_action_modify_field(const uint64_t action_flags, } if (action_modify_field->src.field != RTE_FLOW_FIELD_VALUE && action_modify_field->src.field != RTE_FLOW_FIELD_POINTER) { - if (action_modify_field->src.offset >= src_width || + if (!attr->transfer && !attr->group) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, "modify field action " + "is not supported for group 0"); + if ((action_modify_field->src.offset + + action_modify_field->width > src_width) || (action_modify_field->src.offset % 32)) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, @@ -4631,11 +4629,6 @@ flow_dv_validate_action_modify_field(const uint64_t action_flags, NULL, "cannot copy from inner headers"); } - if (action_modify_field->width == 0) - return rte_flow_error_set(error, EINVAL, - RTE_FLOW_ERROR_TYPE_ACTION, - NULL, - "width is required for modify action"); if (action_modify_field->dst.field == action_modify_field->src.field) return rte_flow_error_set(error, EINVAL, @@ -4657,6 +4650,36 @@ flow_dv_validate_action_modify_field(const uint64_t action_flags, NULL, "modifications of an arbitrary" " place in a packet is not supported"); + if (action_modify_field->dst.field == RTE_FLOW_FIELD_VLAN_TYPE || + action_modify_field->src.field == RTE_FLOW_FIELD_VLAN_TYPE) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "modifications of the 802.1Q Tag" + " Identifier is not supported"); + if (action_modify_field->dst.field == RTE_FLOW_FIELD_VXLAN_VNI || + action_modify_field->src.field == RTE_FLOW_FIELD_VXLAN_VNI) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "modifications of the VXLAN Network" + " Identifier is not supported"); + if (action_modify_field->dst.field == RTE_FLOW_FIELD_GENEVE_VNI || + action_modify_field->src.field == RTE_FLOW_FIELD_GENEVE_VNI) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + NULL, + "modifications of the GENEVE Network" + " Identifier is not supported"); + if (action_modify_field->dst.field == RTE_FLOW_FIELD_MARK || + action_modify_field->src.field == RTE_FLOW_FIELD_MARK) { + if (config->dv_xmeta_en == MLX5_XMETA_MODE_LEGACY || + !mlx5_flow_ext_mreg_supported(dev)) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ACTION, action, + "cannot modify mark without extended" + " metadata register support"); + } if (action_modify_field->operation != RTE_FLOW_MODIFY_SET) return rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, @@ -6926,14 +6949,11 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, action_flags |= MLX5_FLOW_ACTION_TUNNEL_SET; break; case RTE_FLOW_ACTION_TYPE_MODIFY_FIELD: - if (!attr->transfer && !attr->group) - return rte_flow_error_set(error, ENOTSUP, - RTE_FLOW_ERROR_TYPE_ACTION, - NULL, "modify field action " - "is not supported for group 0"); - ret = flow_dv_validate_action_modify_field(action_flags, - actions, - error); + ret = flow_dv_validate_action_modify_field(dev, + action_flags, + actions, + attr, + error); if (ret < 0) return ret; /* Count all modify-header actions as one action. */