Message ID | 20210226081438.1693788-1-xiaoyun.li@intel.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | net/i40e: fix IPv4 fragment offload issue | expand |
Context | Check | Description |
---|---|---|
ci/iol-testing | success | Testing PASS |
ci/iol-mellanox-Functional | success | Functional Testing PASS |
ci/iol-mellanox-Performance | success | Performance Testing PASS |
ci/github-robot | success | github build: passed |
ci/travis-robot | fail | travis build: failed |
ci/intel-Testing | success | Testing PASS |
ci/Intel-compilation | success | Compilation OK |
ci/checkpatch | warning | coding style issues |
> -----Original Message----- > From: Li, Xiaoyun <xiaoyun.li@intel.com> > Sent: Friday, February 26, 2021 4:15 PM > To: dev@dpdk.org; Xing, Beilei <beilei.xing@intel.com>; Guo, Jia > <jia.guo@intel.com>; Finn, Emma <emma.finn@intel.com> > Cc: Li, Xiaoyun <xiaoyun.li@intel.com>; stable@dpdk.org > Subject: [PATCH] net/i40e: fix IPv4 fragment offload issue > > IPv4 fragment_offset mask was required to be 0 no matter what the spec value > was. But zero mask means not caring about fragment_offset field then both > non-frag and frag packets should hit the rule. > > But the actual fragment rules should be like the following: > Only non-fragment packets can hit Rule 1: > Rule 1: mask=0x3fff, spec=0 > Only fragment packets can hit rule 2: > Rule 2: mask=0x3fff, spec=0x8, last=0x2000 > > This patch allows the above rules. > > Fixes: 42044b69c67d ("net/i40e: support input set selection for FDIR") > Cc: stable@dpdk.org > > Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com> > --- > drivers/net/i40e/i40e_flow.c | 89 ++++++++++++++++++++++++++++++++---- > 1 file changed, 80 insertions(+), 9 deletions(-) > > diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index > 4d44282312..86d96d9a11 100644 > --- a/drivers/net/i40e/i40e_flow.c > +++ b/drivers/net/i40e/i40e_flow.c > + "Invalid IPv4 " > + "fragment_offset mask"); Needn't split the comments line. > + return -rte_errno; > + } > + /* > + * non-frag rule: > + * mask=0x3fff,sepc=0 Typo: sepc->spec > + * frag rule: > + * mask=0x3fff,spec=0x8,last=0x2000 > + */ > + if (frag_spec == > + (1 << RTE_IPV4_HDR_FO_SHIFT) && > + frag_last == > RTE_IPV4_HDR_MF_FLAG) { > + pctype = > + > I40E_FILTER_PCTYPE_FRAG_IPV4; > + } else if (frag_spec || frag_last) { > + rte_flow_error_set(error, > + EINVAL, > + > RTE_FLOW_ERROR_TYPE_ITEM, > + item, > + "Invalid IPv4 " > + "fragment_offset rule"); Same as above. > + return -rte_errno; > + } > + } else if (frag_spec || frag_last) { > + rte_flow_error_set(error, > + EINVAL, > + > RTE_FLOW_ERROR_TYPE_ITEM, > + item, > + "Invalid fragment_offset"); > + return -rte_errno; > + } > > if (input_set & (I40E_INSET_DMAC | > I40E_INSET_SMAC)) { > if (input_set & (I40E_INSET_IPV4_SRC > | > -- > 2.25.1
Hi > -----Original Message----- > From: Xing, Beilei <beilei.xing@intel.com> > Sent: Tuesday, March 2, 2021 14:54 > To: Li, Xiaoyun <xiaoyun.li@intel.com>; dev@dpdk.org; Guo, Jia > <jia.guo@intel.com>; Finn, Emma <emma.finn@intel.com> > Cc: stable@dpdk.org > Subject: RE: [PATCH] net/i40e: fix IPv4 fragment offload issue > > > > > -----Original Message----- > > From: Li, Xiaoyun <xiaoyun.li@intel.com> > > Sent: Friday, February 26, 2021 4:15 PM > > To: dev@dpdk.org; Xing, Beilei <beilei.xing@intel.com>; Guo, Jia > > <jia.guo@intel.com>; Finn, Emma <emma.finn@intel.com> > > Cc: Li, Xiaoyun <xiaoyun.li@intel.com>; stable@dpdk.org > > Subject: [PATCH] net/i40e: fix IPv4 fragment offload issue > > > > IPv4 fragment_offset mask was required to be 0 no matter what the spec > > value was. But zero mask means not caring about fragment_offset field > > then both non-frag and frag packets should hit the rule. > > > > But the actual fragment rules should be like the following: > > Only non-fragment packets can hit Rule 1: > > Rule 1: mask=0x3fff, spec=0 > > Only fragment packets can hit rule 2: > > Rule 2: mask=0x3fff, spec=0x8, last=0x2000 > > > > This patch allows the above rules. > > > > Fixes: 42044b69c67d ("net/i40e: support input set selection for FDIR") > > Cc: stable@dpdk.org > > > > Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com> > > --- > > drivers/net/i40e/i40e_flow.c | 89 > > ++++++++++++++++++++++++++++++++---- > > 1 file changed, 80 insertions(+), 9 deletions(-) > > > > diff --git a/drivers/net/i40e/i40e_flow.c > > b/drivers/net/i40e/i40e_flow.c index > > 4d44282312..86d96d9a11 100644 > > --- a/drivers/net/i40e/i40e_flow.c > > +++ b/drivers/net/i40e/i40e_flow.c > > > > + "Invalid IPv4 " > > + "fragment_offset mask"); > > Needn't split the comments line. > > > + return -rte_errno; > > + } > > + /* > > + * non-frag rule: > > + * mask=0x3fff,sepc=0 > > Typo: sepc->spec > > > + * frag rule: > > + * mask=0x3fff,spec=0x8,last=0x2000 > > + */ > > + if (frag_spec == > > + (1 << RTE_IPV4_HDR_FO_SHIFT) && > > + frag_last == > > RTE_IPV4_HDR_MF_FLAG) { > > + pctype = > > + > > I40E_FILTER_PCTYPE_FRAG_IPV4; > > + } else if (frag_spec || frag_last) { > > + rte_flow_error_set(error, > > + EINVAL, > > + > > RTE_FLOW_ERROR_TYPE_ITEM, > > + item, > > + "Invalid IPv4 " > > + "fragment_offset rule"); > > Same as above. > > > + return -rte_errno; > > + } > > + } else if (frag_spec || frag_last) { > > + rte_flow_error_set(error, > > + EINVAL, > > + > > RTE_FLOW_ERROR_TYPE_ITEM, > > + item, > > + "Invalid fragment_offset"); > > + return -rte_errno; > > + } > > > > if (input_set & (I40E_INSET_DMAC | > > I40E_INSET_SMAC)) { > > if (input_set & (I40E_INSET_IPV4_SRC > > | > > -- > > 2.25.1 Thanks for the review. Will update them in v2. BRs Xiaoyun
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 4d44282312..86d96d9a11 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -2433,7 +2433,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, const struct rte_flow_item *item = pattern; const struct rte_flow_item_eth *eth_spec, *eth_mask; const struct rte_flow_item_vlan *vlan_spec, *vlan_mask; - const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_mask; + const struct rte_flow_item_ipv4 *ipv4_spec, *ipv4_last, *ipv4_mask; const struct rte_flow_item_ipv6 *ipv6_spec, *ipv6_mask; const struct rte_flow_item_tcp *tcp_spec, *tcp_mask; const struct rte_flow_item_udp *udp_spec, *udp_mask; @@ -2446,7 +2446,6 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, uint8_t pctype = 0; uint64_t input_set = I40E_INSET_NONE; - uint16_t frag_off; enum rte_flow_item_type item_type; enum rte_flow_item_type next_type; enum rte_flow_item_type l3 = RTE_FLOW_ITEM_TYPE_END; @@ -2472,7 +2471,7 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, memset(len_arr, 0, sizeof(len_arr)); filter->input.flow_ext.customized_pctype = false; for (; item->type != RTE_FLOW_ITEM_TYPE_END; item++) { - if (item->last) { + if (item->last && item->type != RTE_FLOW_ITEM_TYPE_IPV4) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, item, @@ -2611,15 +2610,40 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, l3 = RTE_FLOW_ITEM_TYPE_IPV4; ipv4_spec = item->spec; ipv4_mask = item->mask; + ipv4_last = item->last; pctype = I40E_FILTER_PCTYPE_NONF_IPV4_OTHER; layer_idx = I40E_FLXPLD_L3_IDX; + if (ipv4_last) { + if (!ipv4_spec || !ipv4_mask || !outer_ip) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Not support range"); + return -rte_errno; + } + /* Only fragment_offset supports range */ + if (ipv4_last->hdr.version_ihl || + ipv4_last->hdr.type_of_service || + ipv4_last->hdr.total_length || + ipv4_last->hdr.packet_id || + ipv4_last->hdr.time_to_live || + ipv4_last->hdr.next_proto_id || + ipv4_last->hdr.hdr_checksum || + ipv4_last->hdr.src_addr || + ipv4_last->hdr.dst_addr) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Not support range"); + return -rte_errno; + } + } if (ipv4_spec && ipv4_mask && outer_ip) { /* Check IPv4 mask and update input set */ if (ipv4_mask->hdr.version_ihl || ipv4_mask->hdr.total_length || ipv4_mask->hdr.packet_id || - ipv4_mask->hdr.fragment_offset || ipv4_mask->hdr.hdr_checksum) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ITEM, @@ -2640,11 +2664,58 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev, input_set |= I40E_INSET_IPV4_PROTO; /* Check if it is fragment. */ - frag_off = ipv4_spec->hdr.fragment_offset; - frag_off = rte_be_to_cpu_16(frag_off); - if (frag_off & RTE_IPV4_HDR_OFFSET_MASK || - frag_off & RTE_IPV4_HDR_MF_FLAG) - pctype = I40E_FILTER_PCTYPE_FRAG_IPV4; + uint16_t frag_mask = + ipv4_mask->hdr.fragment_offset; + uint16_t frag_spec = + ipv4_spec->hdr.fragment_offset; + uint16_t frag_last = 0; + if (ipv4_last) + frag_last = + ipv4_last->hdr.fragment_offset; + if (frag_mask) { + frag_mask = rte_be_to_cpu_16(frag_mask); + frag_spec = rte_be_to_cpu_16(frag_spec); + frag_last = rte_be_to_cpu_16(frag_last); + /* frag_off mask has to be 0x3fff */ + if (frag_mask != + (RTE_IPV4_HDR_OFFSET_MASK | + RTE_IPV4_HDR_MF_FLAG)) { + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid IPv4 " + "fragment_offset mask"); + return -rte_errno; + } + /* + * non-frag rule: + * mask=0x3fff,sepc=0 + * frag rule: + * mask=0x3fff,spec=0x8,last=0x2000 + */ + if (frag_spec == + (1 << RTE_IPV4_HDR_FO_SHIFT) && + frag_last == RTE_IPV4_HDR_MF_FLAG) { + pctype = + I40E_FILTER_PCTYPE_FRAG_IPV4; + } else if (frag_spec || frag_last) { + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid IPv4 " + "fragment_offset rule"); + return -rte_errno; + } + } else if (frag_spec || frag_last) { + rte_flow_error_set(error, + EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "Invalid fragment_offset"); + return -rte_errno; + } if (input_set & (I40E_INSET_DMAC | I40E_INSET_SMAC)) { if (input_set & (I40E_INSET_IPV4_SRC |
IPv4 fragment_offset mask was required to be 0 no matter what the spec value was. But zero mask means not caring about fragment_offset field then both non-frag and frag packets should hit the rule. But the actual fragment rules should be like the following: Only non-fragment packets can hit Rule 1: Rule 1: mask=0x3fff, spec=0 Only fragment packets can hit rule 2: Rule 2: mask=0x3fff, spec=0x8, last=0x2000 This patch allows the above rules. Fixes: 42044b69c67d ("net/i40e: support input set selection for FDIR") Cc: stable@dpdk.org Signed-off-by: Xiaoyun Li <xiaoyun.li@intel.com> --- drivers/net/i40e/i40e_flow.c | 89 ++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 9 deletions(-)