* Copy a list of pattern items. * * @param[out] dst * Destination buffer. Can be NULL if @p size is zero. * @param size * Size of @p dst in bytes. * @param[in] src * Source pattern items. * @param num * Maximum number of pattern items to process from @p src or 0 to process * the entire list. In both cases, processing stops after * RTE_FLOW_ITEM_TYPE_END is encountered. * @p
| 819 | * otherwise and rte_errno is set. |
| 820 | */ |
| 821 | static int |
| 822 | rte_flow_conv_pattern(struct rte_flow_item *dst, |
| 823 | const size_t size, |
| 824 | const struct rte_flow_item *src, |
| 825 | unsigned int num, |
| 826 | struct rte_flow_error *error) |
| 827 | { |
| 828 | uintptr_t data = (uintptr_t)dst; |
| 829 | size_t off; |
| 830 | size_t ret; |
| 831 | unsigned int i; |
| 832 | |
| 833 | for (i = 0, off = 0; !num || i != num; ++i, ++src, ++dst) { |
| 834 | /** |
| 835 | * allow PMD private flow item |
| 836 | */ |
| 837 | if (((int)src->type >= 0) && |
| 838 | ((size_t)src->type >= RTE_DIM(rte_flow_desc_item) || |
| 839 | !rte_flow_desc_item[src->type].name)) |
| 840 | return rte_flow_error_set |
| 841 | (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ITEM, src, |
| 842 | "cannot convert unknown item type"); |
| 843 | if (size >= off + sizeof(*dst)) |
| 844 | *dst = (struct rte_flow_item){ |
| 845 | .type = src->type, |
| 846 | }; |
| 847 | off += sizeof(*dst); |
| 848 | if (!src->type) |
| 849 | num = i + 1; |
| 850 | } |
| 851 | num = i; |
| 852 | src -= num; |
| 853 | dst -= num; |
| 854 | do { |
| 855 | if (src->spec) { |
| 856 | off = RTE_ALIGN_CEIL(off, sizeof(double)); |
| 857 | ret = rte_flow_conv_item_spec |
| 858 | ((void *)(data + off), |
| 859 | size > off ? size - off : 0, src, |
| 860 | RTE_FLOW_CONV_ITEM_SPEC); |
| 861 | if (size && size >= off + ret) |
| 862 | dst->spec = (void *)(data + off); |
| 863 | off += ret; |
| 864 | |
| 865 | } |
| 866 | if (src->last) { |
| 867 | off = RTE_ALIGN_CEIL(off, sizeof(double)); |
| 868 | ret = rte_flow_conv_item_spec |
| 869 | ((void *)(data + off), |
| 870 | size > off ? size - off : 0, src, |
| 871 | RTE_FLOW_CONV_ITEM_LAST); |
| 872 | if (size && size >= off + ret) |
| 873 | dst->last = (void *)(data + off); |
| 874 | off += ret; |
| 875 | } |
| 876 | if (src->mask) { |
| 877 | off = RTE_ALIGN_CEIL(off, sizeof(double)); |
| 878 | ret = rte_flow_conv_item_spec |
no test coverage detected