+ if (!memcmp(ipv6_mask->hdr.src_addr, ipv6_addr_mask,
+ RTE_DIM(ipv6_mask->hdr.src_addr))) {
+ input_set |= IAVF_INSET_IPV6_SRC;
+ VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6,
+ SRC);
+ }
+ if (!memcmp(ipv6_mask->hdr.dst_addr, ipv6_addr_mask,
+ RTE_DIM(ipv6_mask->hdr.dst_addr))) {
+ input_set |= IAVF_INSET_IPV6_DST;
+ VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, IPV6,
+ DST);
+ }
+
+ if (tun_inner) {
+ input_set &= ~IAVF_PROT_IPV6_OUTER;
+ input_set |= IAVF_PROT_IPV6_INNER;
+ }
+
+ rte_memcpy(hdr->buffer, &ipv6_spec->hdr,
+ sizeof(ipv6_spec->hdr));
+
+ hdrs->count = ++layer;
+ break;
+
+ case RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT:
+ ipv6_frag_spec = item->spec;
+ ipv6_frag_last = item->last;
+ ipv6_frag_mask = item->mask;
+ next_type = (item + 1)->type;
+
+ hdr = &hdrs->proto_hdr[layer];
+
+ VIRTCHNL_SET_PROTO_HDR_TYPE(hdr, IPV6_EH_FRAG);
+
+ if (!(ipv6_frag_spec && ipv6_frag_mask)) {
+ hdrs->count = ++layer;
+ break;
+ }
+
+ /* only support any packet id for fragment IPv6
+ * any packet_id:
+ * spec is 0, last is 0xffffffff, mask is 0xffffffff
+ */
+ if (ipv6_frag_last && ipv6_frag_spec->hdr.id == 0 &&
+ ipv6_frag_last->hdr.id == UINT32_MAX &&
+ ipv6_frag_mask->hdr.id == UINT32_MAX &&
+ ipv6_frag_mask->hdr.frag_data == UINT16_MAX) {
+ /* all IPv6 fragment packet has the same
+ * ethertype, if the spec is for all valid
+ * packet id, set ethertype into input set.
+ */
+ input_set |= IAVF_INSET_ETHERTYPE;
+ VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1, ETH,
+ ETHERTYPE);
+
+ rte_memcpy(hdr->buffer, &ipv6_frag_spec->hdr,
+ sizeof(ipv6_frag_spec->hdr));
+ } else if (ipv6_frag_mask->hdr.id == UINT32_MAX) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item, "Invalid IPv6 mask.");
+ return -rte_errno;
+ }
+
+ hdrs->count = ++layer;