* Copy action configuration. * * @param[out] buf * Output buffer. Can be NULL if @p size is zero. * @param size * Size of @p buf in bytes. * @param[in] action * Action to copy configuration from. * * @return * Number of bytes needed to store pattern item specification regardless * of @p size. @p buf contents are truncated to @p size if not large * enough. */
| 709 | * enough. |
| 710 | */ |
| 711 | static size_t |
| 712 | rte_flow_conv_action_conf(void *buf, const size_t size, |
| 713 | const struct rte_flow_action *action) |
| 714 | { |
| 715 | size_t off; |
| 716 | |
| 717 | switch (action->type) { |
| 718 | union { |
| 719 | const struct rte_flow_action_rss *rss; |
| 720 | const struct rte_flow_action_vxlan_encap *vxlan_encap; |
| 721 | const struct rte_flow_action_nvgre_encap *nvgre_encap; |
| 722 | } src; |
| 723 | union { |
| 724 | struct rte_flow_action_rss *rss; |
| 725 | struct rte_flow_action_vxlan_encap *vxlan_encap; |
| 726 | struct rte_flow_action_nvgre_encap *nvgre_encap; |
| 727 | } dst; |
| 728 | size_t tmp; |
| 729 | int ret; |
| 730 | |
| 731 | case RTE_FLOW_ACTION_TYPE_RSS: |
| 732 | src.rss = action->conf; |
| 733 | dst.rss = buf; |
| 734 | rte_memcpy(dst.rss, |
| 735 | (&(struct rte_flow_action_rss){ |
| 736 | .func = src.rss->func, |
| 737 | .level = src.rss->level, |
| 738 | .types = src.rss->types, |
| 739 | .key_len = src.rss->key_len, |
| 740 | .queue_num = src.rss->queue_num, |
| 741 | }), |
| 742 | size > sizeof(*dst.rss) ? sizeof(*dst.rss) : size); |
| 743 | off = sizeof(*dst.rss); |
| 744 | if (src.rss->key_len && src.rss->key) { |
| 745 | off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->key)); |
| 746 | tmp = sizeof(*src.rss->key) * src.rss->key_len; |
| 747 | if (size >= (uint64_t)off + (uint64_t)tmp) |
| 748 | dst.rss->key = rte_memcpy |
| 749 | ((void *)((uintptr_t)dst.rss + off), |
| 750 | src.rss->key, tmp); |
| 751 | off += tmp; |
| 752 | } |
| 753 | if (src.rss->queue_num) { |
| 754 | off = RTE_ALIGN_CEIL(off, sizeof(*dst.rss->queue)); |
| 755 | tmp = sizeof(*src.rss->queue) * src.rss->queue_num; |
| 756 | if (size >= (uint64_t)off + (uint64_t)tmp) |
| 757 | dst.rss->queue = rte_memcpy |
| 758 | ((void *)((uintptr_t)dst.rss + off), |
| 759 | src.rss->queue, tmp); |
| 760 | off += tmp; |
| 761 | } |
| 762 | break; |
| 763 | case RTE_FLOW_ACTION_TYPE_VXLAN_ENCAP: |
| 764 | case RTE_FLOW_ACTION_TYPE_NVGRE_ENCAP: |
| 765 | src.vxlan_encap = action->conf; |
| 766 | dst.vxlan_encap = buf; |
| 767 | RTE_BUILD_BUG_ON(sizeof(*src.vxlan_encap) != |
| 768 | sizeof(*src.nvgre_encap) || |
no test coverage detected