* Check support for a given item. * * @param[in] item * Item specification. * @param size * Bit-Mask size in bytes. * @param[in] supported_mask * Bit-mask covering supported fields to compare with spec, last and mask in * \item. * @param[in] default_mask * Bit-mask default mask if none is provided in \item. * * @return * 0 on success. */
| 837 | * 0 on success. |
| 838 | */ |
| 839 | static int |
| 840 | tap_flow_item_validate(const struct rte_flow_item *item, |
| 841 | unsigned int size, |
| 842 | const uint8_t *supported_mask, |
| 843 | const uint8_t *default_mask) |
| 844 | { |
| 845 | int ret = 0; |
| 846 | |
| 847 | /* An empty layer is allowed, as long as all fields are NULL */ |
| 848 | if (!item->spec && (item->mask || item->last)) |
| 849 | return -1; |
| 850 | /* Is the item spec compatible with what the NIC supports? */ |
| 851 | if (item->spec && !item->mask) { |
| 852 | unsigned int i; |
| 853 | const uint8_t *spec = item->spec; |
| 854 | |
| 855 | for (i = 0; i < size; ++i) |
| 856 | if ((spec[i] | supported_mask[i]) != supported_mask[i]) |
| 857 | return -1; |
| 858 | /* Is the default mask compatible with what the NIC supports? */ |
| 859 | for (i = 0; i < size; i++) |
| 860 | if ((default_mask[i] | supported_mask[i]) != |
| 861 | supported_mask[i]) |
| 862 | return -1; |
| 863 | } |
| 864 | /* Is the item last compatible with what the NIC supports? */ |
| 865 | if (item->last && !item->mask) { |
| 866 | unsigned int i; |
| 867 | const uint8_t *spec = item->last; |
| 868 | |
| 869 | for (i = 0; i < size; ++i) |
| 870 | if ((spec[i] | supported_mask[i]) != supported_mask[i]) |
| 871 | return -1; |
| 872 | } |
| 873 | /* Is the item mask compatible with what the NIC supports? */ |
| 874 | if (item->mask) { |
| 875 | unsigned int i; |
| 876 | const uint8_t *spec = item->mask; |
| 877 | |
| 878 | for (i = 0; i < size; ++i) |
| 879 | if ((spec[i] | supported_mask[i]) != supported_mask[i]) |
| 880 | return -1; |
| 881 | } |
| 882 | /** |
| 883 | * Once masked, Are item spec and item last equal? |
| 884 | * TC does not support range so anything else is invalid. |
| 885 | */ |
| 886 | if (item->spec && item->last) { |
| 887 | uint8_t spec[size]; |
| 888 | uint8_t last[size]; |
| 889 | const uint8_t *apply = default_mask; |
| 890 | unsigned int i; |
| 891 | |
| 892 | if (item->mask) |
| 893 | apply = item->mask; |
| 894 | for (i = 0; i < size; ++i) { |
| 895 | spec[i] = ((const uint8_t *)item->spec)[i] & apply[i]; |
| 896 | last[i] = ((const uint8_t *)item->last)[i] & apply[i]; |