Hi > -----Original Message----- > From: Guo, Jia <jia....@intel.com> > Sent: Wednesday, March 17, 2021 11:12 > To: or...@nvidia.com; Zhang, Qi Z <qi.z.zh...@intel.com>; Xing, Beilei > <beilei.x...@intel.com>; Li, Xiaoyun <xiaoyun...@intel.com>; Wu, Jingjing > <jingjing...@intel.com> > Cc: Zhang, Yuying <yuying.zh...@intel.com>; Xu, Ting <ting...@intel.com>; > dev@dpdk.org; Guo, Jia <jia....@intel.com> > Subject: [PATCH v1 4/4] net/iavf: support FDIR for IP fragment packet > > New FDIR parsing are added to handle the fragmented IPv4/IPv6 packet. > > Signed-off-by: Ting Xu <ting...@intel.com> > Signed-off-by: Jeff Guo <jia....@intel.com> > --- > drivers/net/iavf/iavf_fdir.c | 278 ++++++++++++++++++--------- > drivers/net/iavf/iavf_generic_flow.h | 5 + > 2 files changed, 190 insertions(+), 93 deletions(-) > > diff --git a/drivers/net/iavf/iavf_fdir.c b/drivers/net/iavf/iavf_fdir.c index > e3f3b5f22a..348d423081 100644 > --- a/drivers/net/iavf/iavf_fdir.c > +++ b/drivers/net/iavf/iavf_fdir.c > @@ -34,7 +34,7 @@ <snip> > > uint8_t ipv6_addr_mask[16] = { > 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -528,12 > +534,6 @@ iavf_fdir_parse_pattern(__rte_unused struct iavf_adapter *ad, > }; > > for (item = pattern; item->type != RTE_FLOW_ITEM_TYPE_END; item++) > { > - if (item->last) {
You can't directly remove the check. If users use "last" for items like RTE_FLOW_ITEM_TYPE_ETH. The driver doesn't support that. > - rte_flow_error_set(error, EINVAL, > - RTE_FLOW_ERROR_TYPE_ITEM, item, > - "Not support range"); > - } > - > item_type = item->type; > <snip> > + if (ipv4_mask->hdr.version_ihl || > + ipv4_mask->hdr.total_length || > + ipv4_mask->hdr.hdr_checksum) { > + rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ITEM, > + item, "Invalid IPv4 mask."); > + return -rte_errno; > + } > > - rte_memcpy(hdr->buffer, > - &ipv4_spec->hdr, > - sizeof(ipv4_spec->hdr)); The ipv4_mask is checked. But what about ipv4_last? What if users set a rule which includes "last" for hdr.version_ihl? The code doesn't process that and not err return. You should block all situations in ipv4_last except for ipv4_last->hdr.fragment_offset. <snip> > + > + if (ipv4_mask->hdr.packet_id == UINT16_MAX || > + ipv4_mask->hdr.fragment_offset == UINT16_MAX) { And I don't understand your logic here. Only if ipv4_mask->hdr.fragment_offset and ipv4_mask->hdr.packet_id Are UINT16_MAX, you process this case. But what about other cases? Shouldn't those cases return err like not supported? And the mask for fragment_offset shouldn't be 0xffff (UINT16_MAX), it should be 0x3fff (RTE_IPV4_HDR_OFFSET_MASK | RTE_IPV4_HDR_MF_FLAG). Because only the last 14 bits matters. The other 2 bits are reserved bit and DF bit, it doesn't matter if it's fragment packets or not. > + if (ipv4_last && > + ipv4_spec->hdr.packet_id == 0 && > + ipv4_last->hdr.packet_id == 0xffff) And I don't understand this part too. I thought it's a fragment rule and non-fragment rule. Why is this related to packet_id? And what about fragment_offset spec and last? In ovs usercase, the rule for fragment packets is like flow create 0 ingress pattern eth / ipv4 src is xxx dst is xxx fragment_offset spec 0x8 fragment_offset last 0x2000 fragment_offset mask 0x3fff / end actions queue index 1 / end And the rule for non-fragment rule is like: flow create 0 ingress pattern eth / ipv4 src is xxx dst is xxx fragment_offset spec 0 fragment_offset mask 0x3fff / end actions queue index 1 / end or flow create 0 ingress pattern eth / ipv4 src is xxx dst is xxx fragment_offset mask 0x3fff / end actions queue index 1 / end How can your codes here make sure the rules behave correctly? > + spec_all_pid = true; > + > + /* All IPv4 fragment packet has the same > + * ethertype, if the spec is for all invalid > + * packet id, set the ethertype into input set. > + */ > + input_set |= spec_all_pid ? > + IAVF_INSET_ETHERTYPE : > + IAVF_INSET_IPV4_ID; > + > + if (spec_all_pid) > + > VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr1, > + ETH, ETHERTYPE); > + else > + > VIRTCHNL_ADD_PROTO_HDR_FIELD_BIT(hdr, > + IPV4, PKID); > } > > + rte_memcpy(hdr->buffer, &ipv4_spec->hdr, > + sizeof(ipv4_spec->hdr)); > + > hdrs.count = ++layer; > break; > I'm not familiar with IPv6 fragment rule. So not review that part. <snip> > -- > 2.20.1