* Validate VLAN item. * * @param[in] item * Item specification. * @param[in] item_flags * Bit-fields that holds the items detected until now. * @param[in] dev * Ethernet device flow is being created on. * @param[out] error * Pointer to error structure. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */
| 2775 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 2776 | */ |
| 2777 | int |
| 2778 | mlx5_flow_validate_item_vlan(const struct rte_flow_item *item, |
| 2779 | uint64_t item_flags, |
| 2780 | struct rte_eth_dev *dev, |
| 2781 | struct rte_flow_error *error) |
| 2782 | { |
| 2783 | const struct rte_flow_item_vlan *spec = item->spec; |
| 2784 | const struct rte_flow_item_vlan *mask = item->mask; |
| 2785 | const struct rte_flow_item_vlan nic_mask = { |
| 2786 | .hdr.vlan_tci = RTE_BE16(UINT16_MAX), |
| 2787 | .hdr.eth_proto = RTE_BE16(UINT16_MAX), |
| 2788 | }; |
| 2789 | uint16_t vlan_tag = 0; |
| 2790 | const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); |
| 2791 | int ret; |
| 2792 | const uint64_t l34m = tunnel ? (MLX5_FLOW_LAYER_INNER_L3 | |
| 2793 | MLX5_FLOW_LAYER_INNER_L4) : |
| 2794 | (MLX5_FLOW_LAYER_OUTER_L3 | |
| 2795 | MLX5_FLOW_LAYER_OUTER_L4); |
| 2796 | const uint64_t vlanm = tunnel ? MLX5_FLOW_LAYER_INNER_VLAN : |
| 2797 | MLX5_FLOW_LAYER_OUTER_VLAN; |
| 2798 | |
| 2799 | if (item_flags & vlanm) |
| 2800 | return rte_flow_error_set(error, EINVAL, |
| 2801 | RTE_FLOW_ERROR_TYPE_ITEM, item, |
| 2802 | "multiple VLAN layers not supported"); |
| 2803 | else if ((item_flags & l34m) != 0) |
| 2804 | return rte_flow_error_set(error, EINVAL, |
| 2805 | RTE_FLOW_ERROR_TYPE_ITEM, item, |
| 2806 | "VLAN cannot follow L3/L4 layer"); |
| 2807 | if (!mask) |
| 2808 | mask = &rte_flow_item_vlan_mask; |
| 2809 | ret = mlx5_flow_item_acceptable(item, (const uint8_t *)mask, |
| 2810 | (const uint8_t *)&nic_mask, |
| 2811 | sizeof(struct rte_flow_item_vlan), |
| 2812 | MLX5_ITEM_RANGE_NOT_ACCEPTED, error); |
| 2813 | if (ret) |
| 2814 | return ret; |
| 2815 | if (!tunnel && mask->hdr.vlan_tci != RTE_BE16(0x0fff)) { |
| 2816 | struct mlx5_priv *priv = dev->data->dev_private; |
| 2817 | |
| 2818 | if (priv->vmwa_context) { |
| 2819 | /* |
| 2820 | * Non-NULL context means we have a virtual machine |
| 2821 | * and SR-IOV enabled, we have to create VLAN interface |
| 2822 | * to make hypervisor to setup E-Switch vport |
| 2823 | * context correctly. We avoid creating the multiple |
| 2824 | * VLAN interfaces, so we cannot support VLAN tag mask. |
| 2825 | */ |
| 2826 | return rte_flow_error_set(error, EINVAL, |
| 2827 | RTE_FLOW_ERROR_TYPE_ITEM, |
| 2828 | item, |
| 2829 | "VLAN tag mask is not" |
| 2830 | " supported in virtual" |
| 2831 | " environment"); |
| 2832 | } |
| 2833 | } |
| 2834 | if (spec) { |
no test coverage detected