[3/5] net/bnxt: fix protocol size for VXLAN encap copy

Message ID 141eb0140301108b1320ecfd93c89e48b02cd546.1605493464.git.jackmin@nvidia.com (mailing list archive)
State Changes Requested, archived
Delegated to: Ferruh Yigit
Headers
Series fix protocol size calculation |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Xiaoyu Min Nov. 16, 2020, 7:55 a.m. UTC
  From: Xiaoyu Min <jackmin@nvidia.com>

The rte_flow_item_eth and rte_flow_item_vlan items are refined.
The structs do not exactly represent the packet bits captured on the
wire anymore so should only copy real header instead of the whole struct.

Replace the rte_flow_item_* with the existing corresponding rte_*_hdr.

Fixes: 09315fc83861 ("ethdev: add VLAN attributes to ethernet and VLAN items")

Signed-off-by: Xiaoyu Min <jackmin@nvidia.com>
---
 drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)
  

Comments

Ferruh Yigit Nov. 16, 2020, 4:12 p.m. UTC | #1
On 11/16/2020 7:55 AM, Xiaoyu Min wrote:
> From: Xiaoyu Min <jackmin@nvidia.com>
> 
> The rte_flow_item_eth and rte_flow_item_vlan items are refined.
> The structs do not exactly represent the packet bits captured on the
> wire anymore so should only copy real header instead of the whole struct.
> 
> Replace the rte_flow_item_* with the existing corresponding rte_*_hdr.
> 
> Fixes: 09315fc83861 ("ethdev: add VLAN attributes to ethernet and VLAN items")
> 
> Signed-off-by: Xiaoyu Min <jackmin@nvidia.com>

<...>

> @@ -1726,7 +1727,7 @@ ulp_rte_vxlan_encap_act_handler(const struct rte_flow_action *action_item,
>   		BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
>   		return BNXT_TF_RC_ERROR;
>   	}
> -	vxlan_size = sizeof(struct rte_flow_item_vxlan);
> +	vxlan_size = sizeof(struct rte_vxlan_hdr);
>   	/* copy the vxlan details */
>   	memcpy(&vxlan_spec, item->spec, vxlan_size);
>   	vxlan_spec.flags = 0x08;
> 

'vxlan_size' seems used both to copy rt_flow_item [1] and to header [2]. Also 
''vxlan_size' is used to copy the 'vxlan_spec'.

Since both "struct rte_flow_item_vxlan" & "struct rte_vxlan_hdr" size is same, 
this should work fine, but I guess it may be broken if sizes of those two 
structures changes in the future.

[1]
memcpy(&vxlan_spec, item->spec, vxlan_size);

[2]
ulp_encap_buffer_copy(buff, (const uint8_t *)&vxlan_spec,
	vxlan_size, ULP_BUFFER_ALIGN_8_BYTE);
  
Ajit Khaparde Nov. 18, 2020, 12:34 a.m. UTC | #2
On Mon, Nov 16, 2020 at 8:13 AM Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> On 11/16/2020 7:55 AM, Xiaoyu Min wrote:
> > From: Xiaoyu Min <jackmin@nvidia.com>
> >
> > The rte_flow_item_eth and rte_flow_item_vlan items are refined.
> > The structs do not exactly represent the packet bits captured on the
> > wire anymore so should only copy real header instead of the whole struct.
> >
> > Replace the rte_flow_item_* with the existing corresponding rte_*_hdr.
> >
> > Fixes: 09315fc83861 ("ethdev: add VLAN attributes to ethernet and VLAN
> items")
> >
> > Signed-off-by: Xiaoyu Min <jackmin@nvidia.com>
>
> <...>
>
> > @@ -1726,7 +1727,7 @@ ulp_rte_vxlan_encap_act_handler(const struct
> rte_flow_action *action_item,
> >               BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
> >               return BNXT_TF_RC_ERROR;
> >       }
> > -     vxlan_size = sizeof(struct rte_flow_item_vxlan);
> > +     vxlan_size = sizeof(struct rte_vxlan_hdr);
> >       /* copy the vxlan details */
> >       memcpy(&vxlan_spec, item->spec, vxlan_size);
> >       vxlan_spec.flags = 0x08;
> >
>
> 'vxlan_size' seems used both to copy rt_flow_item [1] and to header [2].
> Also
> ''vxlan_size' is used to copy the 'vxlan_spec'.
>
> Since both "struct rte_flow_item_vxlan" & "struct rte_vxlan_hdr" size is
> same,
> this should work fine, but I guess it may be broken if sizes of those two
> structures changes in the future.
>
> [1]
> memcpy(&vxlan_spec, item->spec, vxlan_size);
>
> [2]
> ulp_encap_buffer_copy(buff, (const uint8_t *)&vxlan_spec,
>         vxlan_size, ULP_BUFFER_ALIGN_8_BYTE);
>
Also, I feel rte_flow_item_vxlan is a control plane structure while
rte_vlan_hdr is more for dataplane.
It's better to keep them separate to allow refining them independently.
  
Andrew Rybchenko Nov. 18, 2020, 6:37 a.m. UTC | #3
On 11/18/20 3:34 AM, Ajit Khaparde wrote:
> On Mon, Nov 16, 2020 at 8:13 AM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
>> On 11/16/2020 7:55 AM, Xiaoyu Min wrote:
>>> From: Xiaoyu Min <jackmin@nvidia.com>
>>>
>>> The rte_flow_item_eth and rte_flow_item_vlan items are refined.
>>> The structs do not exactly represent the packet bits captured on the
>>> wire anymore so should only copy real header instead of the whole struct.
>>>
>>> Replace the rte_flow_item_* with the existing corresponding rte_*_hdr.
>>>
>>> Fixes: 09315fc83861 ("ethdev: add VLAN attributes to ethernet and VLAN
>> items")
>>>
>>> Signed-off-by: Xiaoyu Min <jackmin@nvidia.com>
>>
>> <...>
>>
>>> @@ -1726,7 +1727,7 @@ ulp_rte_vxlan_encap_act_handler(const struct
>> rte_flow_action *action_item,
>>>               BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
>>>               return BNXT_TF_RC_ERROR;
>>>       }
>>> -     vxlan_size = sizeof(struct rte_flow_item_vxlan);
>>> +     vxlan_size = sizeof(struct rte_vxlan_hdr);
>>>       /* copy the vxlan details */
>>>       memcpy(&vxlan_spec, item->spec, vxlan_size);
>>>       vxlan_spec.flags = 0x08;
>>>
>>
>> 'vxlan_size' seems used both to copy rt_flow_item [1] and to header [2].
>> Also
>> ''vxlan_size' is used to copy the 'vxlan_spec'.
>>
>> Since both "struct rte_flow_item_vxlan" & "struct rte_vxlan_hdr" size is
>> same,
>> this should work fine, but I guess it may be broken if sizes of those two
>> structures changes in the future.
>>
>> [1]
>> memcpy(&vxlan_spec, item->spec, vxlan_size);
>>
>> [2]
>> ulp_encap_buffer_copy(buff, (const uint8_t *)&vxlan_spec,
>>         vxlan_size, ULP_BUFFER_ALIGN_8_BYTE);
>>
> Also, I feel rte_flow_item_vxlan is a control plane structure while
> rte_vlan_hdr is more for dataplane.
> It's better to keep them separate to allow refining them independently.

I disagree with the point. It is typical duplication which
should be fixed. VXLAN item should consist of rte_vxlan_hdr
plus extra non header fields. In fact, similar thing should
be done for Ethernet flow item spec.

These items are used for VXLAN encap action and in current
state of definitions it is tricky to use VXLAN and Ethernet
items to construct header to be prepended. It is required
to copy field by field since it is bad to rely on the fact
that flow item starts from protocol header if it is not
specified in corresponding C type definition.
  
Ajit Khaparde Nov. 18, 2020, 5:44 p.m. UTC | #4
On Tue, Nov 17, 2020 at 10:37 PM Andrew Rybchenko
<andrew.rybchenko@oktetlabs.ru> wrote:
>
> On 11/18/20 3:34 AM, Ajit Khaparde wrote:
> > On Mon, Nov 16, 2020 at 8:13 AM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> >
> >> On 11/16/2020 7:55 AM, Xiaoyu Min wrote:
> >>> From: Xiaoyu Min <jackmin@nvidia.com>
> >>>
> >>> The rte_flow_item_eth and rte_flow_item_vlan items are refined.
> >>> The structs do not exactly represent the packet bits captured on the
> >>> wire anymore so should only copy real header instead of the whole struct.
> >>>
> >>> Replace the rte_flow_item_* with the existing corresponding rte_*_hdr.
> >>>
> >>> Fixes: 09315fc83861 ("ethdev: add VLAN attributes to ethernet and VLAN
> >> items")
> >>>
> >>> Signed-off-by: Xiaoyu Min <jackmin@nvidia.com>
> >>
> >> <...>
> >>
> >>> @@ -1726,7 +1727,7 @@ ulp_rte_vxlan_encap_act_handler(const struct
> >> rte_flow_action *action_item,
> >>>               BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
> >>>               return BNXT_TF_RC_ERROR;
> >>>       }
> >>> -     vxlan_size = sizeof(struct rte_flow_item_vxlan);
> >>> +     vxlan_size = sizeof(struct rte_vxlan_hdr);
> >>>       /* copy the vxlan details */
> >>>       memcpy(&vxlan_spec, item->spec, vxlan_size);
> >>>       vxlan_spec.flags = 0x08;
> >>>
> >>
> >> 'vxlan_size' seems used both to copy rt_flow_item [1] and to header [2].
> >> Also
> >> ''vxlan_size' is used to copy the 'vxlan_spec'.
> >>
> >> Since both "struct rte_flow_item_vxlan" & "struct rte_vxlan_hdr" size is
> >> same,
> >> this should work fine, but I guess it may be broken if sizes of those two
> >> structures changes in the future.
> >>
> >> [1]
> >> memcpy(&vxlan_spec, item->spec, vxlan_size);
> >>
> >> [2]
> >> ulp_encap_buffer_copy(buff, (const uint8_t *)&vxlan_spec,
> >>         vxlan_size, ULP_BUFFER_ALIGN_8_BYTE);
> >>
> > Also, I feel rte_flow_item_vxlan is a control plane structure while
> > rte_vlan_hdr is more for dataplane.
> > It's better to keep them separate to allow refining them independently.
>
> I disagree with the point. It is typical duplication which
> should be fixed. VXLAN item should consist of rte_vxlan_hdr
> plus extra non header fields. In fact, similar thing should
> be done for Ethernet flow item spec.
>
> These items are used for VXLAN encap action and in current
> state of definitions it is tricky to use VXLAN and Ethernet
> items to construct header to be prepended. It is required
> to copy field by field since it is bad to rely on the fact
> that flow item starts from protocol header if it is not
> specified in corresponding C type definition.
I took a look at the change again. I had an impression that
it is changing from specific protocol header to rte flow item,
not the other way around. This is fine.
Note that the commit is changing VXLAN and VLAN. But the log
suggests only VXLAN. Other than that,

Acked-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
  

Patch

diff --git a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
index a54c55c5f5..823eeb21b8 100644
--- a/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
+++ b/drivers/net/bnxt/tf_ulp/ulp_rte_parser.c
@@ -3,6 +3,7 @@ 
  * All rights reserved.
  */
 
+#include <rte_vxlan.h>
 #include "bnxt.h"
 #include "ulp_template_db_enum.h"
 #include "ulp_template_struct.h"
@@ -1548,7 +1549,7 @@  ulp_rte_vxlan_encap_act_handler(const struct rte_flow_action *action_item,
 		buff = &ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG];
 		ulp_encap_buffer_copy(buff,
 				      item->spec,
-				      sizeof(struct rte_flow_item_vlan),
+				      sizeof(struct rte_vlan_hdr),
 				      ULP_BUFFER_ALIGN_8_BYTE);
 
 		if (!ulp_rte_item_skip_void(&item, 1))
@@ -1559,15 +1560,15 @@  ulp_rte_vxlan_encap_act_handler(const struct rte_flow_action *action_item,
 	if (item->type == RTE_FLOW_ITEM_TYPE_VLAN) {
 		vlan_num++;
 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG +
-		       sizeof(struct rte_flow_item_vlan)],
+		       sizeof(struct rte_vlan_hdr)],
 		       item->spec,
-		       sizeof(struct rte_flow_item_vlan));
+		       sizeof(struct rte_vlan_hdr));
 		if (!ulp_rte_item_skip_void(&item, 1))
 			return BNXT_TF_RC_ERROR;
 	}
 	/* Update the vlan count and size of more than one */
 	if (vlan_num) {
-		vlan_size = vlan_num * sizeof(struct rte_flow_item_vlan);
+		vlan_size = vlan_num * sizeof(struct rte_vlan_hdr);
 		vlan_num = tfp_cpu_to_be_32(vlan_num);
 		memcpy(&ap->act_details[BNXT_ULP_ACT_PROP_IDX_ENCAP_VTAG_NUM],
 		       &vlan_num,
@@ -1726,7 +1727,7 @@  ulp_rte_vxlan_encap_act_handler(const struct rte_flow_action *action_item,
 		BNXT_TF_DBG(ERR, "vxlan encap does not have vni\n");
 		return BNXT_TF_RC_ERROR;
 	}
-	vxlan_size = sizeof(struct rte_flow_item_vxlan);
+	vxlan_size = sizeof(struct rte_vxlan_hdr);
 	/* copy the vxlan details */
 	memcpy(&vxlan_spec, item->spec, vxlan_size);
 	vxlan_spec.flags = 0x08;