[dpdk-dev,5/5] ethdev: define default item masks in flow API

Message ID 6b75505ebd460c28b1b7c6c9191f43f4c84614d9.1484046037.git.adrien.mazarguil@6wind.com
State Accepted, archived
Delegated to: Thomas Monjalon
Headers show

Checks

Context Check Description
ci/Intel compilation success Compilation OK
ci/checkpatch success coding style OK

Commit Message

Adrien Mazarguil Jan. 10, 2017, 1:08 p.m.
Leaving default pattern item mask values up for interpretation by PMDs is
an undefined behavior that applications might find difficult to use in the
wild. It also needlessly complicates PMD implementation.

This commit addresses this by defining consistent default masks for each
item type.

Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
Cc: John McNamara <john.mcnamara@intel.com>
Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
Cc: Wei Zhao <wei.zhao1@intel.com>
Cc: Beilei Xing <beilei.xing@intel.com>
---
 doc/guides/prog_guide/rte_flow.rst |  25 ++++++--
 lib/librte_ether/rte_flow.h        | 110 +++++++++++++++++++++++++++++---
 2 files changed, 121 insertions(+), 14 deletions(-)

Patch

diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 93d0dc2..3bf8871 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -217,13 +217,11 @@  Usage restrictions and expected behavior:
   values lower than those in ``spec`` are not supported.
 
 - Setting ``spec`` and optionally ``last`` without ``mask`` causes the PMD
-  to only take the fields it can recognize into account. There is no error
-  checking for unsupported fields.
+  to use the default mask defined for that item (defined as
+  ``rte_flow_item_{name}_mask`` constants).
 
-- Not setting any of them (assuming item type allows it) uses default
-  parameters that depend on the item type. Most of the time, particularly
-  for protocol header items, it is equivalent to providing an empty (zeroed)
-  ``mask``.
+- Not setting any of them (assuming item type allows it) is equivalent to
+  providing an empty (zeroed) ``mask`` for broad (nonspecific) matching.
 
 - ``mask`` is a simple bit-mask applied before interpreting the contents of
   ``spec`` and ``last``, which may yield unexpected results if not used
@@ -550,6 +548,7 @@  duplicated between device instances by default.
 - Can be specified multiple times to match traffic addressed to several VF
   IDs.
 - Can be combined with a PF item to match both PF and VF traffic.
+- Default ``mask`` matches any VF ID.
 
 .. _table_rte_flow_item_vf:
 
@@ -583,6 +582,8 @@  not be contiguous.
 As a device property, the list of allowed values as well as the value
 associated with a port_id should be retrieved by other means.
 
+- Default ``mask`` matches any port index.
+
 .. _table_rte_flow_item_port:
 
 .. table:: PORT
@@ -616,6 +617,8 @@  stand for several protocol layers.
 This is usually specified as the first pattern item when looking for a
 protocol anywhere in a packet.
 
+- Default ``mask`` stands for any number of layers.
+
 .. _table_rte_flow_item_any:
 
 .. table:: ANY
@@ -673,6 +676,7 @@  Matching a zero-length pattern is allowed, doing so resets the relative
 offset for subsequent items.
 
 - This type does not support ranges (``last`` field).
+- Default ``mask`` matches all fields exactly.
 
 .. _table_rte_flow_item_raw:
 
@@ -785,6 +789,7 @@  Matches an Ethernet header.
 - ``dst``: destination MAC.
 - ``src``: source MAC.
 - ``type``: EtherType.
+- Default ``mask`` matches destination and source addresses only.
 
 Item: ``VLAN``
 ^^^^^^^^^^^^^^
@@ -793,6 +798,7 @@  Matches an 802.1Q/ad VLAN tag.
 
 - ``tpid``: tag protocol identifier.
 - ``tci``: tag control information.
+- Default ``mask`` matches TCI only.
 
 Item: ``IPV4``
 ^^^^^^^^^^^^^^
@@ -802,6 +808,7 @@  Matches an IPv4 header.
 Note: IPv4 options are handled by dedicated pattern items.
 
 - ``hdr``: IPv4 header definition (``rte_ip.h``).
+- Default ``mask`` matches source and destination addresses only.
 
 Item: ``IPV6``
 ^^^^^^^^^^^^^^
@@ -811,6 +818,7 @@  Matches an IPv6 header.
 Note: IPv6 options are handled by dedicated pattern items.
 
 - ``hdr``: IPv6 header definition (``rte_ip.h``).
+- Default ``mask`` matches source and destination addresses only.
 
 Item: ``ICMP``
 ^^^^^^^^^^^^^^
@@ -818,6 +826,7 @@  Item: ``ICMP``
 Matches an ICMP header.
 
 - ``hdr``: ICMP header definition (``rte_icmp.h``).
+- Default ``mask`` matches ICMP type and code only.
 
 Item: ``UDP``
 ^^^^^^^^^^^^^
@@ -825,6 +834,7 @@  Item: ``UDP``
 Matches a UDP header.
 
 - ``hdr``: UDP header definition (``rte_udp.h``).
+- Default ``mask`` matches source and destination ports only.
 
 Item: ``TCP``
 ^^^^^^^^^^^^^
@@ -832,6 +842,7 @@  Item: ``TCP``
 Matches a TCP header.
 
 - ``hdr``: TCP header definition (``rte_tcp.h``).
+- Default ``mask`` matches source and destination ports only.
 
 Item: ``SCTP``
 ^^^^^^^^^^^^^^
@@ -839,6 +850,7 @@  Item: ``SCTP``
 Matches a SCTP header.
 
 - ``hdr``: SCTP header definition (``rte_sctp.h``).
+- Default ``mask`` matches source and destination ports only.
 
 Item: ``VXLAN``
 ^^^^^^^^^^^^^^^
@@ -849,6 +861,7 @@  Matches a VXLAN header (RFC 7348).
 - ``rsvd0``: reserved, normally 0x000000.
 - ``vni``: VXLAN network identifier.
 - ``rsvd1``: reserved, normally 0x00.
+- Default ``mask`` matches VNI only.
 
 Actions
 ~~~~~~~
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 59dc1ef..06da341 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -282,7 +282,12 @@  enum rte_flow_item_type {
  * A zeroed mask stands for any number of layers.
  */
 struct rte_flow_item_any {
-	uint32_t num; /* Number of layers covered. */
+	uint32_t num; /**< Number of layers covered. */
+};
+
+/** Default mask for RTE_FLOW_ITEM_TYPE_ANY. */
+static const struct rte_flow_item_any rte_flow_item_any_mask = {
+	.num = 0x00000000,
 };
 
 /**
@@ -307,6 +312,11 @@  struct rte_flow_item_vf {
 	uint32_t id; /**< Destination VF ID. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_VF. */
+static const struct rte_flow_item_vf rte_flow_item_vf_mask = {
+	.id = 0x00000000,
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_PORT
  *
@@ -331,6 +341,11 @@  struct rte_flow_item_port {
 	uint32_t index; /**< Physical port index. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_PORT. */
+static const struct rte_flow_item_port rte_flow_item_port_mask = {
+	.index = 0x00000000,
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_RAW
  *
@@ -359,6 +374,16 @@  struct rte_flow_item_raw {
 	uint8_t pattern[]; /**< Byte string to look for. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_RAW. */
+static const struct rte_flow_item_raw rte_flow_item_raw_mask = {
+	.relative = 1,
+	.search = 1,
+	.reserved = 0x3fffffff,
+	.offset = 0xffffffff,
+	.limit = 0xffff,
+	.length = 0xffff,
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_ETH
  *
@@ -370,6 +395,13 @@  struct rte_flow_item_eth {
 	uint16_t type; /**< EtherType. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_ETH. */
+static const struct rte_flow_item_eth rte_flow_item_eth_mask = {
+	.dst.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+	.src.addr_bytes = "\xff\xff\xff\xff\xff\xff",
+	.type = 0x0000,
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_VLAN
  *
@@ -383,6 +415,12 @@  struct rte_flow_item_vlan {
 	uint16_t tci; /**< Tag control information. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_VLAN. */
+static const struct rte_flow_item_vlan rte_flow_item_vlan_mask = {
+	.tpid = 0x0000,
+	.tci = 0xffff,
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_IPV4
  *
@@ -394,6 +432,14 @@  struct rte_flow_item_ipv4 {
 	struct ipv4_hdr hdr; /**< IPv4 header definition. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_IPV4. */
+static const struct rte_flow_item_ipv4 rte_flow_item_ipv4_mask = {
+	.hdr = {
+		.src_addr = 0xffffffff,
+		.dst_addr = 0xffffffff,
+	},
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_IPV6.
  *
@@ -405,6 +451,18 @@  struct rte_flow_item_ipv6 {
 	struct ipv6_hdr hdr; /**< IPv6 header definition. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_IPV6. */
+static const struct rte_flow_item_ipv6 rte_flow_item_ipv6_mask = {
+	.hdr = {
+		.src_addr =
+			"\xff\xff\xff\xff\xff\xff\xff\xff"
+			"\xff\xff\xff\xff\xff\xff\xff\xff",
+		.dst_addr =
+			"\xff\xff\xff\xff\xff\xff\xff\xff"
+			"\xff\xff\xff\xff\xff\xff\xff\xff",
+	},
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_ICMP.
  *
@@ -414,6 +472,14 @@  struct rte_flow_item_icmp {
 	struct icmp_hdr hdr; /**< ICMP header definition. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_ICMP. */
+static const struct rte_flow_item_icmp rte_flow_item_icmp_mask = {
+	.hdr = {
+		.icmp_type = 0xff,
+		.icmp_code = 0xff,
+	},
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_UDP.
  *
@@ -423,6 +489,14 @@  struct rte_flow_item_udp {
 	struct udp_hdr hdr; /**< UDP header definition. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_UDP. */
+static const struct rte_flow_item_udp rte_flow_item_udp_mask = {
+	.hdr = {
+		.src_port = 0xffff,
+		.dst_port = 0xffff,
+	},
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_TCP.
  *
@@ -432,6 +506,14 @@  struct rte_flow_item_tcp {
 	struct tcp_hdr hdr; /**< TCP header definition. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_TCP. */
+static const struct rte_flow_item_tcp rte_flow_item_tcp_mask = {
+	.hdr = {
+		.src_port = 0xffff,
+		.dst_port = 0xffff,
+	},
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_SCTP.
  *
@@ -441,6 +523,14 @@  struct rte_flow_item_sctp {
 	struct sctp_hdr hdr; /**< SCTP header definition. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_SCTP. */
+static const struct rte_flow_item_sctp rte_flow_item_sctp_mask = {
+	.hdr = {
+		.src_port = 0xffff,
+		.dst_port = 0xffff,
+	},
+};
+
 /**
  * RTE_FLOW_ITEM_TYPE_VXLAN.
  *
@@ -453,6 +543,11 @@  struct rte_flow_item_vxlan {
 	uint8_t rsvd1; /**< Reserved, normally 0x00. */
 };
 
+/** Default mask for RTE_FLOW_ITEM_TYPE_VXLAN. */
+static const struct rte_flow_item_vxlan rte_flow_item_vxlan_mask = {
+	.vni = "\xff\xff\xff",
+};
+
 /**
  * Matching pattern item definition.
  *
@@ -464,15 +559,18 @@  struct rte_flow_item_vxlan {
  * Patterns are terminated by END items.
  *
  * The spec field should be a valid pointer to a structure of the related
- * item type. It may be set to NULL in many cases to use default values.
+ * item type. It may remain unspecified (NULL) in many cases to request
+ * broad (nonspecific) matching. In such cases, last and mask must also be
+ * set to NULL.
  *
  * Optionally, last can point to a structure of the same type to define an
  * inclusive range. This is mostly supported by integer and address fields,
  * may cause errors otherwise. Fields that do not support ranges must be set
  * to 0 or to the same value as the corresponding fields in spec.
  *
- * By default all fields present in spec are considered relevant (see note
- * below). This behavior can be altered by providing a mask structure of the
+ * Only the fields defined to nonzero values in the default masks (see
+ * rte_flow_item_{name}_mask constants) are considered relevant by
+ * default. This can be overridden by providing a mask structure of the
  * same type with applicable bits set to one. It can also be used to
  * partially filter out specific fields (e.g. as an alternate mean to match
  * ranges of IP addresses).
@@ -482,10 +580,6 @@  struct rte_flow_item_vxlan {
  * carefully. For example, if for an IPv4 address field, spec provides
  * 10.1.2.3, last provides 10.3.4.5 and mask provides 255.255.0.0, the
  * effective range becomes 10.1.0.0 to 10.3.255.255.
- *
- * Note: the defaults for data-matching items such as IPv4 when mask is not
- * specified actually depend on the underlying implementation since only
- * recognized fields can be taken into account.
  */
 struct rte_flow_item {
 	enum rte_flow_item_type type; /**< Item type. */