* Validate VXLAN item. * * @param[in] dev * Pointer to the Ethernet device structure. * @param[in] udp_dport * UDP destination port * @param[in] item * Item specification. * @param[in] item_flags * Bit-fields that holds the items detected until now. * @param root * Whether action is on root table. * @param[out] error * Pointer to error structure. * * @return * 0 on su
| 3193 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 3194 | */ |
| 3195 | int |
| 3196 | mlx5_flow_validate_item_vxlan(struct rte_eth_dev *dev, |
| 3197 | uint16_t udp_dport, |
| 3198 | const struct rte_flow_item *item, |
| 3199 | uint64_t item_flags, |
| 3200 | bool root, |
| 3201 | struct rte_flow_error *error) |
| 3202 | { |
| 3203 | const struct rte_flow_item_vxlan *spec = item->spec; |
| 3204 | const struct rte_flow_item_vxlan *mask = item->mask; |
| 3205 | int ret; |
| 3206 | struct mlx5_priv *priv = dev->data->dev_private; |
| 3207 | union vni { |
| 3208 | uint32_t vlan_id; |
| 3209 | uint8_t vni[4]; |
| 3210 | } id = { .vlan_id = 0, }; |
| 3211 | const struct rte_flow_item_vxlan nic_mask = { |
| 3212 | .hdr.vni = "\xff\xff\xff", |
| 3213 | .hdr.rsvd1 = 0xff, |
| 3214 | }; |
| 3215 | const struct rte_flow_item_vxlan *valid_mask; |
| 3216 | |
| 3217 | if (item_flags & MLX5_FLOW_LAYER_TUNNEL) |
| 3218 | return rte_flow_error_set(error, ENOTSUP, |
| 3219 | RTE_FLOW_ERROR_TYPE_ITEM, item, |
| 3220 | "multiple tunnel layers not" |
| 3221 | " supported"); |
| 3222 | valid_mask = &rte_flow_item_vxlan_mask; |
| 3223 | /* |
| 3224 | * Verify only UDPv4 is present as defined in |
| 3225 | * https://tools.ietf.org/html/rfc7348 |
| 3226 | */ |
| 3227 | if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_UDP)) |
| 3228 | return rte_flow_error_set(error, EINVAL, |
| 3229 | RTE_FLOW_ERROR_TYPE_ITEM, item, |
| 3230 | "no outer UDP layer found"); |
| 3231 | if (!mask) |
| 3232 | mask = &rte_flow_item_vxlan_mask; |
| 3233 | |
| 3234 | if (priv->sh->steering_format_version != |
| 3235 | MLX5_STEERING_LOGIC_FORMAT_CONNECTX_5 || |
| 3236 | !udp_dport || udp_dport == MLX5_UDP_PORT_VXLAN) { |
| 3237 | /* non-root table */ |
| 3238 | if (!root && priv->sh->misc5_cap) |
| 3239 | valid_mask = &nic_mask; |
| 3240 | /* Group zero in NIC domain */ |
| 3241 | if (!root && priv->sh->tunnel_header_0_1) |
| 3242 | valid_mask = &nic_mask; |
| 3243 | } |
| 3244 | ret = mlx5_flow_item_acceptable |
| 3245 | (item, (const uint8_t *)mask, |
| 3246 | (const uint8_t *)valid_mask, |
| 3247 | sizeof(struct rte_flow_item_vxlan), |
| 3248 | MLX5_ITEM_RANGE_NOT_ACCEPTED, error); |
| 3249 | if (ret < 0) |
| 3250 | return ret; |
| 3251 | if (spec) { |
| 3252 | memcpy(&id.vni[1], spec->hdr.vni, 3); |
no test coverage detected