[02/10] ethdev: add IPv6 fragment extension header item

Message ID 3b2c7f074e245db507f9b21d28dbe68b87051515.1601474841.git.dekelp@nvidia.com (mailing list archive)
State Superseded, archived
Delegated to: Ferruh Yigit
Headers
Series support match on L3 fragmented packets |

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Dekel Peled Sept. 30, 2020, 2:10 p.m. UTC
Applications handling fragmented IPv6 packets need to match on IPv6
fragment extension header, in order to identify the fragments order
and location in the packet.
This patch introduces the IPv6 fragment extension header item,
proposed in [1].

Relevant definitions are moved from lib/librte_ip_frag/rte_ip_frag.h
to lib/librte_net/rte_ip.h, as they are needed for IPv6 header handling.
struct ipv6_extension_fragment renamed to rte_ipv6_fragment_ext to
adapt it to the common naming convention.

Default mask is not defined, since all fields are optional.

[1] http://mails.dpdk.org/archives/dev/2020-March/160255.html

Signed-off-by: Dekel Peled <dekelp@nvidia.com>
---
 doc/guides/prog_guide/rte_flow.rst | 16 ++++++++++++++--
 lib/librte_ethdev/rte_flow.c       |  1 +
 lib/librte_ethdev/rte_flow.h       | 21 +++++++++++++++++++++
 lib/librte_ip_frag/rte_ip_frag.h   | 26 ++------------------------
 lib/librte_net/rte_ip.h            | 26 ++++++++++++++++++++++++--
 5 files changed, 62 insertions(+), 28 deletions(-)
  

Comments

Ori Kam Sept. 30, 2020, 2:55 p.m. UTC | #1
> -----Original Message-----
> From: Dekel Peled <dekelp@nvidia.com>
> Sent: Wednesday, September 30, 2020 5:10 PM
> Subject: [PATCH 02/10] ethdev: add IPv6 fragment extension header item
> 
> Applications handling fragmented IPv6 packets need to match on IPv6
> fragment extension header, in order to identify the fragments order
> and location in the packet.
> This patch introduces the IPv6 fragment extension header item,
> proposed in [1].
> 
> Relevant definitions are moved from lib/librte_ip_frag/rte_ip_frag.h
> to lib/librte_net/rte_ip.h, as they are needed for IPv6 header handling.
> struct ipv6_extension_fragment renamed to rte_ipv6_fragment_ext to
> adapt it to the common naming convention.
> 
> Default mask is not defined, since all fields are optional.
> 
> [1]
> https://nam11.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmails.dpd
> k.org%2Farchives%2Fdev%2F2020-
> March%2F160255.html&amp;data=02%7C01%7Corika%40nvidia.com%7C52959
> fd24ed2489868e308d8654abe56%7C43083d15727340c1b7db39efd9ccc17a%7C
> 0%7C0%7C637370718986486792&amp;sdata=EPQFJHS9JJvzNj%2Ff9ODWt6yd3
> F1HhQiKcPX6UD1eWGA%3D&amp;reserved=0
> 
> Signed-off-by: Dekel Peled <dekelp@nvidia.com>
> ---
>  doc/guides/prog_guide/rte_flow.rst | 16 ++++++++++++++--
>  lib/librte_ethdev/rte_flow.c       |  1 +
>  lib/librte_ethdev/rte_flow.h       | 21 +++++++++++++++++++++
>  lib/librte_ip_frag/rte_ip_frag.h   | 26 ++------------------------
>  lib/librte_net/rte_ip.h            | 26 ++++++++++++++++++++++++--
>  5 files changed, 62 insertions(+), 28 deletions(-)
> 
> diff --git a/doc/guides/prog_guide/rte_flow.rst
> b/doc/guides/prog_guide/rte_flow.rst
> index 0b476da..826e45d 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -947,8 +947,8 @@ Item: ``IPV6``
>  Matches an IPv6 header.
> 
>  Dedicated flags indicate existence of specific extension headers.
> -Every type of extension header can use a dedicated pattern item, or
> -the generic `Item: IPV6_EXT`_.
> +Every type of extension header can use a dedicated pattern item,
> +for example `Item: IPV6_FRAG_EXT`_, or the generic `Item: IPV6_EXT`_.
> 
>  - ``hdr``: IPv6 header definition (``rte_ip.h``).
>  - ``hop_ext_exist``: Hop-by-Hop Options extension header exists.
> @@ -1187,6 +1187,18 @@ Normally preceded by any of:
>  - `Item: IPV6`_
>  - `Item: IPV6_EXT`_
> 
> +Item: ``IPV6_FRAG_EXT``
> +^^^^^^^^^^^^^^^^^^^^^^^
> +
> +Matches the presence of IPv6 fragment extension header.
> +
> +- ``hdr``: IPv6 fragment extension header definition (``rte_ip.h``).
> +
> +Normally preceded by any of:
> +
> +- `Item: IPV6`_
> +- `Item: IPV6_EXT`_
> +
>  Item: ``ICMP6``
>  ^^^^^^^^^^^^^^^
> 
> diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
> index f8fdd68..c1f3132 100644
> --- a/lib/librte_ethdev/rte_flow.c
> +++ b/lib/librte_ethdev/rte_flow.c
> @@ -72,6 +72,7 @@ struct rte_flow_desc_data {
>  	MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
>  	MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct
> rte_flow_item_arp_eth_ipv4)),
>  	MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)),
> +	MK_FLOW_ITEM(IPV6_FRAG_EXT, sizeof(struct
> rte_flow_item_ipv6_frag_ext)),
>  	MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
>  	MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct
> rte_flow_item_icmp6_nd_ns)),
>  	MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct
> rte_flow_item_icmp6_nd_na)),
> diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
> index 5b5bed2..1443e6a 100644
> --- a/lib/librte_ethdev/rte_flow.h
> +++ b/lib/librte_ethdev/rte_flow.h
> @@ -368,6 +368,13 @@ enum rte_flow_item_type {
>  	RTE_FLOW_ITEM_TYPE_IPV6_EXT,
> 
>  	/**
> +	 * Matches the presence of IPv6 fragment extension header.
> +	 *
> +	 * See struct rte_flow_item_ipv6_frag_ext.
> +	 */
> +	RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT,
> +
> +	/**
>  	 * Matches any ICMPv6 header.
>  	 *
>  	 * See struct rte_flow_item_icmp6.
> @@ -1188,6 +1195,20 @@ struct rte_flow_item_ipv6_ext
> rte_flow_item_ipv6_ext_mask = {
>  #endif
> 
>  /**
> + * RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT
> + *
> + * Matches the presence of IPv6 fragment extension header.
> + *
> + * Preceded by any of:
> + *
> + * - RTE_FLOW_ITEM_TYPE_IPV6
> + * - RTE_FLOW_ITEM_TYPE_IPV6_EXT
> + */
> +struct rte_flow_item_ipv6_frag_ext {
> +	struct rte_ipv6_fragment_ext hdr;
> +};
> +
> +/**
>   * RTE_FLOW_ITEM_TYPE_ICMP6
>   *
>   * Matches any ICMPv6 header.
> diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
> index 66edd7e..0bfe64b 100644
> --- a/lib/librte_ip_frag/rte_ip_frag.h
> +++ b/lib/librte_ip_frag/rte_ip_frag.h
> @@ -110,30 +110,8 @@ struct rte_ip_frag_tbl {
>  	__extension__ struct ip_frag_pkt pkt[0]; /**< hash table. */
>  };
> 
> -/** IPv6 fragment extension header */
> -#define	RTE_IPV6_EHDR_MF_SHIFT			0
> -#define	RTE_IPV6_EHDR_MF_MASK			1
> -#define	RTE_IPV6_EHDR_FO_SHIFT			3
> -#define	RTE_IPV6_EHDR_FO_MASK			(~((1 <<
> RTE_IPV6_EHDR_FO_SHIFT) - 1))
> -#define	RTE_IPV6_EHDR_FO_ALIGN			(1 <<
> RTE_IPV6_EHDR_FO_SHIFT)
> -
> -#define RTE_IPV6_FRAG_USED_MASK			\
> -	(RTE_IPV6_EHDR_MF_MASK | RTE_IPV6_EHDR_FO_MASK)
> -
> -#define RTE_IPV6_GET_MF(x)				((x) &
> RTE_IPV6_EHDR_MF_MASK)
> -#define RTE_IPV6_GET_FO(x)				((x) >>
> RTE_IPV6_EHDR_FO_SHIFT)
> -
> -#define RTE_IPV6_SET_FRAG_DATA(fo, mf)	\
> -	(((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) &
> RTE_IPV6_EHDR_MF_MASK))
> -
> -struct ipv6_extension_fragment {
> -	uint8_t next_header;            /**< Next header type */
> -	uint8_t reserved;               /**< Reserved */
> -	uint16_t frag_data;             /**< All fragmentation data */
> -	uint32_t id;                    /**< Packet ID */
> -} __rte_packed;
> -
> -
> +/* struct ipv6_extension_fragment moved to librte_net/rte_ip.h and renamed.
> */
> +#define ipv6_extension_fragment	rte_ipv6_fragment_ext
> 
>  /**
>   * Create a new IP fragmentation table.
> diff --git a/lib/librte_net/rte_ip.h b/lib/librte_net/rte_ip.h
> index fcd1eb3..3081c46 100644
> --- a/lib/librte_net/rte_ip.h
> +++ b/lib/librte_net/rte_ip.h
> @@ -456,8 +456,30 @@ struct rte_ipv6_hdr {
>  	return (uint16_t)cksum;
>  }
> 
> -/* IPv6 fragmentation header size */
> -#define RTE_IPV6_FRAG_HDR_SIZE 8
> +/** IPv6 fragment extension header. */
> +#define	RTE_IPV6_EHDR_MF_SHIFT	0
> +#define	RTE_IPV6_EHDR_MF_MASK	1
> +#define	RTE_IPV6_EHDR_FO_SHIFT	3
> +#define	RTE_IPV6_EHDR_FO_MASK	(~((1 <<
> RTE_IPV6_EHDR_FO_SHIFT) - 1))
> +#define	RTE_IPV6_EHDR_FO_ALIGN	(1 <<
> RTE_IPV6_EHDR_FO_SHIFT)
> +
> +#define RTE_IPV6_FRAG_USED_MASK	(RTE_IPV6_EHDR_MF_MASK |
> RTE_IPV6_EHDR_FO_MASK)
> +
> +#define RTE_IPV6_GET_MF(x)	((x) & RTE_IPV6_EHDR_MF_MASK)
> +#define RTE_IPV6_GET_FO(x)	((x) >> RTE_IPV6_EHDR_FO_SHIFT)
> +
> +#define RTE_IPV6_SET_FRAG_DATA(fo, mf)	\
> +	(((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) &
> RTE_IPV6_EHDR_MF_MASK))
> +
> +struct rte_ipv6_fragment_ext {
> +	uint8_t next_header;	/**< Next header type */
> +	uint8_t reserved;	/**< Reserved */
> +	rte_be16_t frag_data;	/**< All fragmentation data */
> +	rte_be32_t id;		/**< Packet ID */
> +} __rte_packed;
> +
> +/* IPv6 fragment extension header size */
> +#define RTE_IPV6_FRAG_HDR_SIZE	sizeof(struct rte_ipv6_fragment_ext)
> 
>  /**
>   * Parse next IPv6 header extension
> --
> 1.8.3.1

Acked-by: Ori Kam <orika@nvidia.com>
Thanks,
Ori
  

Patch

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 0b476da..826e45d 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -947,8 +947,8 @@  Item: ``IPV6``
 Matches an IPv6 header.
 
 Dedicated flags indicate existence of specific extension headers.
-Every type of extension header can use a dedicated pattern item, or
-the generic `Item: IPV6_EXT`_.
+Every type of extension header can use a dedicated pattern item,
+for example `Item: IPV6_FRAG_EXT`_, or the generic `Item: IPV6_EXT`_.
 
 - ``hdr``: IPv6 header definition (``rte_ip.h``).
 - ``hop_ext_exist``: Hop-by-Hop Options extension header exists.
@@ -1187,6 +1187,18 @@  Normally preceded by any of:
 - `Item: IPV6`_
 - `Item: IPV6_EXT`_
 
+Item: ``IPV6_FRAG_EXT``
+^^^^^^^^^^^^^^^^^^^^^^^
+
+Matches the presence of IPv6 fragment extension header.
+
+- ``hdr``: IPv6 fragment extension header definition (``rte_ip.h``).
+
+Normally preceded by any of:
+
+- `Item: IPV6`_
+- `Item: IPV6_EXT`_
+
 Item: ``ICMP6``
 ^^^^^^^^^^^^^^^
 
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index f8fdd68..c1f3132 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -72,6 +72,7 @@  struct rte_flow_desc_data {
 	MK_FLOW_ITEM(VXLAN_GPE, sizeof(struct rte_flow_item_vxlan_gpe)),
 	MK_FLOW_ITEM(ARP_ETH_IPV4, sizeof(struct rte_flow_item_arp_eth_ipv4)),
 	MK_FLOW_ITEM(IPV6_EXT, sizeof(struct rte_flow_item_ipv6_ext)),
+	MK_FLOW_ITEM(IPV6_FRAG_EXT, sizeof(struct rte_flow_item_ipv6_frag_ext)),
 	MK_FLOW_ITEM(ICMP6, sizeof(struct rte_flow_item_icmp6)),
 	MK_FLOW_ITEM(ICMP6_ND_NS, sizeof(struct rte_flow_item_icmp6_nd_ns)),
 	MK_FLOW_ITEM(ICMP6_ND_NA, sizeof(struct rte_flow_item_icmp6_nd_na)),
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index 5b5bed2..1443e6a 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -368,6 +368,13 @@  enum rte_flow_item_type {
 	RTE_FLOW_ITEM_TYPE_IPV6_EXT,
 
 	/**
+	 * Matches the presence of IPv6 fragment extension header.
+	 *
+	 * See struct rte_flow_item_ipv6_frag_ext.
+	 */
+	RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT,
+
+	/**
 	 * Matches any ICMPv6 header.
 	 *
 	 * See struct rte_flow_item_icmp6.
@@ -1188,6 +1195,20 @@  struct rte_flow_item_ipv6_ext rte_flow_item_ipv6_ext_mask = {
 #endif
 
 /**
+ * RTE_FLOW_ITEM_TYPE_IPV6_FRAG_EXT
+ *
+ * Matches the presence of IPv6 fragment extension header.
+ *
+ * Preceded by any of:
+ *
+ * - RTE_FLOW_ITEM_TYPE_IPV6
+ * - RTE_FLOW_ITEM_TYPE_IPV6_EXT
+ */
+struct rte_flow_item_ipv6_frag_ext {
+	struct rte_ipv6_fragment_ext hdr;
+};
+
+/**
  * RTE_FLOW_ITEM_TYPE_ICMP6
  *
  * Matches any ICMPv6 header.
diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip_frag.h
index 66edd7e..0bfe64b 100644
--- a/lib/librte_ip_frag/rte_ip_frag.h
+++ b/lib/librte_ip_frag/rte_ip_frag.h
@@ -110,30 +110,8 @@  struct rte_ip_frag_tbl {
 	__extension__ struct ip_frag_pkt pkt[0]; /**< hash table. */
 };
 
-/** IPv6 fragment extension header */
-#define	RTE_IPV6_EHDR_MF_SHIFT			0
-#define	RTE_IPV6_EHDR_MF_MASK			1
-#define	RTE_IPV6_EHDR_FO_SHIFT			3
-#define	RTE_IPV6_EHDR_FO_MASK			(~((1 << RTE_IPV6_EHDR_FO_SHIFT) - 1))
-#define	RTE_IPV6_EHDR_FO_ALIGN			(1 << RTE_IPV6_EHDR_FO_SHIFT)
-
-#define RTE_IPV6_FRAG_USED_MASK			\
-	(RTE_IPV6_EHDR_MF_MASK | RTE_IPV6_EHDR_FO_MASK)
-
-#define RTE_IPV6_GET_MF(x)				((x) & RTE_IPV6_EHDR_MF_MASK)
-#define RTE_IPV6_GET_FO(x)				((x) >> RTE_IPV6_EHDR_FO_SHIFT)
-
-#define RTE_IPV6_SET_FRAG_DATA(fo, mf)	\
-	(((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) & RTE_IPV6_EHDR_MF_MASK))
-
-struct ipv6_extension_fragment {
-	uint8_t next_header;            /**< Next header type */
-	uint8_t reserved;               /**< Reserved */
-	uint16_t frag_data;             /**< All fragmentation data */
-	uint32_t id;                    /**< Packet ID */
-} __rte_packed;
-
-
+/* struct ipv6_extension_fragment moved to librte_net/rte_ip.h and renamed. */
+#define ipv6_extension_fragment	rte_ipv6_fragment_ext
 
 /**
  * Create a new IP fragmentation table.
diff --git a/lib/librte_net/rte_ip.h b/lib/librte_net/rte_ip.h
index fcd1eb3..3081c46 100644
--- a/lib/librte_net/rte_ip.h
+++ b/lib/librte_net/rte_ip.h
@@ -456,8 +456,30 @@  struct rte_ipv6_hdr {
 	return (uint16_t)cksum;
 }
 
-/* IPv6 fragmentation header size */
-#define RTE_IPV6_FRAG_HDR_SIZE 8
+/** IPv6 fragment extension header. */
+#define	RTE_IPV6_EHDR_MF_SHIFT	0
+#define	RTE_IPV6_EHDR_MF_MASK	1
+#define	RTE_IPV6_EHDR_FO_SHIFT	3
+#define	RTE_IPV6_EHDR_FO_MASK	(~((1 << RTE_IPV6_EHDR_FO_SHIFT) - 1))
+#define	RTE_IPV6_EHDR_FO_ALIGN	(1 << RTE_IPV6_EHDR_FO_SHIFT)
+
+#define RTE_IPV6_FRAG_USED_MASK	(RTE_IPV6_EHDR_MF_MASK | RTE_IPV6_EHDR_FO_MASK)
+
+#define RTE_IPV6_GET_MF(x)	((x) & RTE_IPV6_EHDR_MF_MASK)
+#define RTE_IPV6_GET_FO(x)	((x) >> RTE_IPV6_EHDR_FO_SHIFT)
+
+#define RTE_IPV6_SET_FRAG_DATA(fo, mf)	\
+	(((fo) & RTE_IPV6_EHDR_FO_MASK) | ((mf) & RTE_IPV6_EHDR_MF_MASK))
+
+struct rte_ipv6_fragment_ext {
+	uint8_t next_header;	/**< Next header type */
+	uint8_t reserved;	/**< Reserved */
+	rte_be16_t frag_data;	/**< All fragmentation data */
+	rte_be32_t id;		/**< Packet ID */
+} __rte_packed;
+
+/* IPv6 fragment extension header size */
+#define RTE_IPV6_FRAG_HDR_SIZE	sizeof(struct rte_ipv6_fragment_ext)
 
 /**
  * Parse next IPv6 header extension