[v3,1/8] ethdev: add IPv6 routing extension header definition

Message ID 20230130035941.1495874-2-rongweil@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series add IPv6 routing extension support |

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/loongarch-compilation warning apply patch failure
ci/iol-testing warning apply patch failure

Commit Message

Rongwei Liu Jan. 30, 2023, 3:59 a.m. UTC
  Add IPv6 routing extension header definition and no
TLV support for now.

At rte_flow layer, there are new items defined for matching
type/nexthdr/segments_left field.

Add command line support for IPv6 routing extension header
matching: type/nexthdr/segment_list.

Signed-off-by: Rongwei Liu <rongweil@nvidia.com>
Acked-by: Ori Kam <orika@nvidia.com>
---
 app/test-pmd/cmdline_flow.c            | 46 ++++++++++++++++++++++++++
 doc/guides/prog_guide/rte_flow.rst     |  9 +++++
 doc/guides/rel_notes/release_23_03.rst |  9 +++++
 lib/ethdev/rte_flow.c                  | 19 +++++++++++
 lib/ethdev/rte_flow.h                  | 19 +++++++++++
 lib/net/rte_ip.h                       | 21 ++++++++++++
 6 files changed, 123 insertions(+)
  

Comments

Stephen Hemminger Jan. 30, 2023, 4:47 p.m. UTC | #1
On Mon, 30 Jan 2023 05:59:33 +0200
Rongwei Liu <rongweil@nvidia.com> wrote:

>  
> +/**
> + * IPv6 Routing Extension Header
> + */
> +struct rte_ipv6_routing_ext {
> +	uint8_t next_hdr;			/**< Protocol, next header. */
> +	uint8_t hdr_len;			/**< Header length. */
> +	uint8_t type;				/**< Extension header type. */
> +	uint8_t segments_left;			/**< Valid segments number. */
> +	__extension__
> +	union {
> +		rte_be32_t flags;
> +		struct {
> +			uint8_t last_entry;	/**< The last_entry field of SRH */
> +			uint8_t flag;		/**< Packet flag. */
> +			rte_be16_t tag;		/**< Packet tag. */
> +		};
> +	};
> +	__extension__
> +	rte_be32_t segments[0];			/**< Each hop IPv6 address. */

Use flex array rather than zero size.
Zero size arrays cause warnings with later compilers.
  
Stephen Hemminger Jan. 30, 2023, 4:50 p.m. UTC | #2
On Mon, 30 Jan 2023 05:59:33 +0200
Rongwei Liu <rongweil@nvidia.com> wrote:

> +static size_t
> +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)

> +{
> +	struct rte_flow_item_ipv6_routing_ext *dst = buf;
> +	const struct rte_flow_item_ipv6_routing_ext *src = data;
> +	size_t len;
> +
> +	if (src->hdr.hdr_len)
> +		len = src->hdr.hdr_len << 3;
> +	else
> +		len = src->hdr.segments_left << 4;
> +	if (dst == NULL)
> +		return 0;
> +	rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)), src->hdr.segments, len);
> +	return len;

Why use rte_memcpy for such a small size? Please just use normal memcpy which
will cause more compiler and static scan checking.

That cast is unnecessary in C because "segments" is an array and any valid
pointer type can be passed as void *.
  
Rongwei Liu Jan. 31, 2023, 2:03 a.m. UTC | #3
HI Stephen:

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 00:48
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> >
> > +/**
> > + * IPv6 Routing Extension Header
> > + */
> > +struct rte_ipv6_routing_ext {
> > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > +     uint8_t hdr_len;                        /**< Header length. */
> > +     uint8_t type;                           /**< Extension header type. */
> > +     uint8_t segments_left;                  /**< Valid segments number. */
> > +     __extension__
> > +     union {
> > +             rte_be32_t flags;
> > +             struct {
> > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > +                     uint8_t flag;           /**< Packet flag. */
> > +                     rte_be16_t tag;         /**< Packet tag. */
> > +             };
> > +     };
> > +     __extension__
> > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
> 
> Use flex array rather than zero size.
> Zero size arrays cause warnings with later compilers.
Sure. Thanks.
  
Rongwei Liu Jan. 31, 2023, 2:05 a.m. UTC | #4
HI Stephen:

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 00:50
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> > +static size_t
> > +rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
> 
> > +{
> > +     struct rte_flow_item_ipv6_routing_ext *dst = buf;
> > +     const struct rte_flow_item_ipv6_routing_ext *src = data;
> > +     size_t len;
> > +
> > +     if (src->hdr.hdr_len)
> > +             len = src->hdr.hdr_len << 3;
> > +     else
> > +             len = src->hdr.segments_left << 4;
> > +     if (dst == NULL)
> > +             return 0;
> > +     rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)), src->hdr.segments,
> len);
> > +     return len;
> 
> Why use rte_memcpy for such a small size? Please just use normal memcpy
> which will cause more compiler and static scan checking.
> 
Following existing routine, rte_flow_item_***_conv(). Change to memcpy() in the next version
> That cast is unnecessary in C because "segments" is an array and any valid
> pointer type can be passed as void *.
Sure
  
Rongwei Liu Jan. 31, 2023, 2:27 a.m. UTC | #5
HI Stephen

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 00:48
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> >
> > +/**
> > + * IPv6 Routing Extension Header
> > + */
> > +struct rte_ipv6_routing_ext {
> > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > +     uint8_t hdr_len;                        /**< Header length. */
> > +     uint8_t type;                           /**< Extension header type. */
> > +     uint8_t segments_left;                  /**< Valid segments number. */
> > +     __extension__
> > +     union {
> > +             rte_be32_t flags;
> > +             struct {
> > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > +                     uint8_t flag;           /**< Packet flag. */
> > +                     rte_be16_t tag;         /**< Packet tag. */
> > +             };
> > +     };
> > +     __extension__
> > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
> 
> Use flex array rather than zero size.
> Zero size arrays cause warnings with later compilers.
Using flex array helps improve this network header definition but caused warning in the rte_flow_item_**
struct rte_flow_item_ipv6_routing_ext {
       struct rte_ipv6_routing_ext hdr;                                                                                                                                                                                                                    
}; 
"invalid use of structure with flexible array member [-Werror=pedantic]"
  
Stephen Hemminger Jan. 31, 2023, 2:55 a.m. UTC | #6
On Tue, 31 Jan 2023 02:27:56 +0000
Rongwei Liu <rongweil@nvidia.com> wrote:

> HI Stephen
> 
> BR
> Rongwei
> 
> > -----Original Message-----
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > Sent: Tuesday, January 31, 2023 00:48
> > To: Rongwei Liu <rongweil@nvidia.com>
> > Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> > <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> > Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> > <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> > Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> > <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> > dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> > Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> > definition
> > 
> > External email: Use caution opening links or attachments
> > 
> > 
> > On Mon, 30 Jan 2023 05:59:33 +0200
> > Rongwei Liu <rongweil@nvidia.com> wrote:
> >   
> > >
> > > +/**
> > > + * IPv6 Routing Extension Header
> > > + */
> > > +struct rte_ipv6_routing_ext {
> > > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > > +     uint8_t hdr_len;                        /**< Header length. */
> > > +     uint8_t type;                           /**< Extension header type. */
> > > +     uint8_t segments_left;                  /**< Valid segments number. */
> > > +     __extension__
> > > +     union {
> > > +             rte_be32_t flags;
> > > +             struct {
> > > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > > +                     uint8_t flag;           /**< Packet flag. */
> > > +                     rte_be16_t tag;         /**< Packet tag. */
> > > +             };
> > > +     };
> > > +     __extension__
> > > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */  
> > 
> > Use flex array rather than zero size.
> > Zero size arrays cause warnings with later compilers.  
> Using flex array helps improve this network header definition but caused warning in the rte_flow_item_**
> struct rte_flow_item_ipv6_routing_ext {
>        struct rte_ipv6_routing_ext hdr;                                                                                                                                                                                                                    
> }; 
> "invalid use of structure with flexible array member [-Werror=pedantic]"

Not sure, only Nvidia/Mellanox messes with pedantic
  
Stephen Hemminger Jan. 31, 2023, 3:02 a.m. UTC | #7
On Mon, 30 Jan 2023 05:59:33 +0200
Rongwei Liu <rongweil@nvidia.com> wrote:

> +/**
> + * @warning
> + * @b EXPERIMENTAL: this structure may change without prior notice
> + *
> + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> + *
> + * Matches an IPv6 routing extension header.
> + */
> +struct rte_flow_item_ipv6_routing_ext {
> +	struct rte_ipv6_routing_ext hdr;
> +};

The problem with nesting a variable length structure inside
another structure is not allowed.

The issue is that the applicaiton would have to pass a variable
length structure in for the flow definition. The flow item is
variable length for this type? all the others are fixed length.

One option would be to get rid of the wrapper structure.
  
Rongwei Liu Jan. 31, 2023, 3:20 a.m. UTC | #8
HI Stephen

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 10:56
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Tue, 31 Jan 2023 02:27:56 +0000
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> > HI Stephen
> >
> > BR
> > Rongwei
> >
> > > -----Original Message-----
> > > From: Stephen Hemminger <stephen@networkplumber.org>
> > > Sent: Tuesday, January 31, 2023 00:48
> > > To: Rongwei Liu <rongweil@nvidia.com>
> > > Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> > > <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> > > Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> > > <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> > > Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> > > <andrew.rybchenko@oktetlabs.ru>; Olivier Matz
> > > <olivier.matz@6wind.com>; dev@dpdk.org; Raslan Darawsheh
> > > <rasland@nvidia.com>
> > > Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension
> > > header definition
> > >
> > > External email: Use caution opening links or attachments
> > >
> > >
> > > On Mon, 30 Jan 2023 05:59:33 +0200
> > > Rongwei Liu <rongweil@nvidia.com> wrote:
> > >
> > > >
> > > > +/**
> > > > + * IPv6 Routing Extension Header
> > > > + */
> > > > +struct rte_ipv6_routing_ext {
> > > > +     uint8_t next_hdr;                       /**< Protocol, next header. */
> > > > +     uint8_t hdr_len;                        /**< Header length. */
> > > > +     uint8_t type;                           /**< Extension header type. */
> > > > +     uint8_t segments_left;                  /**< Valid segments number. */
> > > > +     __extension__
> > > > +     union {
> > > > +             rte_be32_t flags;
> > > > +             struct {
> > > > +                     uint8_t last_entry;     /**< The last_entry field of SRH */
> > > > +                     uint8_t flag;           /**< Packet flag. */
> > > > +                     rte_be16_t tag;         /**< Packet tag. */
> > > > +             };
> > > > +     };
> > > > +     __extension__
> > > > +     rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
> > >
> > > Use flex array rather than zero size.
> > > Zero size arrays cause warnings with later compilers.
> > Using flex array helps improve this network header definition but
> > caused warning in the rte_flow_item_** struct
> rte_flow_item_ipv6_routing_ext {
> >        struct rte_ipv6_routing_ext hdr; }; "invalid use of structure
> > with flexible array member [-Werror=pedantic]"
> 
> Not sure, only Nvidia/Mellanox messes with pedantic
This is caused by failsafe driver.
In file included from ../drivers/net/failsafe/failsafe_ether.c:8:
../lib/ethdev/rte_flow.h:892:44: error: invalid use of structure with flexible array member [-Werror=pedantic]
  __extension__ struct rte_ipv6_routing_ext hdr;
                                            ^~~
  
Rongwei Liu Jan. 31, 2023, 3:24 a.m. UTC | #9
Hi Stephen

BR
Rongwei

> -----Original Message-----
> From: Stephen Hemminger <stephen@networkplumber.org>
> Sent: Tuesday, January 31, 2023 11:02
> To: Rongwei Liu <rongweil@nvidia.com>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>; Olivier Matz <olivier.matz@6wind.com>;
> dev@dpdk.org; Raslan Darawsheh <rasland@nvidia.com>
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> External email: Use caution opening links or attachments
> 
> 
> On Mon, 30 Jan 2023 05:59:33 +0200
> Rongwei Liu <rongweil@nvidia.com> wrote:
> 
> > +/**
> > + * @warning
> > + * @b EXPERIMENTAL: this structure may change without prior notice
> > + *
> > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > + *
> > + * Matches an IPv6 routing extension header.
> > + */
> > +struct rte_flow_item_ipv6_routing_ext {
> > +     struct rte_ipv6_routing_ext hdr; };
> 
> The problem with nesting a variable length structure inside another structure
> is not allowed.
> 
> The issue is that the applicaiton would have to pass a variable length structure
> in for the flow definition. The flow item is variable length for this type? all the
> others are fixed length.
> 
Yeah, segments_left is uint8 per definition. RFC doesn't set an upper limitation.
It stands for intermediate routing nodes between src and dst nodes.
> One option would be to get rid of the wrapper structure.
Yeah, it works. @Andrew Rybchenko  Can you share your preference here?
  
Rongwei Liu Jan. 31, 2023, 9:18 a.m. UTC | #10
HI Stephen:

BR
Rongwei

> -----Original Message-----
> From: Rongwei Liu
> Sent: Tuesday, January 31, 2023 11:25
> To: Stephen Hemminger <stephen@networkplumber.org>; Andrew Rybchenko
> <andrew.rybchenko@oktetlabs.ru>
> Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> Ferruh Yigit <ferruh.yigit@amd.com>; Olivier Matz
> <olivier.matz@6wind.com>; dev@dpdk.org; Raslan Darawsheh
> <rasland@nvidia.com>
> Subject: RE: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> Hi Stephen
> 
> BR
> Rongwei
> 
> > -----Original Message-----
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > Sent: Tuesday, January 31, 2023 11:02
> > To: Rongwei Liu <rongweil@nvidia.com>
> > Cc: Matan Azrad <matan@nvidia.com>; Slava Ovsiienko
> > <viacheslavo@nvidia.com>; Ori Kam <orika@nvidia.com>; NBU-Contact-
> > Thomas Monjalon (EXTERNAL) <thomas@monjalon.net>; Aman Singh
> > <aman.deep.singh@intel.com>; Yuying Zhang <yuying.zhang@intel.com>;
> > Ferruh Yigit <ferruh.yigit@amd.com>; Andrew Rybchenko
> > <andrew.rybchenko@oktetlabs.ru>; Olivier Matz
> > <olivier.matz@6wind.com>; dev@dpdk.org; Raslan Darawsheh
> > <rasland@nvidia.com>
> > Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> > definition
> >
> > External email: Use caution opening links or attachments
> >
> >
> > On Mon, 30 Jan 2023 05:59:33 +0200
> > Rongwei Liu <rongweil@nvidia.com> wrote:
> >
> > > +/**
> > > + * @warning
> > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > + *
> > > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > > + *
> > > + * Matches an IPv6 routing extension header.
> > > + */
> > > +struct rte_flow_item_ipv6_routing_ext {
> > > +     struct rte_ipv6_routing_ext hdr; };
> >
> > The problem with nesting a variable length structure inside another
> > structure is not allowed.
> >
> > The issue is that the applicaiton would have to pass a variable length
> > structure in for the flow definition. The flow item is variable length
> > for this type? all the others are fixed length.
> >
> Yeah, segments_left is uint8 per definition. RFC doesn't set an upper limitation.
> It stands for intermediate routing nodes between src and dst nodes.
> > One option would be to get rid of the wrapper structure.
> Yeah, it works. @Andrew Rybchenko  Can you share your preference here?
I want to propose "moving flex array" out of the "struct rte_ipv6_routing_ext " and present in " struct rte_flow_item_ipv6_routing_ext"
Sounds good?
  
Thomas Monjalon Jan. 31, 2023, 9:42 a.m. UTC | #11
31/01/2023 10:18, Rongwei Liu:
> From: Rongwei Liu
> > From: Stephen Hemminger <stephen@networkplumber.org>
> > > Rongwei Liu <rongweil@nvidia.com> wrote:
> > >
> > > > +/**
> > > > + * @warning
> > > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > > + *
> > > > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > > > + *
> > > > + * Matches an IPv6 routing extension header.
> > > > + */
> > > > +struct rte_flow_item_ipv6_routing_ext {
> > > > +     struct rte_ipv6_routing_ext hdr; };
> > >
> > > The problem with nesting a variable length structure inside another
> > > structure is not allowed.
> > >
> > > The issue is that the applicaiton would have to pass a variable length
> > > structure in for the flow definition. The flow item is variable length
> > > for this type? all the others are fixed length.
> > >
> > Yeah, segments_left is uint8 per definition. RFC doesn't set an upper limitation.
> > It stands for intermediate routing nodes between src and dst nodes.
> > > One option would be to get rid of the wrapper structure.
> > Yeah, it works. @Andrew Rybchenko  Can you share your preference here?
> I want to propose "moving flex array" out of the "struct rte_ipv6_routing_ext " and present in " struct rte_flow_item_ipv6_routing_ext"
> Sounds good?

For Geneve, we have defined a separate flow item: rte_flow_item_geneve_opt.
I'm OK to move the optional fields in the flow item.
This is what you did in v4.
  
Ori Kam Jan. 31, 2023, 11:42 a.m. UTC | #12
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, 31 January 2023 11:43
> Subject: Re: [PATCH v3 1/8] ethdev: add IPv6 routing extension header
> definition
> 
> 31/01/2023 10:18, Rongwei Liu:
> > From: Rongwei Liu
> > > From: Stephen Hemminger <stephen@networkplumber.org>
> > > > Rongwei Liu <rongweil@nvidia.com> wrote:
> > > >
> > > > > +/**
> > > > > + * @warning
> > > > > + * @b EXPERIMENTAL: this structure may change without prior notice
> > > > > + *
> > > > > + * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
> > > > > + *
> > > > > + * Matches an IPv6 routing extension header.
> > > > > + */
> > > > > +struct rte_flow_item_ipv6_routing_ext {
> > > > > +     struct rte_ipv6_routing_ext hdr; };
> > > >
> > > > The problem with nesting a variable length structure inside another
> > > > structure is not allowed.
> > > >
> > > > The issue is that the applicaiton would have to pass a variable length
> > > > structure in for the flow definition. The flow item is variable length
> > > > for this type? all the others are fixed length.
> > > >
> > > Yeah, segments_left is uint8 per definition. RFC doesn't set an upper
> limitation.
> > > It stands for intermediate routing nodes between src and dst nodes.
> > > > One option would be to get rid of the wrapper structure.
> > > Yeah, it works. @Andrew Rybchenko  Can you share your preference
> here?
> > I want to propose "moving flex array" out of the "struct
> rte_ipv6_routing_ext " and present in " struct
> rte_flow_item_ipv6_routing_ext"
> > Sounds good?
> 
> For Geneve, we have defined a separate flow item:
> rte_flow_item_geneve_opt.
> I'm OK to move the optional fields in the flow item.
> This is what you did in v4.
> 

I also think we should just drop the  rte_be32_t segments[0];                 /**< Each hop IPv6 address. */
In any case application must allocate the correct size so maybe we can just remove it.

Best,
Ori
> 
> 
>
  

Patch

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 88108498e0..7a8516829c 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -298,6 +298,10 @@  enum index {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_ICMP,
 	ITEM_ICMP_TYPE,
 	ITEM_ICMP_CODE,
@@ -1326,6 +1330,7 @@  static const enum index next_item[] = {
 	ITEM_ARP_ETH_IPV4,
 	ITEM_IPV6_EXT,
 	ITEM_IPV6_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
 	ITEM_ICMP6,
 	ITEM_ICMP6_ND_NS,
 	ITEM_ICMP6_ND_NA,
@@ -1435,6 +1440,15 @@  static const enum index item_ipv6[] = {
 	ITEM_IPV6_SRC,
 	ITEM_IPV6_DST,
 	ITEM_IPV6_HAS_FRAG_EXT,
+	ITEM_IPV6_ROUTING_EXT,
+	ITEM_NEXT,
+	ZERO,
+};
+
+static const enum index item_ipv6_routing_ext[] = {
+	ITEM_IPV6_ROUTING_EXT_TYPE,
+	ITEM_IPV6_ROUTING_EXT_NEXT_HDR,
+	ITEM_IPV6_ROUTING_EXT_SEG_LEFT,
 	ITEM_NEXT,
 	ZERO,
 };
@@ -3844,6 +3858,38 @@  static const struct token token_list[] = {
 		.args = ARGS(ARGS_ENTRY_BF(struct rte_flow_item_ipv6,
 					   has_frag_ext, 1)),
 	},
+	[ITEM_IPV6_ROUTING_EXT] = {
+		.name = "ipv6_routing_ext",
+		.help = "match IPv6 routing extension header",
+		.priv = PRIV_ITEM(IPV6_ROUTING_EXT,
+				  sizeof(struct rte_flow_item_ipv6_routing_ext)),
+		.next = NEXT(item_ipv6_routing_ext),
+		.call = parse_vc,
+	},
+	[ITEM_IPV6_ROUTING_EXT_TYPE] = {
+		.name = "ext_type",
+		.help = "match IPv6 routing extension header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.type)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_NEXT_HDR] = {
+		.name = "ext_next_hdr",
+		.help = "match IPv6 routing extension header next header type",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.next_hdr)),
+	},
+	[ITEM_IPV6_ROUTING_EXT_SEG_LEFT] = {
+		.name = "ext_seg_left",
+		.help = "match IPv6 routing extension header segment left",
+		.next = NEXT(item_ipv6_routing_ext, NEXT_ENTRY(COMMON_UNSIGNED),
+			     item_param),
+		.args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_ipv6_routing_ext,
+					     hdr.segments_left)),
+	},
 	[ITEM_ICMP] = {
 		.name = "icmp",
 		.help = "match ICMP header",
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 3e6242803d..602fab29d3 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -1544,6 +1544,15 @@  Matches Color Marker set by a Meter.
 
 - ``color``: Metering color marker.
 
+Item: ``IPV6_ROUTING_EXT``
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches IPv6 routing extension header.
+
+- ``next_hdr``: Next layer header type.
+- ``type``: IPv6 routing extension header type.
+- ``segments_left``: How many IPv6 destination addresses carries on.
+
 Actions
 ~~~~~~~
 
diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst
index b8c5b68d6c..8f482301f7 100644
--- a/doc/guides/rel_notes/release_23_03.rst
+++ b/doc/guides/rel_notes/release_23_03.rst
@@ -55,6 +55,11 @@  New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* **Added rte_flow support for matching IPv6 routing extension header fields.**
+
+  Added ``ipv6_routing_ext`` items in rte_flow to match IPv6 routing extension
+  header.
+
 
 Removed Items
 -------------
@@ -84,6 +89,10 @@  API Changes
    Also, make sure to start the actual text at the margin.
    =======================================================
 
+* net: added a new structure:
+
+    - IPv6 routing extension header ``rte_ipv6_routing_ext``.
+
 
 ABI Changes
 -----------
diff --git a/lib/ethdev/rte_flow.c b/lib/ethdev/rte_flow.c
index 7d0c24366c..5c423db160 100644
--- a/lib/ethdev/rte_flow.c
+++ b/lib/ethdev/rte_flow.c
@@ -76,6 +76,23 @@  rte_flow_item_flex_conv(void *buf, const void *data)
 	return src->length;
 }
 
+static size_t
+rte_flow_item_ipv6_routing_ext_conv(void *buf, const void *data)
+{
+	struct rte_flow_item_ipv6_routing_ext *dst = buf;
+	const struct rte_flow_item_ipv6_routing_ext *src = data;
+	size_t len;
+
+	if (src->hdr.hdr_len)
+		len = src->hdr.hdr_len << 3;
+	else
+		len = src->hdr.segments_left << 4;
+	if (dst == NULL)
+		return 0;
+	rte_memcpy((void *)((uintptr_t)(dst->hdr.segments)), src->hdr.segments, len);
+	return len;
+}
+
 /** Generate flow_item[] entry. */
 #define MK_FLOW_ITEM(t, s) \
 	[RTE_FLOW_ITEM_TYPE_ ## t] = { \
@@ -157,6 +174,8 @@  static const struct rte_flow_desc_data rte_flow_desc_item[] = {
 	MK_FLOW_ITEM(L2TPV2, sizeof(struct rte_flow_item_l2tpv2)),
 	MK_FLOW_ITEM(PPP, sizeof(struct rte_flow_item_ppp)),
 	MK_FLOW_ITEM(METER_COLOR, sizeof(struct rte_flow_item_meter_color)),
+	MK_FLOW_ITEM_FN(IPV6_ROUTING_EXT, sizeof(struct rte_flow_item_ipv6_routing_ext),
+			rte_flow_item_ipv6_routing_ext_conv),
 };
 
 /** Generate flow_action[] entry. */
diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h
index b60987db4b..9b9018cba2 100644
--- a/lib/ethdev/rte_flow.h
+++ b/lib/ethdev/rte_flow.h
@@ -624,6 +624,13 @@  enum rte_flow_item_type {
 	 * See struct rte_flow_item_meter_color.
 	 */
 	RTE_FLOW_ITEM_TYPE_METER_COLOR,
+
+	/**
+	 * Matches the presence of IPv6 routing extension header.
+	 *
+	 * @see struct rte_flow_item_ipv6_routing_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT,
 };
 
 /**
@@ -873,6 +880,18 @@  struct rte_flow_item_ipv6 {
 	uint32_t reserved:23;
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ITEM_TYPE_IPV6_ROUTING_EXT.
+ *
+ * Matches an IPv6 routing extension header.
+ */
+struct rte_flow_item_ipv6_routing_ext {
+	struct rte_ipv6_routing_ext hdr;
+};
+
 /** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
 #ifndef __cplusplus
 static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
diff --git a/lib/net/rte_ip.h b/lib/net/rte_ip.h
index 9c8e8206f0..56c151372a 100644
--- a/lib/net/rte_ip.h
+++ b/lib/net/rte_ip.h
@@ -539,6 +539,27 @@  struct rte_ipv6_hdr {
 	uint8_t  dst_addr[16];	/**< IP address of destination host(s). */
 } __rte_packed;
 
+/**
+ * IPv6 Routing Extension Header
+ */
+struct rte_ipv6_routing_ext {
+	uint8_t next_hdr;			/**< Protocol, next header. */
+	uint8_t hdr_len;			/**< Header length. */
+	uint8_t type;				/**< Extension header type. */
+	uint8_t segments_left;			/**< Valid segments number. */
+	__extension__
+	union {
+		rte_be32_t flags;
+		struct {
+			uint8_t last_entry;	/**< The last_entry field of SRH */
+			uint8_t flag;		/**< Packet flag. */
+			rte_be16_t tag;		/**< Packet tag. */
+		};
+	};
+	__extension__
+	rte_be32_t segments[0];			/**< Each hop IPv6 address. */
+} __rte_packed;
+
 /* IPv6 vtc_flow: IPv / TC / flow_label */
 #define RTE_IPV6_HDR_FL_SHIFT 0
 #define RTE_IPV6_HDR_TC_SHIFT 20