- return -1;
- if (item->spec && !item->mask) {
- unsigned int i;
- const uint8_t *spec = item->spec;
-
- for (i = 0; i < size; ++i)
- if ((spec[i] | mask[i]) != mask[i])
- return -1;
- }
- if (item->last && !item->mask) {
- unsigned int i;
- const uint8_t *spec = item->last;
-
- for (i = 0; i < size; ++i)
- if ((spec[i] | mask[i]) != mask[i])
- return -1;
- }
- if (item->spec && item->last) {
- uint8_t spec[size];
- uint8_t last[size];
- const uint8_t *apply = mask;
- unsigned int i;
-
- if (item->mask)
- apply = item->mask;
- for (i = 0; i < size; ++i) {
- spec[i] = ((const uint8_t *)item->spec)[i] & apply[i];
- last[i] = ((const uint8_t *)item->last)[i] & apply[i];
- }
- ret = memcmp(spec, last, size);
- }
- return ret;
-}
-
-static int
-mlx4_flow_validate_eth(const struct rte_flow_item *item,
- const uint8_t *mask, unsigned int size)
-{
- if (item->mask) {
- const struct rte_flow_item_eth *mask = item->mask;
-
- if (mask->dst.addr_bytes[0] != 0xff ||
- mask->dst.addr_bytes[1] != 0xff ||
- mask->dst.addr_bytes[2] != 0xff ||
- mask->dst.addr_bytes[3] != 0xff ||
- mask->dst.addr_bytes[4] != 0xff ||
- mask->dst.addr_bytes[5] != 0xff)
- return -1;
- }
- return mlx4_flow_item_validate(item, mask, size);
-}
-
-static int
-mlx4_flow_validate_vlan(const struct rte_flow_item *item,
- const uint8_t *mask, unsigned int size)
-{
- if (item->mask) {
- const struct rte_flow_item_vlan *mask = item->mask;
-
- if (mask->tci != 0 &&
- ntohs(mask->tci) != 0x0fff)
- return -1;
- }
- return mlx4_flow_item_validate(item, mask, size);
-}
-
-static int
-mlx4_flow_validate_ipv4(const struct rte_flow_item *item,
- const uint8_t *mask, unsigned int size)
-{
- if (item->mask) {
- const struct rte_flow_item_ipv4 *mask = item->mask;
-
- if (mask->hdr.src_addr != 0 &&
- mask->hdr.src_addr != 0xffffffff)
- return -1;
- if (mask->hdr.dst_addr != 0 &&
- mask->hdr.dst_addr != 0xffffffff)
- return -1;
- }
- return mlx4_flow_item_validate(item, mask, size);
-}
-
-static int
-mlx4_flow_validate_udp(const struct rte_flow_item *item,
- const uint8_t *mask, unsigned int size)
-{
- if (item->mask) {
- const struct rte_flow_item_udp *mask = item->mask;
-
- if (mask->hdr.src_port != 0 &&
- mask->hdr.src_port != 0xffff)
- return -1;
- if (mask->hdr.dst_port != 0 &&
- mask->hdr.dst_port != 0xffff)
- return -1;
- }
- return mlx4_flow_item_validate(item, mask, size);
-}
-
-static int
-mlx4_flow_validate_tcp(const struct rte_flow_item *item,
- const uint8_t *mask, unsigned int size)
-{
- if (item->mask) {
- const struct rte_flow_item_tcp *mask = item->mask;
-
- if (mask->hdr.src_port != 0 &&
- mask->hdr.src_port != 0xffff)
- return -1;
- if (mask->hdr.dst_port != 0 &&
- mask->hdr.dst_port != 0xffff)
- return -1;
+ return rte_flow_error_set
+ (error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item,
+ "\"mask\" or \"last\" field provided without a"
+ " corresponding \"spec\"");
+ /* No spec, no mask, no problem. */
+ if (!item->spec)
+ return 0;
+ mask = item->mask ?
+ (const uint8_t *)item->mask :
+ (const uint8_t *)proc->mask_default;
+ MLX4_ASSERT(mask);
+ /*
+ * Single-pass check to make sure that:
+ * - Mask is supported, no bits are set outside proc->mask_support.
+ * - Both item->spec and item->last are included in mask.
+ */
+ for (i = 0; i != proc->mask_sz; ++i) {
+ if (!mask[i])
+ continue;
+ if ((mask[i] | ((const uint8_t *)proc->mask_support)[i]) !=
+ ((const uint8_t *)proc->mask_support)[i])
+ return rte_flow_error_set
+ (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
+ item, "unsupported field found in \"mask\"");
+ if (item->last &&
+ (((const uint8_t *)item->spec)[i] & mask[i]) !=
+ (((const uint8_t *)item->last)[i] & mask[i]))
+ return rte_flow_error_set
+ (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "range between \"spec\" and \"last\""
+ " is larger than \"mask\"");