diff mbox series

[2/2] pipeline: autodetect endianness of action args

Message ID 20210411232338.4005-2-cristian.dumitrescu@intel.com (mailing list archive)
State Accepted
Delegated to: Thomas Monjalon
Headers show
Series [1/2] pipeline: modularize the instruction optimizer | expand

Checks

Context Check Description
ci/github-robot success github build: passed
ci/travis-robot fail travis build: failed
ci/Intel-compilation fail Compilation issues
ci/checkpatch success coding style OK

Commit Message

Dumitrescu, Cristian April 11, 2021, 11:23 p.m. UTC
Each table entry is made up of match fields and action data, with the
latter made up of the action ID and the action arguments. The approach
of having the user specify explicitly the endianness of the action
arguments is difficult to be picked up by P4 compilers, as the P4
compiler is generally unaware about this aspect.

This commit introduces the auto-detection of the endianness of the
action arguments by examining the endianness of the their destination:
network byte order (NBO) when they get copied to headers and host byte
order (HBO) when they get copied to packet meta-data or mailboxes.

The endianness specification of each action argument as part of the
rule specification, e.g. H(...) and N(...) is removed from the rule
file and auto-detected based on their destination. The DMA instruction
scope is made internal, so mov instructions need to be used. The
pattern of transferring complete headers from table entry action args
to headers is detected, and the associated set of mov instructions
plus header validate is internally detected and replaced with the
internal-only DMA instruction to preserve performance.

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
 examples/pipeline/examples/vxlan.spec      |  41 ++-
 examples/pipeline/examples/vxlan_table.py  |  44 ++--
 examples/pipeline/examples/vxlan_table.txt |  32 +--
 lib/librte_pipeline/rte_swx_ctl.c          |  15 +-
 lib/librte_pipeline/rte_swx_ctl.h          |   6 +
 lib/librte_pipeline/rte_swx_pipeline.c     | 282 ++++++++++++++++++---
 lib/librte_pipeline/rte_swx_pipeline.h     |   4 -
 7 files changed, 322 insertions(+), 102 deletions(-)

Comments

Thomas Monjalon April 20, 2021, 12:48 a.m. UTC | #1
12/04/2021 01:23, Cristian Dumitrescu:
> Each table entry is made up of match fields and action data, with the
> latter made up of the action ID and the action arguments. The approach
> of having the user specify explicitly the endianness of the action
> arguments is difficult to be picked up by P4 compilers, as the P4
> compiler is generally unaware about this aspect.
> 
> This commit introduces the auto-detection of the endianness of the
> action arguments by examining the endianness of the their destination:
> network byte order (NBO) when they get copied to headers and host byte
> order (HBO) when they get copied to packet meta-data or mailboxes.
> 
> The endianness specification of each action argument as part of the
> rule specification, e.g. H(...) and N(...) is removed from the rule
> file and auto-detected based on their destination. The DMA instruction
> scope is made internal, so mov instructions need to be used. The
> pattern of transferring complete headers from table entry action args
> to headers is detected, and the associated set of mov instructions
> plus header validate is internally detected and replaced with the
> internal-only DMA instruction to preserve performance.
> 
> Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> ---
>  examples/pipeline/examples/vxlan.spec      |  41 ++-
>  examples/pipeline/examples/vxlan_table.py  |  44 ++--
>  examples/pipeline/examples/vxlan_table.txt |  32 +--
>  lib/librte_pipeline/rte_swx_ctl.c          |  15 +-
>  lib/librte_pipeline/rte_swx_ctl.h          |   6 +
>  lib/librte_pipeline/rte_swx_pipeline.c     | 282 ++++++++++++++++++---
>  lib/librte_pipeline/rte_swx_pipeline.h     |   4 -

There are compilation issues in the CI:
https://patches.dpdk.org/project/dpdk/patch/20210411232338.4005-2-cristian.dumitrescu@intel.com/
Dumitrescu, Cristian April 20, 2021, 10:04 a.m. UTC | #2
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, April 20, 2021 1:48 AM
> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> action args
> 
> 12/04/2021 01:23, Cristian Dumitrescu:
> > Each table entry is made up of match fields and action data, with the
> > latter made up of the action ID and the action arguments. The approach
> > of having the user specify explicitly the endianness of the action
> > arguments is difficult to be picked up by P4 compilers, as the P4
> > compiler is generally unaware about this aspect.
> >
> > This commit introduces the auto-detection of the endianness of the
> > action arguments by examining the endianness of the their destination:
> > network byte order (NBO) when they get copied to headers and host byte
> > order (HBO) when they get copied to packet meta-data or mailboxes.
> >
> > The endianness specification of each action argument as part of the
> > rule specification, e.g. H(...) and N(...) is removed from the rule
> > file and auto-detected based on their destination. The DMA instruction
> > scope is made internal, so mov instructions need to be used. The
> > pattern of transferring complete headers from table entry action args
> > to headers is detected, and the associated set of mov instructions
> > plus header validate is internally detected and replaced with the
> > internal-only DMA instruction to preserve performance.
> >
> > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > ---
> >  examples/pipeline/examples/vxlan.spec      |  41 ++-
> >  examples/pipeline/examples/vxlan_table.py  |  44 ++--
> >  examples/pipeline/examples/vxlan_table.txt |  32 +--
> >  lib/librte_pipeline/rte_swx_ctl.c          |  15 +-
> >  lib/librte_pipeline/rte_swx_ctl.h          |   6 +
> >  lib/librte_pipeline/rte_swx_pipeline.c     | 282 ++++++++++++++++++---
> >  lib/librte_pipeline/rte_swx_pipeline.h     |   4 -
> 
> There are compilation issues in the CI:
> https://patches.dpdk.org/project/dpdk/patch/20210411232338.4005-2-
> cristian.dumitrescu@intel.com/
> 

Hi Thomas,

The reason for the CI issues is because this patch set has dependencies on the previous patches that were pending, but now already applied by you (thank you!), so there should not be any real issues?

Regards,
Cristian
Thomas Monjalon April 20, 2021, 10:06 a.m. UTC | #3
20/04/2021 12:04, Dumitrescu, Cristian:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 12/04/2021 01:23, Cristian Dumitrescu:
> > > Each table entry is made up of match fields and action data, with the
> > > latter made up of the action ID and the action arguments. The approach
> > > of having the user specify explicitly the endianness of the action
> > > arguments is difficult to be picked up by P4 compilers, as the P4
> > > compiler is generally unaware about this aspect.
> > >
> > > This commit introduces the auto-detection of the endianness of the
> > > action arguments by examining the endianness of the their destination:
> > > network byte order (NBO) when they get copied to headers and host byte
> > > order (HBO) when they get copied to packet meta-data or mailboxes.
> > >
> > > The endianness specification of each action argument as part of the
> > > rule specification, e.g. H(...) and N(...) is removed from the rule
> > > file and auto-detected based on their destination. The DMA instruction
> > > scope is made internal, so mov instructions need to be used. The
> > > pattern of transferring complete headers from table entry action args
> > > to headers is detected, and the associated set of mov instructions
> > > plus header validate is internally detected and replaced with the
> > > internal-only DMA instruction to preserve performance.
> > >
> > > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > > ---
> > >  examples/pipeline/examples/vxlan.spec      |  41 ++-
> > >  examples/pipeline/examples/vxlan_table.py  |  44 ++--
> > >  examples/pipeline/examples/vxlan_table.txt |  32 +--
> > >  lib/librte_pipeline/rte_swx_ctl.c          |  15 +-
> > >  lib/librte_pipeline/rte_swx_ctl.h          |   6 +
> > >  lib/librte_pipeline/rte_swx_pipeline.c     | 282 ++++++++++++++++++---
> > >  lib/librte_pipeline/rte_swx_pipeline.h     |   4 -
> > 
> > There are compilation issues in the CI:
> > https://patches.dpdk.org/project/dpdk/patch/20210411232338.4005-2-
> > cristian.dumitrescu@intel.com/
> > 
> 
> Hi Thomas,
> 
> The reason for the CI issues is because this patch set has dependencies on the previous patches that were pending, but now already applied by you (thank you!), so there should not be any real issues?

Yes I didn't see any issue locally, just wanted to confirm.
Dumitrescu, Cristian April 20, 2021, 10:20 a.m. UTC | #4
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, April 20, 2021 11:07 AM
> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> action args
> 
> 20/04/2021 12:04, Dumitrescu, Cristian:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 12/04/2021 01:23, Cristian Dumitrescu:
> > > > Each table entry is made up of match fields and action data, with the
> > > > latter made up of the action ID and the action arguments. The approach
> > > > of having the user specify explicitly the endianness of the action
> > > > arguments is difficult to be picked up by P4 compilers, as the P4
> > > > compiler is generally unaware about this aspect.
> > > >
> > > > This commit introduces the auto-detection of the endianness of the
> > > > action arguments by examining the endianness of the their destination:
> > > > network byte order (NBO) when they get copied to headers and host
> byte
> > > > order (HBO) when they get copied to packet meta-data or mailboxes.
> > > >
> > > > The endianness specification of each action argument as part of the
> > > > rule specification, e.g. H(...) and N(...) is removed from the rule
> > > > file and auto-detected based on their destination. The DMA instruction
> > > > scope is made internal, so mov instructions need to be used. The
> > > > pattern of transferring complete headers from table entry action args
> > > > to headers is detected, and the associated set of mov instructions
> > > > plus header validate is internally detected and replaced with the
> > > > internal-only DMA instruction to preserve performance.
> > > >
> > > > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > > > ---
> > > >  examples/pipeline/examples/vxlan.spec      |  41 ++-
> > > >  examples/pipeline/examples/vxlan_table.py  |  44 ++--
> > > >  examples/pipeline/examples/vxlan_table.txt |  32 +--
> > > >  lib/librte_pipeline/rte_swx_ctl.c          |  15 +-
> > > >  lib/librte_pipeline/rte_swx_ctl.h          |   6 +
> > > >  lib/librte_pipeline/rte_swx_pipeline.c     | 282 ++++++++++++++++++-
> --
> > > >  lib/librte_pipeline/rte_swx_pipeline.h     |   4 -
> > >
> > > There are compilation issues in the CI:
> > > https://patches.dpdk.org/project/dpdk/patch/20210411232338.4005-2-
> > > cristian.dumitrescu@intel.com/
> > >
> >
> > Hi Thomas,
> >
> > The reason for the CI issues is because this patch set has dependencies on
> the previous patches that were pending, but now already applied by you
> (thank you!), so there should not be any real issues?
> 
> Yes I didn't see any issue locally, just wanted to confirm.
> 

Thanks, Thomas. I just double checked by applying this set on the main latest, and I could not see any apply or build issues.
Aaron Conole April 20, 2021, 2:48 p.m. UTC | #5
"Dumitrescu, Cristian" <cristian.dumitrescu@intel.com> writes:

>> -----Original Message-----
>> From: Thomas Monjalon <thomas@monjalon.net>
>> Sent: Tuesday, April 20, 2021 11:07 AM
>> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
>> Cc: dev@dpdk.org
>> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
>> action args
>> 
>> 20/04/2021 12:04, Dumitrescu, Cristian:
>> > From: Thomas Monjalon <thomas@monjalon.net>
>> > > 12/04/2021 01:23, Cristian Dumitrescu:
>> > > > Each table entry is made up of match fields and action data, with the
>> > > > latter made up of the action ID and the action arguments. The approach
>> > > > of having the user specify explicitly the endianness of the action
>> > > > arguments is difficult to be picked up by P4 compilers, as the P4
>> > > > compiler is generally unaware about this aspect.
>> > > >
>> > > > This commit introduces the auto-detection of the endianness of the
>> > > > action arguments by examining the endianness of the their destination:
>> > > > network byte order (NBO) when they get copied to headers and host
>> byte
>> > > > order (HBO) when they get copied to packet meta-data or mailboxes.
>> > > >
>> > > > The endianness specification of each action argument as part of the
>> > > > rule specification, e.g. H(...) and N(...) is removed from the rule
>> > > > file and auto-detected based on their destination. The DMA instruction
>> > > > scope is made internal, so mov instructions need to be used. The
>> > > > pattern of transferring complete headers from table entry action args
>> > > > to headers is detected, and the associated set of mov instructions
>> > > > plus header validate is internally detected and replaced with the
>> > > > internal-only DMA instruction to preserve performance.
>> > > >
>> > > > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>> > > > ---
>> > > >  examples/pipeline/examples/vxlan.spec      |  41 ++-
>> > > >  examples/pipeline/examples/vxlan_table.py  |  44 ++--
>> > > >  examples/pipeline/examples/vxlan_table.txt |  32 +--
>> > > >  lib/librte_pipeline/rte_swx_ctl.c          |  15 +-
>> > > >  lib/librte_pipeline/rte_swx_ctl.h          |   6 +
>> > > >  lib/librte_pipeline/rte_swx_pipeline.c     | 282 ++++++++++++++++++-
>> --
>> > > >  lib/librte_pipeline/rte_swx_pipeline.h     |   4 -
>> > >
>> > > There are compilation issues in the CI:
>> > > https://patches.dpdk.org/project/dpdk/patch/20210411232338.4005-2-
>> > > cristian.dumitrescu@intel.com/
>> > >
>> >
>> > Hi Thomas,
>> >
>> > The reason for the CI issues is because this patch set has dependencies on
>> the previous patches that were pending, but now already applied by you
>> (thank you!), so there should not be any real issues?
>> 
>> Yes I didn't see any issue locally, just wanted to confirm.
>> 
>
> Thanks, Thomas. I just double checked by applying this set on the main
> latest, and I could not see any apply or build issues.

I restarted the builds for this.

Currently, travis robot (but not github actions) reports an error even
after the restart of this build - this is in error.  The correct build
should be:

https://travis-ci.com/github/ovsrobot/dpdk/builds/223614512

And that shows the build completed successfully.  Looks like we pull the
build list incorrectly.
Thomas Monjalon April 20, 2021, 7:57 p.m. UTC | #6
12/04/2021 01:23, Cristian Dumitrescu:
> Each table entry is made up of match fields and action data, with the
> latter made up of the action ID and the action arguments. The approach
> of having the user specify explicitly the endianness of the action
> arguments is difficult to be picked up by P4 compilers, as the P4
> compiler is generally unaware about this aspect.
> 
> This commit introduces the auto-detection of the endianness of the
> action arguments by examining the endianness of the their destination:
> network byte order (NBO) when they get copied to headers and host byte
> order (HBO) when they get copied to packet meta-data or mailboxes.
> 
> The endianness specification of each action argument as part of the
> rule specification, e.g. H(...) and N(...) is removed from the rule
> file and auto-detected based on their destination. The DMA instruction
> scope is made internal, so mov instructions need to be used. The
> pattern of transferring complete headers from table entry action args
> to headers is detected, and the associated set of mov instructions
> plus header validate is internally detected and replaced with the
> internal-only DMA instruction to preserve performance.
> 
> Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>

Series applied, thanks
Ali Alnubani April 21, 2021, 7:49 a.m. UTC | #7
Hi,

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> Sent: Tuesday, April 20, 2021 10:58 PM
> To: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> action args
> 
> 12/04/2021 01:23, Cristian Dumitrescu:
> > Each table entry is made up of match fields and action data, with the
> > latter made up of the action ID and the action arguments. The approach
> > of having the user specify explicitly the endianness of the action
> > arguments is difficult to be picked up by P4 compilers, as the P4
> > compiler is generally unaware about this aspect.
> >
> > This commit introduces the auto-detection of the endianness of the
> > action arguments by examining the endianness of the their destination:
> > network byte order (NBO) when they get copied to headers and host byte
> > order (HBO) when they get copied to packet meta-data or mailboxes.
> >
> > The endianness specification of each action argument as part of the
> > rule specification, e.g. H(...) and N(...) is removed from the rule
> > file and auto-detected based on their destination. The DMA instruction
> > scope is made internal, so mov instructions need to be used. The
> > pattern of transferring complete headers from table entry action args
> > to headers is detected, and the associated set of mov instructions
> > plus header validate is internally detected and replaced with the
> > internal-only DMA instruction to preserve performance.
> >
> > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> 
> Series applied, thanks
> 
> 

I believe this patchset is causing the build failures in https://bugs.dpdk.org/show_bug.cgi?id=683.

Regards,
Ali
Aaron Conole April 21, 2021, 12:57 p.m. UTC | #8
Ali Alnubani <alialnu@nvidia.com> writes:

> Hi,
>
>> -----Original Message-----
>> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
>> Sent: Tuesday, April 20, 2021 10:58 PM
>> To: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>> Cc: dev@dpdk.org
>> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
>> action args
>> 
>> 12/04/2021 01:23, Cristian Dumitrescu:
>> > Each table entry is made up of match fields and action data, with the
>> > latter made up of the action ID and the action arguments. The approach
>> > of having the user specify explicitly the endianness of the action
>> > arguments is difficult to be picked up by P4 compilers, as the P4
>> > compiler is generally unaware about this aspect.
>> >
>> > This commit introduces the auto-detection of the endianness of the
>> > action arguments by examining the endianness of the their destination:
>> > network byte order (NBO) when they get copied to headers and host byte
>> > order (HBO) when they get copied to packet meta-data or mailboxes.
>> >
>> > The endianness specification of each action argument as part of the
>> > rule specification, e.g. H(...) and N(...) is removed from the rule
>> > file and auto-detected based on their destination. The DMA instruction
>> > scope is made internal, so mov instructions need to be used. The
>> > pattern of transferring complete headers from table entry action args
>> > to headers is detected, and the associated set of mov instructions
>> > plus header validate is internally detected and replaced with the
>> > internal-only DMA instruction to preserve performance.
>> >
>> > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>> 
>> Series applied, thanks
>> 
>> 
>
> I believe this patchset is causing the build failures in https://bugs.dpdk.org/show_bug.cgi?id=683.

Where do you see those build errors?  Compiler version, etc?  For example:

  https://github.com/ovsrobot/dpdk/actions/runs/767327010

This build was successful after rerunning with the prerequisite patch
applied to mainline.  I am concerned why the CI didn't catch this.

> Regards,
> Ali
Ali Alnubani April 21, 2021, 1:03 p.m. UTC | #9
> -----Original Message-----
> From: Aaron Conole <aconole@redhat.com>
> Sent: Wednesday, April 21, 2021 3:57 PM
> To: Ali Alnubani <alialnu@nvidia.com>
> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Cristian
> Dumitrescu <cristian.dumitrescu@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> action args
> 
> Ali Alnubani <alialnu@nvidia.com> writes:
> 
> > Hi,
> >
> >> -----Original Message-----
> >> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> >> Sent: Tuesday, April 20, 2021 10:58 PM
> >> To: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> >> Cc: dev@dpdk.org
> >> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> >> action args
> >>
> >> 12/04/2021 01:23, Cristian Dumitrescu:
> >> > Each table entry is made up of match fields and action data, with the
> >> > latter made up of the action ID and the action arguments. The approach
> >> > of having the user specify explicitly the endianness of the action
> >> > arguments is difficult to be picked up by P4 compilers, as the P4
> >> > compiler is generally unaware about this aspect.
> >> >
> >> > This commit introduces the auto-detection of the endianness of the
> >> > action arguments by examining the endianness of the their destination:
> >> > network byte order (NBO) when they get copied to headers and host
> byte
> >> > order (HBO) when they get copied to packet meta-data or mailboxes.
> >> >
> >> > The endianness specification of each action argument as part of the
> >> > rule specification, e.g. H(...) and N(...) is removed from the rule
> >> > file and auto-detected based on their destination. The DMA instruction
> >> > scope is made internal, so mov instructions need to be used. The
> >> > pattern of transferring complete headers from table entry action args
> >> > to headers is detected, and the associated set of mov instructions
> >> > plus header validate is internally detected and replaced with the
> >> > internal-only DMA instruction to preserve performance.
> >> >
> >> > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> >>
> >> Series applied, thanks
> >>
> >>
> >
> > I believe this patchset is causing the build failures in
> https://bugs.dpdk.org/show_bug.cgi?id=683.
> 
> Where do you see those build errors?  Compiler version, etc?  For example:
> 
>   https://github.com/ovsrobot/dpdk/actions/runs/767327010
> 
> This build was successful after rerunning with the prerequisite patch
> applied to mainline.  I am concerned why the CI didn't catch this.
> 

From the ticket:
> OS: CentOS 7.9.2009
> gcc: 4.8.5
> meson: 0.55.1
> ninja-build: 1.10.2

The build errors don't reproduce in Ubuntu 18.04.

- Ali
Aaron Conole April 21, 2021, 1:21 p.m. UTC | #10
Ali Alnubani <alialnu@nvidia.com> writes:

>> -----Original Message-----
>> From: Aaron Conole <aconole@redhat.com>
>> Sent: Wednesday, April 21, 2021 3:57 PM
>> To: Ali Alnubani <alialnu@nvidia.com>
>> Cc: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Cristian
>> Dumitrescu <cristian.dumitrescu@intel.com>; dev@dpdk.org
>> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
>> action args
>> 
>> Ali Alnubani <alialnu@nvidia.com> writes:
>> 
>> > Hi,
>> >
>> >> -----Original Message-----
>> >> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
>> >> Sent: Tuesday, April 20, 2021 10:58 PM
>> >> To: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>> >> Cc: dev@dpdk.org
>> >> Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
>> >> action args
>> >>
>> >> 12/04/2021 01:23, Cristian Dumitrescu:
>> >> > Each table entry is made up of match fields and action data, with the
>> >> > latter made up of the action ID and the action arguments. The approach
>> >> > of having the user specify explicitly the endianness of the action
>> >> > arguments is difficult to be picked up by P4 compilers, as the P4
>> >> > compiler is generally unaware about this aspect.
>> >> >
>> >> > This commit introduces the auto-detection of the endianness of the
>> >> > action arguments by examining the endianness of the their destination:
>> >> > network byte order (NBO) when they get copied to headers and host
>> byte
>> >> > order (HBO) when they get copied to packet meta-data or mailboxes.
>> >> >
>> >> > The endianness specification of each action argument as part of the
>> >> > rule specification, e.g. H(...) and N(...) is removed from the rule
>> >> > file and auto-detected based on their destination. The DMA instruction
>> >> > scope is made internal, so mov instructions need to be used. The
>> >> > pattern of transferring complete headers from table entry action args
>> >> > to headers is detected, and the associated set of mov instructions
>> >> > plus header validate is internally detected and replaced with the
>> >> > internal-only DMA instruction to preserve performance.
>> >> >
>> >> > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>> >>
>> >> Series applied, thanks
>> >>
>> >>
>> >
>> > I believe this patchset is causing the build failures in
>> https://bugs.dpdk.org/show_bug.cgi?id=683.
>> 
>> Where do you see those build errors?  Compiler version, etc?  For example:
>> 
>>   https://github.com/ovsrobot/dpdk/actions/runs/767327010
>> 
>> This build was successful after rerunning with the prerequisite patch
>> applied to mainline.  I am concerned why the CI didn't catch this.
>> 
>
> From the ticket:
>> OS: CentOS 7.9.2009
>> gcc: 4.8.5
>> meson: 0.55.1
>> ninja-build: 1.10.2
>
> The build errors don't reproduce in Ubuntu 18.04.

Thanks.

> - Ali
Dumitrescu, Cristian April 21, 2021, 1:58 p.m. UTC | #11
> -----Original Message-----
> From: Ali Alnubani <alialnu@nvidia.com>
> Sent: Wednesday, April 21, 2021 8:50 AM
> To: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Dumitrescu,
> Cristian <cristian.dumitrescu@intel.com>; Aaron Conole
> <aconole@redhat.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> action args
> 
> Hi,
> 
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> > Sent: Tuesday, April 20, 2021 10:58 PM
> > To: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> > action args
> >
> > 12/04/2021 01:23, Cristian Dumitrescu:
> > > Each table entry is made up of match fields and action data, with the
> > > latter made up of the action ID and the action arguments. The approach
> > > of having the user specify explicitly the endianness of the action
> > > arguments is difficult to be picked up by P4 compilers, as the P4
> > > compiler is generally unaware about this aspect.
> > >
> > > This commit introduces the auto-detection of the endianness of the
> > > action arguments by examining the endianness of the their destination:
> > > network byte order (NBO) when they get copied to headers and host
> byte
> > > order (HBO) when they get copied to packet meta-data or mailboxes.
> > >
> > > The endianness specification of each action argument as part of the
> > > rule specification, e.g. H(...) and N(...) is removed from the rule
> > > file and auto-detected based on their destination. The DMA instruction
> > > scope is made internal, so mov instructions need to be used. The
> > > pattern of transferring complete headers from table entry action args
> > > to headers is detected, and the associated set of mov instructions
> > > plus header validate is internally detected and replaced with the
> > > internal-only DMA instruction to preserve performance.
> > >
> > > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> >
> > Series applied, thanks
> >
> >
> 
> I believe this patchset is causing the build failures in
> https://bugs.dpdk.org/show_bug.cgi?id=683.
> 
> Regards,
> Ali

Hi Ali,

I checked this issue and here are my findings:

1. The compiler warnings are NOT caused by this patch, all of them are triggered by older code.
2. Why were they not triggered before? Either this is the first time CentOS 7 is run or the compiler has a mind of its own (my vote goes to the former).
3. These are all 100% fake issues that are probably triggered by the old GCC version from CentOS 7.

I just sent a patch now (you are copied on it) with some harmless local variable initializations in the hope it will stop these warnings on CentOS 7. As I don't have access to a CentOS 7 machine, can you please confirm whether the warnings are fixed?

As the warnings are triggered selectively for just more occurrences of a common pattern as opposed to all occurrences, I am trying to fix all occurrences of this pattern in order to prevent the same warnings showing up again.

Regards,
Cristian
Ali Alnubani April 21, 2021, 2:24 p.m. UTC | #12
Hi Cristian,

> -----Original Message-----
> From: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Sent: Wednesday, April 21, 2021 4:58 PM
> To: Ali Alnubani <alialnu@nvidia.com>; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; Aaron Conole <aconole@redhat.com>
> Cc: dev@dpdk.org
> Subject: RE: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> action args
> 
> 
> 
> > -----Original Message-----
> > From: Ali Alnubani <alialnu@nvidia.com>
> > Sent: Wednesday, April 21, 2021 8:50 AM
> > To: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>; Dumitrescu,
> > Cristian <cristian.dumitrescu@intel.com>; Aaron Conole
> > <aconole@redhat.com>
> > Cc: dev@dpdk.org
> > Subject: RE: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> > action args
> >
> > Hi,
> >
> > > -----Original Message-----
> > > From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> > > Sent: Tuesday, April 20, 2021 10:58 PM
> > > To: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > > Cc: dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> > > action args
> > >
> > > 12/04/2021 01:23, Cristian Dumitrescu:
> > > > Each table entry is made up of match fields and action data, with the
> > > > latter made up of the action ID and the action arguments. The approach
> > > > of having the user specify explicitly the endianness of the action
> > > > arguments is difficult to be picked up by P4 compilers, as the P4
> > > > compiler is generally unaware about this aspect.
> > > >
> > > > This commit introduces the auto-detection of the endianness of the
> > > > action arguments by examining the endianness of the their destination:
> > > > network byte order (NBO) when they get copied to headers and host
> > byte
> > > > order (HBO) when they get copied to packet meta-data or mailboxes.
> > > >
> > > > The endianness specification of each action argument as part of the
> > > > rule specification, e.g. H(...) and N(...) is removed from the rule
> > > > file and auto-detected based on their destination. The DMA instruction
> > > > scope is made internal, so mov instructions need to be used. The
> > > > pattern of transferring complete headers from table entry action args
> > > > to headers is detected, and the associated set of mov instructions
> > > > plus header validate is internally detected and replaced with the
> > > > internal-only DMA instruction to preserve performance.
> > > >
> > > > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > >
> > > Series applied, thanks
> > >
> > >
> >
> > I believe this patchset is causing the build failures in
> > https://bugs.dpdk.org/show_bug.cgi?id=683.
> >
> > Regards,
> > Ali
> 
> Hi Ali,
> 
> I checked this issue and here are my findings:
> 
> 1. The compiler warnings are NOT caused by this patch, all of them are
> triggered by older code.

Git-bisect pointed to this patch. The errors didn't reproduce without it.

> 2. Why were they not triggered before? Either this is the first time CentOS 7
> is run or the compiler has a mind of its own (my vote goes to the former).

The check ci/iol-testing contains an image with gcc 4.8.5 (RHEL 7), and I see now that it reproduced the errors in recent patches. See the failing build check in https://lab.dpdk.org/results/dashboard/patchsets/16682/ (under dpdk_meson_compile).

> 3. These are all 100% fake issues that are probably triggered by the old GCC
> version from CentOS 7.
> 
> I just sent a patch now (you are copied on it) with some harmless local
> variable initializations in the hope it will stop these warnings on CentOS 7. As I
> don't have access to a CentOS 7 machine, can you please confirm whether
> the warnings are fixed?
> 

I submitted a patch and updated the status of the Bugzilla ticket a few hours ago. See https://bugs.dpdk.org/show_bug.cgi?id=683#c4.

> As the warnings are triggered selectively for just more occurrences of a
> common pattern as opposed to all occurrences, I am trying to fix all
> occurrences of this pattern in order to prevent the same warnings showing
> up again.
> 

I only initialized occurrences of dst_struct_id and src_struct_id to resolve it though, maybe rebase and update your patch if you think initializing the rest is necessary?

Thanks,
Ali
Dumitrescu, Cristian April 21, 2021, 3:10 p.m. UTC | #13
Hi Ali,

> -----Original Message-----
> From: Ali Alnubani <alialnu@nvidia.com>
> Sent: Wednesday, April 21, 2021 3:25 PM
> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> Cc: dev@dpdk.org; NBU-Contact-Thomas Monjalon
> <thomas@monjalon.net>; Aaron Conole <aconole@redhat.com>
> Subject: RE: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> action args
> 
> Hi Cristian,
> 
> > -----Original Message-----
> > From: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>
> > Sent: Wednesday, April 21, 2021 4:58 PM
> > To: Ali Alnubani <alialnu@nvidia.com>; NBU-Contact-Thomas Monjalon
> > <thomas@monjalon.net>; Aaron Conole <aconole@redhat.com>
> > Cc: dev@dpdk.org
> > Subject: RE: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> > action args
> >
> >
> >
> > > -----Original Message-----
> > > From: Ali Alnubani <alialnu@nvidia.com>
> > > Sent: Wednesday, April 21, 2021 8:50 AM
> > > To: NBU-Contact-Thomas Monjalon <thomas@monjalon.net>;
> Dumitrescu,
> > > Cristian <cristian.dumitrescu@intel.com>; Aaron Conole
> > > <aconole@redhat.com>
> > > Cc: dev@dpdk.org
> > > Subject: RE: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness of
> > > action args
> > >
> > > Hi,
> > >
> > > > -----Original Message-----
> > > > From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> > > > Sent: Tuesday, April 20, 2021 10:58 PM
> > > > To: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > > > Cc: dev@dpdk.org
> > > > Subject: Re: [dpdk-dev] [PATCH 2/2] pipeline: autodetect endianness
> of
> > > > action args
> > > >
> > > > 12/04/2021 01:23, Cristian Dumitrescu:
> > > > > Each table entry is made up of match fields and action data, with the
> > > > > latter made up of the action ID and the action arguments. The
> approach
> > > > > of having the user specify explicitly the endianness of the action
> > > > > arguments is difficult to be picked up by P4 compilers, as the P4
> > > > > compiler is generally unaware about this aspect.
> > > > >
> > > > > This commit introduces the auto-detection of the endianness of the
> > > > > action arguments by examining the endianness of the their
> destination:
> > > > > network byte order (NBO) when they get copied to headers and host
> > > byte
> > > > > order (HBO) when they get copied to packet meta-data or mailboxes.
> > > > >
> > > > > The endianness specification of each action argument as part of the
> > > > > rule specification, e.g. H(...) and N(...) is removed from the rule
> > > > > file and auto-detected based on their destination. The DMA
> instruction
> > > > > scope is made internal, so mov instructions need to be used. The
> > > > > pattern of transferring complete headers from table entry action args
> > > > > to headers is detected, and the associated set of mov instructions
> > > > > plus header validate is internally detected and replaced with the
> > > > > internal-only DMA instruction to preserve performance.
> > > > >
> > > > > Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> > > >
> > > > Series applied, thanks
> > > >
> > > >
> > >
> > > I believe this patchset is causing the build failures in
> > > https://bugs.dpdk.org/show_bug.cgi?id=683.
> > >
> > > Regards,
> > > Ali
> >
> > Hi Ali,
> >
> > I checked this issue and here are my findings:
> >
> > 1. The compiler warnings are NOT caused by this patch, all of them are
> > triggered by older code.
> 
> Git-bisect pointed to this patch. The errors didn't reproduce without it.

This is strange, as code that your patch (as well as mine) "fixed" was not modified by this "pipeline: autodetect endianness ..." patch (easy to check).

Likely this patch triggered some bad memories in the "mind" of the compiler, but TBH I don't think we need to debug it at this point :)

> 
> > 2. Why were they not triggered before? Either this is the first time CentOS
> 7
> > is run or the compiler has a mind of its own (my vote goes to the former).
> 
> The check ci/iol-testing contains an image with gcc 4.8.5 (RHEL 7), and I see
> now that it reproduced the errors in recent patches. See the failing build
> check in https://lab.dpdk.org/results/dashboard/patchsets/16682/ (under
> dpdk_meson_compile).
> 
> > 3. These are all 100% fake issues that are probably triggered by the old GCC
> > version from CentOS 7.
> >
> > I just sent a patch now (you are copied on it) with some harmless local
> > variable initializations in the hope it will stop these warnings on CentOS 7.
> As I
> > don't have access to a CentOS 7 machine, can you please confirm whether
> > the warnings are fixed?
> >
> 
> I submitted a patch and updated the status of the Bugzilla ticket a few hours
> ago. See https://bugs.dpdk.org/show_bug.cgi?id=683#c4.
> 

Cool, thank you for looking at this issue and doing the work to fix it.

I did not see your patch in time, as for some reasons it landed in the bin folder as opposed to my usual DPDK folder.

> > As the warnings are triggered selectively for just more occurrences of a
> > common pattern as opposed to all occurrences, I am trying to fix all
> > occurrences of this pattern in order to prevent the same warnings showing
> > up again.
> >
> 
> I only initialized occurrences of dst_struct_id and src_struct_id to resolve it
> though, maybe rebase and update your patch if you think initializing the rest
> is necessary?
> 

There are a few others that might be triggered at some point, but difficult to have a full list now, maybe it is better to wait for now.

> Thanks,
> Ali

Thanks,
Cristian
diff mbox series

Patch

diff --git a/examples/pipeline/examples/vxlan.spec b/examples/pipeline/examples/vxlan.spec
index 347dca29d..ac62ab2be 100644
--- a/examples/pipeline/examples/vxlan.spec
+++ b/examples/pipeline/examples/vxlan.spec
@@ -60,7 +60,7 @@  metadata instanceof metadata_t
 struct vxlan_encap_args_t {
 	bit<48> ethernet_dst_addr
 	bit<48> ethernet_src_addr
-	bit<16> ethernet_ether_type
+	bit<16> ethernet_ethertype
 	bit<8> ipv4_ver_ihl
 	bit<8> ipv4_diffserv
 	bit<16> ipv4_total_len
@@ -114,11 +114,40 @@  struct vxlan_encap_args_t {
 //
 
 action vxlan_encap args instanceof vxlan_encap_args_t {
-	//Copy from table entry to headers and metadata.
-	dma h.outer_ethernet t.ethernet_dst_addr
-	dma h.outer_ipv4 t.ipv4_ver_ihl
-	dma h.outer_udp t.udp_src_port
-	dma h.outer_vxlan t.vxlan_flags
+	//Set the outer Ethernet header.
+	mov h.outer_ethernet.dst_addr t.ethernet_dst_addr
+	mov h.outer_ethernet.src_addr t.ethernet_src_addr
+	mov h.outer_ethernet.ethertype t.ethernet_ethertype
+	validate h.outer_ethernet
+
+	//Set the outer IPv4 header.
+	mov h.outer_ipv4.ver_ihl t.ipv4_ver_ihl
+	mov h.outer_ipv4.diffserv t.ipv4_diffserv
+	mov h.outer_ipv4.total_len t.ipv4_total_len
+	mov h.outer_ipv4.identification t.ipv4_identification
+	mov h.outer_ipv4.flags_offset t.ipv4_flags_offset
+	mov h.outer_ipv4.ttl t.ipv4_ttl
+	mov h.outer_ipv4.protocol t.ipv4_protocol
+	mov h.outer_ipv4.hdr_checksum t.ipv4_hdr_checksum
+	mov h.outer_ipv4.src_addr t.ipv4_src_addr
+	mov h.outer_ipv4.dst_addr t.ipv4_dst_addr
+	validate h.outer_ipv4
+
+	//Set the outer UDP header.
+	mov h.outer_udp.src_port t.udp_src_port
+	mov h.outer_udp.dst_port t.udp_dst_port
+	mov h.outer_udp.length t.udp_length
+	mov h.outer_udp.checksum t.udp_checksum
+	validate h.outer_udp
+
+	//Set the outer VXLAN header.
+	mov h.outer_vxlan.flags t.vxlan_flags
+	mov h.outer_vxlan.reserved t.vxlan_reserved
+	mov h.outer_vxlan.vni t.vxlan_vni
+	mov h.outer_vxlan.reserved2 t.vxlan_reserved2
+	validate h.outer_vxlan
+
+	//Set the output port.
 	mov m.port_out t.port_out
 
 	//Update h.outer_ipv4.total_len field.
diff --git a/examples/pipeline/examples/vxlan_table.py b/examples/pipeline/examples/vxlan_table.py
index 820c208c7..b1c6f1acd 100755
--- a/examples/pipeline/examples/vxlan_table.py
+++ b/examples/pipeline/examples/vxlan_table.py
@@ -13,28 +13,28 @@ 
 
 KEY = '0xaabbccdd{0:04x}'
 ACTION = 'vxlan_encap'
-ETHERNET_HEADER = 'ethernet_dst_addr N(0xa0a1a2a3{0:04x}) ' \
-    'ethernet_src_addr N(0xb0b1b2b3{0:04x}) ' \
-    'ethernet_ether_type N(0x0800)'
-IPV4_HEADER = 'ipv4_ver_ihl N(0x45) ' \
-    'ipv4_diffserv N(0) ' \
-    'ipv4_total_len N(50) ' \
-    'ipv4_identification N(0) ' \
-    'ipv4_flags_offset N(0) ' \
-    'ipv4_ttl N(64) ' \
-    'ipv4_protocol N(17) ' \
-    'ipv4_hdr_checksum N(0x{1:04x}) ' \
-    'ipv4_src_addr N(0xc0c1{0:04x}) ' \
-    'ipv4_dst_addr N(0xd0d1{0:04x})'
-UDP_HEADER = 'udp_src_port N(0xe0{0:02x}) ' \
-    'udp_dst_port N(4789) ' \
-    'udp_length N(30) ' \
-    'udp_checksum N(0)'
-VXLAN_HEADER = 'vxlan_flags N(0) ' \
-    'vxlan_reserved N(0) ' \
-    'vxlan_vni N({0:d}) ' \
-    'vxlan_reserved2 N(0)'
-PORT_OUT = 'port_out H({0:d})'
+ETHERNET_HEADER = 'ethernet_dst_addr 0xa0a1a2a3{0:04x} ' \
+    'ethernet_src_addr 0xb0b1b2b3{0:04x} ' \
+    'ethernet_ethertype 0x0800'
+IPV4_HEADER = 'ipv4_ver_ihl 0x45 ' \
+    'ipv4_diffserv 0 ' \
+    'ipv4_total_len 50 ' \
+    'ipv4_identification 0 ' \
+    'ipv4_flags_offset 0 ' \
+    'ipv4_ttl 64 ' \
+    'ipv4_protocol 17 ' \
+    'ipv4_hdr_checksum 0x{1:04x} ' \
+    'ipv4_src_addr 0xc0c1{0:04x} ' \
+    'ipv4_dst_addr 0xd0d1{0:04x}'
+UDP_HEADER = 'udp_src_port 0xe0{0:02x} ' \
+    'udp_dst_port 4789 ' \
+    'udp_length 30 ' \
+    'udp_checksum 0'
+VXLAN_HEADER = 'vxlan_flags 0 ' \
+    'vxlan_reserved 0 ' \
+    'vxlan_vni {0:d} ' \
+    'vxlan_reserved2 0'
+PORT_OUT = 'port_out {0:d}'
 
 def ipv4_header_checksum(i):
     cksum = (0x4500 + 0x0032) + (0x0000 + 0x0000) + (0x4011 + 0x0000) + (0xc0c1 + i) + (0xd0d1 + i)
diff --git a/examples/pipeline/examples/vxlan_table.txt b/examples/pipeline/examples/vxlan_table.txt
index acac80a38..25ca647ab 100644
--- a/examples/pipeline/examples/vxlan_table.txt
+++ b/examples/pipeline/examples/vxlan_table.txt
@@ -1,16 +1,16 @@ 
-match 0xaabbccdd0000 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30000) ethernet_src_addr N(0xb0b1b2b30000) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe928) ipv4_src_addr N(0xc0c10000) ipv4_dst_addr N(0xd0d10000) udp_src_port N(0xe000) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(0) vxlan_reserved2 N(0) port_out H(0)
-match 0xaabbccdd0001 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30001) ethernet_src_addr N(0xb0b1b2b30001) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe926) ipv4_src_addr N(0xc0c10001) ipv4_dst_addr N(0xd0d10001) udp_src_port N(0xe001) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(1) vxlan_reserved2 N(0) port_out H(1)
-match 0xaabbccdd0002 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30002) ethernet_src_addr N(0xb0b1b2b30002) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe924) ipv4_src_addr N(0xc0c10002) ipv4_dst_addr N(0xd0d10002) udp_src_port N(0xe002) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(2) vxlan_reserved2 N(0) port_out H(2)
-match 0xaabbccdd0003 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30003) ethernet_src_addr N(0xb0b1b2b30003) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe922) ipv4_src_addr N(0xc0c10003) ipv4_dst_addr N(0xd0d10003) udp_src_port N(0xe003) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(3) vxlan_reserved2 N(0) port_out H(3)
-match 0xaabbccdd0004 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30004) ethernet_src_addr N(0xb0b1b2b30004) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe920) ipv4_src_addr N(0xc0c10004) ipv4_dst_addr N(0xd0d10004) udp_src_port N(0xe004) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(4) vxlan_reserved2 N(0) port_out H(0)
-match 0xaabbccdd0005 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30005) ethernet_src_addr N(0xb0b1b2b30005) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe91e) ipv4_src_addr N(0xc0c10005) ipv4_dst_addr N(0xd0d10005) udp_src_port N(0xe005) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(5) vxlan_reserved2 N(0) port_out H(1)
-match 0xaabbccdd0006 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30006) ethernet_src_addr N(0xb0b1b2b30006) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe91c) ipv4_src_addr N(0xc0c10006) ipv4_dst_addr N(0xd0d10006) udp_src_port N(0xe006) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(6) vxlan_reserved2 N(0) port_out H(2)
-match 0xaabbccdd0007 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30007) ethernet_src_addr N(0xb0b1b2b30007) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe91a) ipv4_src_addr N(0xc0c10007) ipv4_dst_addr N(0xd0d10007) udp_src_port N(0xe007) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(7) vxlan_reserved2 N(0) port_out H(3)
-match 0xaabbccdd0008 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30008) ethernet_src_addr N(0xb0b1b2b30008) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe918) ipv4_src_addr N(0xc0c10008) ipv4_dst_addr N(0xd0d10008) udp_src_port N(0xe008) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(8) vxlan_reserved2 N(0) port_out H(0)
-match 0xaabbccdd0009 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30009) ethernet_src_addr N(0xb0b1b2b30009) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe916) ipv4_src_addr N(0xc0c10009) ipv4_dst_addr N(0xd0d10009) udp_src_port N(0xe009) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(9) vxlan_reserved2 N(0) port_out H(1)
-match 0xaabbccdd000a action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000a) ethernet_src_addr N(0xb0b1b2b3000a) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe914) ipv4_src_addr N(0xc0c1000a) ipv4_dst_addr N(0xd0d1000a) udp_src_port N(0xe00a) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(10) vxlan_reserved2 N(0) port_out H(2)
-match 0xaabbccdd000b action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000b) ethernet_src_addr N(0xb0b1b2b3000b) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe912) ipv4_src_addr N(0xc0c1000b) ipv4_dst_addr N(0xd0d1000b) udp_src_port N(0xe00b) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(11) vxlan_reserved2 N(0) port_out H(3)
-match 0xaabbccdd000c action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000c) ethernet_src_addr N(0xb0b1b2b3000c) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe910) ipv4_src_addr N(0xc0c1000c) ipv4_dst_addr N(0xd0d1000c) udp_src_port N(0xe00c) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(12) vxlan_reserved2 N(0) port_out H(0)
-match 0xaabbccdd000d action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000d) ethernet_src_addr N(0xb0b1b2b3000d) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe90e) ipv4_src_addr N(0xc0c1000d) ipv4_dst_addr N(0xd0d1000d) udp_src_port N(0xe00d) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(13) vxlan_reserved2 N(0) port_out H(1)
-match 0xaabbccdd000e action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000e) ethernet_src_addr N(0xb0b1b2b3000e) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe90c) ipv4_src_addr N(0xc0c1000e) ipv4_dst_addr N(0xd0d1000e) udp_src_port N(0xe00e) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(14) vxlan_reserved2 N(0) port_out H(2)
-match 0xaabbccdd000f action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000f) ethernet_src_addr N(0xb0b1b2b3000f) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe90a) ipv4_src_addr N(0xc0c1000f) ipv4_dst_addr N(0xd0d1000f) udp_src_port N(0xe00f) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(15) vxlan_reserved2 N(0) port_out H(3)
+match 0xaabbccdd0000 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30000 ethernet_src_addr 0xb0b1b2b30000 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe928 ipv4_src_addr 0xc0c10000 ipv4_dst_addr 0xd0d10000 udp_src_port 0xe000 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 0 vxlan_reserved2 0 port_out 0
+match 0xaabbccdd0001 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30001 ethernet_src_addr 0xb0b1b2b30001 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe926 ipv4_src_addr 0xc0c10001 ipv4_dst_addr 0xd0d10001 udp_src_port 0xe001 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 1 vxlan_reserved2 0 port_out 1
+match 0xaabbccdd0002 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30002 ethernet_src_addr 0xb0b1b2b30002 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe924 ipv4_src_addr 0xc0c10002 ipv4_dst_addr 0xd0d10002 udp_src_port 0xe002 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 2 vxlan_reserved2 0 port_out 2
+match 0xaabbccdd0003 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30003 ethernet_src_addr 0xb0b1b2b30003 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe922 ipv4_src_addr 0xc0c10003 ipv4_dst_addr 0xd0d10003 udp_src_port 0xe003 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 3 vxlan_reserved2 0 port_out 3
+match 0xaabbccdd0004 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30004 ethernet_src_addr 0xb0b1b2b30004 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe920 ipv4_src_addr 0xc0c10004 ipv4_dst_addr 0xd0d10004 udp_src_port 0xe004 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 4 vxlan_reserved2 0 port_out 0
+match 0xaabbccdd0005 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30005 ethernet_src_addr 0xb0b1b2b30005 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe91e ipv4_src_addr 0xc0c10005 ipv4_dst_addr 0xd0d10005 udp_src_port 0xe005 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 5 vxlan_reserved2 0 port_out 1
+match 0xaabbccdd0006 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30006 ethernet_src_addr 0xb0b1b2b30006 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe91c ipv4_src_addr 0xc0c10006 ipv4_dst_addr 0xd0d10006 udp_src_port 0xe006 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 6 vxlan_reserved2 0 port_out 2
+match 0xaabbccdd0007 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30007 ethernet_src_addr 0xb0b1b2b30007 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe91a ipv4_src_addr 0xc0c10007 ipv4_dst_addr 0xd0d10007 udp_src_port 0xe007 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 7 vxlan_reserved2 0 port_out 3
+match 0xaabbccdd0008 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30008 ethernet_src_addr 0xb0b1b2b30008 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe918 ipv4_src_addr 0xc0c10008 ipv4_dst_addr 0xd0d10008 udp_src_port 0xe008 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 8 vxlan_reserved2 0 port_out 0
+match 0xaabbccdd0009 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30009 ethernet_src_addr 0xb0b1b2b30009 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe916 ipv4_src_addr 0xc0c10009 ipv4_dst_addr 0xd0d10009 udp_src_port 0xe009 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 9 vxlan_reserved2 0 port_out 1
+match 0xaabbccdd000a action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000a ethernet_src_addr 0xb0b1b2b3000a ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe914 ipv4_src_addr 0xc0c1000a ipv4_dst_addr 0xd0d1000a udp_src_port 0xe00a udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 10 vxlan_reserved2 0 port_out 2
+match 0xaabbccdd000b action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000b ethernet_src_addr 0xb0b1b2b3000b ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe912 ipv4_src_addr 0xc0c1000b ipv4_dst_addr 0xd0d1000b udp_src_port 0xe00b udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 11 vxlan_reserved2 0 port_out 3
+match 0xaabbccdd000c action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000c ethernet_src_addr 0xb0b1b2b3000c ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe910 ipv4_src_addr 0xc0c1000c ipv4_dst_addr 0xd0d1000c udp_src_port 0xe00c udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 12 vxlan_reserved2 0 port_out 0
+match 0xaabbccdd000d action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000d ethernet_src_addr 0xb0b1b2b3000d ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe90e ipv4_src_addr 0xc0c1000d ipv4_dst_addr 0xd0d1000d udp_src_port 0xe00d udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 13 vxlan_reserved2 0 port_out 1
+match 0xaabbccdd000e action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000e ethernet_src_addr 0xb0b1b2b3000e ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe90c ipv4_src_addr 0xc0c1000e ipv4_dst_addr 0xd0d1000e udp_src_port 0xe00e udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 14 vxlan_reserved2 0 port_out 2
+match 0xaabbccdd000f action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000f ethernet_src_addr 0xb0b1b2b3000f ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe90a ipv4_src_addr 0xc0c1000f ipv4_dst_addr 0xd0d1000f udp_src_port 0xe00f udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 15 vxlan_reserved2 0 port_out 3
diff --git a/lib/librte_pipeline/rte_swx_ctl.c b/lib/librte_pipeline/rte_swx_ctl.c
index ca30767ef..4d1ff9ead 100644
--- a/lib/librte_pipeline/rte_swx_ctl.c
+++ b/lib/librte_pipeline/rte_swx_ctl.c
@@ -1721,30 +1721,19 @@  rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl,
 		struct rte_swx_ctl_action_arg_info *arg = &action->args[i];
 		char *arg_name, *arg_val;
 		uint64_t val;
-		int is_nbo = 0;
 
 		arg_name = tokens[2 + i * 2];
 		arg_val = tokens[2 + i * 2 + 1];
 
-		if (strcmp(arg_name, arg->name) ||
-		    (strlen(arg_val) < 4) ||
-		    ((arg_val[0] != 'H') && (arg_val[0] != 'N')) ||
-		    (arg_val[1] != '(') ||
-		    (arg_val[strlen(arg_val) - 1] != ')'))
+		if (strcmp(arg_name, arg->name))
 			goto error;
 
-		if (arg_val[0] == 'N')
-			is_nbo = 1;
-
-		arg_val[strlen(arg_val) - 1] = 0; /* Remove the ')'. */
-		arg_val += 2; /* Remove the "H(" or "N(". */
-
 		val = strtoull(arg_val, &arg_val, 0);
 		if (arg_val[0])
 			goto error;
 
 		/* Endianness conversion. */
-		if (is_nbo)
+		if (arg->is_network_byte_order)
 			val = field_hton(val, arg->n_bits);
 
 		/* Copy to entry. */
diff --git a/lib/librte_pipeline/rte_swx_ctl.h b/lib/librte_pipeline/rte_swx_ctl.h
index b8f22c516..4e5befb50 100644
--- a/lib/librte_pipeline/rte_swx_ctl.h
+++ b/lib/librte_pipeline/rte_swx_ctl.h
@@ -168,6 +168,12 @@  struct rte_swx_ctl_action_arg_info {
 
 	/** Action argument size (in bits). */
 	uint32_t n_bits;
+
+	/** Non-zero (true) when this action argument must be stored in the
+	 * table in network byte order (NBO), zero when it must be stored in
+	 * host byte order (HBO).
+	 */
+	int is_network_byte_order;
 };
 
 /**
diff --git a/lib/librte_pipeline/rte_swx_pipeline.c b/lib/librte_pipeline/rte_swx_pipeline.c
index ba828cbda..d9f47b07e 100644
--- a/lib/librte_pipeline/rte_swx_pipeline.c
+++ b/lib/librte_pipeline/rte_swx_pipeline.c
@@ -733,6 +733,7 @@  struct action {
 	TAILQ_ENTRY(action) node;
 	char name[RTE_SWX_NAME_SIZE];
 	struct struct_type *st;
+	int *args_endianness; /* 0 = Host Byte Order (HBO). */
 	struct instruction *instructions;
 	uint32_t n_instructions;
 	uint32_t id;
@@ -2342,6 +2343,18 @@  header_find(struct rte_swx_pipeline *p, const char *name)
 	return NULL;
 }
 
+static struct header *
+header_find_by_struct_id(struct rte_swx_pipeline *p, uint32_t struct_id)
+{
+	struct header *elem;
+
+	TAILQ_FOREACH(elem, &p->headers, node)
+		if (elem->struct_id == struct_id)
+			return elem;
+
+	return NULL;
+}
+
 static struct header *
 header_parse(struct rte_swx_pipeline *p,
 	     const char *name)
@@ -3722,37 +3735,6 @@  instr_mov_i_exec(struct rte_swx_pipeline *p)
 /*
  * dma.
  */
-static int
-instr_dma_translate(struct rte_swx_pipeline *p,
-		    struct action *action,
-		    char **tokens,
-		    int n_tokens,
-		    struct instruction *instr,
-		    struct instruction_data *data __rte_unused)
-{
-	char *dst = tokens[1];
-	char *src = tokens[2];
-	struct header *h;
-	struct field *tf;
-
-	CHECK(action, EINVAL);
-	CHECK(n_tokens == 3, EINVAL);
-
-	h = header_parse(p, dst);
-	CHECK(h, EINVAL);
-
-	tf = action_field_parse(action, src);
-	CHECK(tf, EINVAL);
-
-	instr->type = INSTR_DMA_HT;
-	instr->dma.dst.header_id[0] = h->id;
-	instr->dma.dst.struct_id[0] = h->struct_id;
-	instr->dma.n_bytes[0] = h->st->n_bits / 8;
-	instr->dma.src.offset[0] = tf->offset / 8;
-
-	return 0;
-}
-
 static inline void
 __instr_dma_ht_exec(struct rte_swx_pipeline *p, uint32_t n_dma);
 
@@ -7710,14 +7692,6 @@  instr_translate(struct rte_swx_pipeline *p,
 					   instr,
 					   data);
 
-	if (!strcmp(tokens[tpos], "dma"))
-		return instr_dma_translate(p,
-					   action,
-					   &tokens[tpos],
-					   n_tokens - tpos,
-					   instr,
-					   data);
-
 	if (!strcmp(tokens[tpos], "add"))
 		return instr_alu_add_translate(p,
 					       action,
@@ -8294,6 +8268,180 @@  instr_pattern_emit_many_tx_optimize(struct instruction *instructions,
 	return n_instructions;
 }
 
+static uint32_t
+action_arg_src_mov_count(struct action *a,
+			 uint32_t arg_id,
+			 struct instruction *instructions,
+			 struct instruction_data *instruction_data,
+			 uint32_t n_instructions);
+
+static int
+instr_pattern_mov_all_validate_search(struct rte_swx_pipeline *p,
+				      struct action *a,
+				      struct instruction *instr,
+				      struct instruction_data *data,
+				      uint32_t n_instr,
+				      struct instruction *instructions,
+				      struct instruction_data *instruction_data,
+				      uint32_t n_instructions,
+				      uint32_t *n_pattern_instr)
+{
+	struct header *h;
+	uint32_t src_field_id, i, j;
+
+	/* Prerequisites. */
+	if (!a || !a->st)
+		return 0;
+
+	/* First instruction: MOV_HM. */
+	if (data[0].invalid || (instr[0].type != INSTR_MOV_HM))
+		return 0;
+
+	h = header_find_by_struct_id(p, instr[0].mov.dst.struct_id);
+	if (!h)
+		return 0;
+
+	for (src_field_id = 0; src_field_id < a->st->n_fields; src_field_id++)
+		if (instr[0].mov.src.offset == a->st->fields[src_field_id].offset / 8)
+			break;
+
+	if (src_field_id == a->st->n_fields)
+		return 0;
+
+	if (instr[0].mov.dst.offset ||
+	    (instr[0].mov.dst.n_bits != h->st->fields[0].n_bits) ||
+	    instr[0].mov.src.struct_id ||
+	    (instr[0].mov.src.n_bits != a->st->fields[src_field_id].n_bits) ||
+	    (instr[0].mov.dst.n_bits != instr[0].mov.src.n_bits))
+		return 0;
+
+	if ((n_instr < h->st->n_fields + 1) ||
+	     (a->st->n_fields < src_field_id + h->st->n_fields + 1))
+		return 0;
+
+	/* Subsequent instructions: MOV_HM. */
+	for (i = 1; i < h->st->n_fields; i++)
+		if (data[i].invalid ||
+		    data[i].n_users ||
+		    (instr[i].type != INSTR_MOV_HM) ||
+		    (instr[i].mov.dst.struct_id != h->struct_id) ||
+		    (instr[i].mov.dst.offset != h->st->fields[i].offset / 8) ||
+		    (instr[i].mov.dst.n_bits != h->st->fields[i].n_bits) ||
+		    instr[i].mov.src.struct_id ||
+		    (instr[i].mov.src.offset != a->st->fields[src_field_id + i].offset / 8) ||
+		    (instr[i].mov.src.n_bits != a->st->fields[src_field_id + i].n_bits) ||
+		    (instr[i].mov.dst.n_bits != instr[i].mov.src.n_bits))
+			return 0;
+
+	/* Last instruction: HDR_VALIDATE. */
+	if ((instr[i].type != INSTR_HDR_VALIDATE) ||
+	    (instr[i].valid.header_id != h->id))
+		return 0;
+
+	/* Check that none of the action args that are used as source for this
+	 * DMA transfer are not used as source in any other mov instruction.
+	 */
+	for (j = src_field_id; j < src_field_id + h->st->n_fields; j++) {
+		uint32_t n_users;
+
+		n_users = action_arg_src_mov_count(a,
+						   j,
+						   instructions,
+						   instruction_data,
+						   n_instructions);
+		if (n_users > 1)
+			return 0;
+	}
+
+	*n_pattern_instr = 1 + i;
+	return 1;
+}
+
+static void
+instr_pattern_mov_all_validate_replace(struct rte_swx_pipeline *p,
+				       struct action *a,
+				       struct instruction *instr,
+				       struct instruction_data *data,
+				       uint32_t n_instr)
+{
+	struct header *h;
+	uint32_t src_field_id, src_offset, i;
+
+	/* Read from the instructions before they are modified. */
+	h = header_find_by_struct_id(p, instr[0].mov.dst.struct_id);
+	if (!h)
+		return;
+
+	for (src_field_id = 0; src_field_id < a->st->n_fields; src_field_id++)
+		if (instr[0].mov.src.offset == a->st->fields[src_field_id].offset / 8)
+			break;
+
+	if (src_field_id == a->st->n_fields)
+		return;
+
+	src_offset = instr[0].mov.src.offset;
+
+	/* Modify the instructions. */
+	instr[0].type = INSTR_DMA_HT;
+	instr[0].dma.dst.header_id[0] = h->id;
+	instr[0].dma.dst.struct_id[0] = h->struct_id;
+	instr[0].dma.src.offset[0] = (uint8_t)src_offset;
+	instr[0].dma.n_bytes[0] = h->st->n_bits / 8;
+
+	for (i = 1; i < n_instr; i++)
+		data[i].invalid = 1;
+
+	/* Update the endianness of the action arguments to header endianness. */
+	for (i = 0; i < h->st->n_fields; i++)
+		a->args_endianness[src_field_id + i] = 1;
+}
+
+static uint32_t
+instr_pattern_mov_all_validate_optimize(struct rte_swx_pipeline *p,
+					struct action *a,
+					struct instruction *instructions,
+					struct instruction_data *instruction_data,
+					uint32_t n_instructions)
+{
+	uint32_t i;
+
+	if (!a || !a->st)
+		return n_instructions;
+
+	for (i = 0; i < n_instructions; ) {
+		struct instruction *instr = &instructions[i];
+		struct instruction_data *data = &instruction_data[i];
+		uint32_t n_instr = 0;
+		int detected;
+
+		/* Mov all + validate. */
+		detected = instr_pattern_mov_all_validate_search(p,
+								 a,
+								 instr,
+								 data,
+								 n_instructions - i,
+								 instructions,
+								 instruction_data,
+								 n_instructions,
+								 &n_instr);
+		if (detected) {
+			instr_pattern_mov_all_validate_replace(p, a, instr, data, n_instr);
+			i += n_instr;
+			continue;
+		}
+
+		/* No pattern starting at the current instruction. */
+		i++;
+	}
+
+	/* Eliminate the invalid instructions that have been optimized out. */
+	n_instructions = instr_compact(instructions,
+				       instruction_data,
+				       n_instructions);
+
+	return n_instructions;
+}
+
 static int
 instr_pattern_dma_many_search(struct instruction *instr,
 			      struct instruction_data *data,
@@ -8378,7 +8526,9 @@  instr_pattern_dma_many_optimize(struct instruction *instructions,
 }
 
 static uint32_t
-instr_optimize(struct instruction *instructions,
+instr_optimize(struct rte_swx_pipeline *p,
+	       struct action *a,
+	       struct instruction *instructions,
 	       struct instruction_data *instruction_data,
 	       uint32_t n_instructions)
 {
@@ -8392,6 +8542,13 @@  instr_optimize(struct instruction *instructions,
 							     instruction_data,
 							     n_instructions);
 
+	/* Mov all + validate. */
+	n_instructions = instr_pattern_mov_all_validate_optimize(p,
+								 a,
+								 instructions,
+								 instruction_data,
+								 n_instructions);
+
 	/* DMA many. */
 	n_instructions = instr_pattern_dma_many_optimize(instructions,
 							 instruction_data,
@@ -8453,7 +8610,7 @@  instruction_config(struct rte_swx_pipeline *p,
 	if (err)
 		goto error;
 
-	n_instructions = instr_optimize(instr, data, n_instructions);
+	n_instructions = instr_optimize(p, a, instr, data, n_instructions);
 
 	err = instr_jmp_resolve(instr, data, n_instructions);
 	if (err)
@@ -8742,6 +8899,13 @@  rte_swx_pipeline_action_config(struct rte_swx_pipeline *p,
 	/* Node allocation. */
 	a = calloc(1, sizeof(struct action));
 	CHECK(a, ENOMEM);
+	if (args_struct_type) {
+		a->args_endianness = calloc(args_struct_type->n_fields, sizeof(int));
+		if (!a->args_endianness) {
+			free(a);
+			CHECK(0, ENOMEM);
+		}
+	}
 
 	/* Node initialization. */
 	strcpy(a->name, name);
@@ -8751,6 +8915,7 @@  rte_swx_pipeline_action_config(struct rte_swx_pipeline *p,
 	/* Instruction translation. */
 	err = instruction_config(p, a, instructions, n_instructions);
 	if (err) {
+		free(a->args_endianness);
 		free(a);
 		return err;
 	}
@@ -8802,6 +8967,40 @@  action_free(struct rte_swx_pipeline *p)
 	}
 }
 
+static uint32_t
+action_arg_src_mov_count(struct action *a,
+			 uint32_t arg_id,
+			 struct instruction *instructions,
+			 struct instruction_data *instruction_data,
+			 uint32_t n_instructions)
+{
+	uint32_t offset, n_users = 0, i;
+
+	if (!a->st ||
+	    (arg_id >= a->st->n_fields) ||
+	    !instructions ||
+	    !instruction_data ||
+	    !n_instructions)
+		return 0;
+
+	offset = a->st->fields[arg_id].offset / 8;
+
+	for (i = 0; i < n_instructions; i++) {
+		struct instruction *instr = &instructions[i];
+		struct instruction_data *data = &instruction_data[i];
+
+		if (data->invalid ||
+		    ((instr->type != INSTR_MOV) && (instr->type != INSTR_MOV_HM)) ||
+		    instr->mov.src.struct_id ||
+		    (instr->mov.src.offset != offset))
+			continue;
+
+		n_users++;
+	}
+
+	return n_users;
+}
+
 /*
  * Table.
  */
@@ -9898,6 +10097,7 @@  rte_swx_ctl_action_arg_info_get(struct rte_swx_pipeline *p,
 	arg = &a->st->fields[action_arg_id];
 	strcpy(action_arg->name, arg->name);
 	action_arg->n_bits = arg->n_bits;
+	action_arg->is_network_byte_order = a->args_endianness[action_arg_id];
 
 	return 0;
 }
diff --git a/lib/librte_pipeline/rte_swx_pipeline.h b/lib/librte_pipeline/rte_swx_pipeline.h
index 156b1fd67..feeb10a5c 100644
--- a/lib/librte_pipeline/rte_swx_pipeline.h
+++ b/lib/librte_pipeline/rte_swx_pipeline.h
@@ -406,10 +406,6 @@  rte_swx_pipeline_packet_metadata_register(struct rte_swx_pipeline *p,
  *<pre>+------------+----------------------+-------------------+------+--------+</pre>
  *<pre>| mov        | dst = src            | mov dst src       | HMEF | HMEFTI |</pre>
  *<pre>+------------+----------------------+-------------------+------+--------+</pre>
- *<pre>| dma        | memcpy(h.hdr,        | dma h.hdr t.field | hdr  | T      |</pre>
- *<pre>|            |    &t.field,         |                   |      |        |</pre>
- *<pre>|            |    sizeof(h.hdr)     |                   |      |        |</pre>
- *<pre>+------------+----------------------+-------------------+------+--------+</pre>
  *<pre>| add        | dst += src           | add dst src       | HMEF | HMEFTI |</pre>
  *<pre>+------------+----------------------+-------------------+------+--------+</pre>
  *<pre>| sub        | dst -= src           | add dst src       | HMEF | HMEFTI |</pre>