* Pointer to Ethernet device.
* @param[in] flow
* Parent flow structure pointer.
+ * @param[in] prefix_layers
+ * Prefix flow layer flags.
* @param[in] attr
* Flow rule attributes.
* @param[in] items
static int
flow_create_split_metadata(struct rte_eth_dev *dev,
struct rte_flow *flow,
+ uint64_t prefix_layers,
const struct rte_flow_attr *attr,
const struct rte_flow_item items[],
const struct rte_flow_action actions[],
if (!config->dv_flow_en ||
config->dv_xmeta_en == MLX5_XMETA_MODE_LEGACY ||
!mlx5_flow_ext_mreg_supported(dev))
- return flow_create_split_inner(dev, flow, NULL, 0,
+ return flow_create_split_inner(dev, flow, NULL, prefix_layers,
attr, items, actions, external,
error);
actions_n = flow_parse_qrss_action(actions, &qrss);
goto exit;
}
/* Add the unmodified original or prefix subflow. */
- ret = flow_create_split_inner(dev, flow, &dev_flow, 0, attr,
+ ret = flow_create_split_inner(dev, flow, &dev_flow, prefix_layers, attr,
items, ext_actions ? ext_actions :
actions, external, error);
if (ret < 0)
MLX5_FLOW_TABLE_LEVEL_SUFFIX;
}
/* Add the prefix subflow. */
- ret = flow_create_split_metadata(dev, flow, &sfx_attr,
+ ret = flow_create_split_metadata(dev, flow, dev_flow ?
+ flow_get_prefix_layer_flags(dev_flow) :
+ 0, &sfx_attr,
sfx_items ? sfx_items : items,
sfx_actions ? sfx_actions : actions,
external, error);
* Pointer to item specification.
* @param[out] attr
* Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ * Pointer to the sub flow.
* @param[in] tunnel_decap
* Whether action is after tunnel decapsulation.
*/
static void
flow_dv_attr_init(const struct rte_flow_item *item, union flow_dv_attr *attr,
- bool tunnel_decap)
+ struct mlx5_flow *dev_flow, bool tunnel_decap)
{
+ /*
+ * If layers is already initialized, it means this dev_flow is the
+ * suffix flow, the layers flags is set by the prefix flow. Need to
+ * use the layer flags from prefix flow as the suffix flow may not
+ * have the user defined items as the flow is split.
+ */
+ if (dev_flow->layers) {
+ if (dev_flow->layers & MLX5_FLOW_LAYER_OUTER_L3_IPV4)
+ attr->ipv4 = 1;
+ else if (dev_flow->layers & MLX5_FLOW_LAYER_OUTER_L3_IPV6)
+ attr->ipv6 = 1;
+ if (dev_flow->layers & MLX5_FLOW_LAYER_OUTER_L4_TCP)
+ attr->tcp = 1;
+ else if (dev_flow->layers & MLX5_FLOW_LAYER_OUTER_L4_UDP)
+ attr->udp = 1;
+ attr->valid = 1;
+ return;
+ }
for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) {
uint8_t next_protocol = 0xff;
-
switch (item->type) {
case RTE_FLOW_ITEM_TYPE_GRE:
case RTE_FLOW_ITEM_TYPE_NVGRE:
* Pointer to rte_flow_item objects list.
* @param[in] attr
* Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ * Pointer to the sub flow.
* @param[in] tunnel_decap
* Whether action is after tunnel decapsulation.
* @param[out] error
(struct mlx5_flow_dv_modify_hdr_resource *resource,
const struct rte_flow_action *action,
const struct rte_flow_item *items,
- union flow_dv_attr *attr, bool tunnel_decap,
- struct rte_flow_error *error)
+ union flow_dv_attr *attr, struct mlx5_flow *dev_flow,
+ bool tunnel_decap, struct rte_flow_error *error)
{
const struct rte_flow_action_set_tp *conf =
(const struct rte_flow_action_set_tp *)(action->conf);
struct field_modify_info *field;
if (!attr->valid)
- flow_dv_attr_init(items, attr, tunnel_decap);
+ flow_dv_attr_init(items, attr, dev_flow, tunnel_decap);
if (attr->udp) {
memset(&udp, 0, sizeof(udp));
memset(&udp_mask, 0, sizeof(udp_mask));
* Pointer to rte_flow_item objects list.
* @param[in] attr
* Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ * Pointer to the sub flow.
* @param[in] tunnel_decap
* Whether action is after tunnel decapsulation.
* @param[out] error
(struct mlx5_flow_dv_modify_hdr_resource *resource,
const struct rte_flow_action *action,
const struct rte_flow_item *items,
- union flow_dv_attr *attr, bool tunnel_decap,
- struct rte_flow_error *error)
+ union flow_dv_attr *attr, struct mlx5_flow *dev_flow,
+ bool tunnel_decap, struct rte_flow_error *error)
{
const struct rte_flow_action_set_ttl *conf =
(const struct rte_flow_action_set_ttl *)(action->conf);
struct field_modify_info *field;
if (!attr->valid)
- flow_dv_attr_init(items, attr, tunnel_decap);
+ flow_dv_attr_init(items, attr, dev_flow, tunnel_decap);
if (attr->ipv4) {
memset(&ipv4, 0, sizeof(ipv4));
memset(&ipv4_mask, 0, sizeof(ipv4_mask));
* Pointer to rte_flow_item objects list.
* @param[in] attr
* Pointer to flow attributes structure.
+ * @param[in] dev_flow
+ * Pointer to the sub flow.
* @param[in] tunnel_decap
* Whether action is after tunnel decapsulation.
* @param[out] error
flow_dv_convert_action_modify_dec_ttl
(struct mlx5_flow_dv_modify_hdr_resource *resource,
const struct rte_flow_item *items,
- union flow_dv_attr *attr, bool tunnel_decap,
- struct rte_flow_error *error)
+ union flow_dv_attr *attr, struct mlx5_flow *dev_flow,
+ bool tunnel_decap, struct rte_flow_error *error)
{
struct rte_flow_item item;
struct rte_flow_item_ipv4 ipv4;
struct field_modify_info *field;
if (!attr->valid)
- flow_dv_attr_init(items, attr, tunnel_decap);
+ flow_dv_attr_init(items, attr, dev_flow, tunnel_decap);
if (attr->ipv4) {
memset(&ipv4, 0, sizeof(ipv4));
memset(&ipv4_mask, 0, sizeof(ipv4_mask));
case RTE_FLOW_ACTION_TYPE_SET_TP_DST:
if (flow_dv_convert_action_modify_tp
(mhdr_res, actions, items,
- &flow_attr, !!(action_flags &
+ &flow_attr, dev_flow, !!(action_flags &
MLX5_FLOW_ACTION_DECAP), error))
return -rte_errno;
action_flags |= actions->type ==
break;
case RTE_FLOW_ACTION_TYPE_DEC_TTL:
if (flow_dv_convert_action_modify_dec_ttl
- (mhdr_res, items, &flow_attr,
+ (mhdr_res, items, &flow_attr, dev_flow,
!!(action_flags &
MLX5_FLOW_ACTION_DECAP), error))
return -rte_errno;
case RTE_FLOW_ACTION_TYPE_SET_TTL:
if (flow_dv_convert_action_modify_ttl
(mhdr_res, actions, items, &flow_attr,
- !!(action_flags &
+ dev_flow, !!(action_flags &
MLX5_FLOW_ACTION_DECAP), error))
return -rte_errno;
action_flags |= MLX5_FLOW_ACTION_SET_TTL;