This new attribute enables applications to create flow rules that do not
simply match traffic whose origin is specified in the pattern (e.g. some
non-default physical port or VF), but actively affect it by applying the
flow rule at the lowest possible level in the underlying device.

Signed-off-by: Adrien Mazarguil <adrien.mazarg...@6wind.com>
---
 app/test-pmd/cmdline_flow.c                 | 11 +++++
 app/test-pmd/config.c                       |  6 ++-
 doc/guides/prog_guide/rte_flow.rst          | 14 +++++++
 doc/guides/testpmd_app_ug/testpmd_funcs.rst | 11 ++---
 drivers/net/bnxt/bnxt_filter.c              |  8 ++++
 drivers/net/e1000/igb_flow.c                | 44 ++++++++++++++++++++
 drivers/net/enic/enic_flow.c                |  6 +++
 drivers/net/i40e/i40e_flow.c                |  8 ++++
 drivers/net/ixgbe/ixgbe_flow.c              | 53 ++++++++++++++++++++++++
 drivers/net/mlx4/mlx4_flow.c                |  4 ++
 drivers/net/mlx5/mlx5_flow.c                |  7 ++++
 drivers/net/mvpp2/mrvl_flow.c               |  6 +++
 drivers/net/sfc/sfc_flow.c                  |  6 +++
 drivers/net/tap/tap_flow.c                  |  6 +++
 lib/librte_ether/rte_flow.h                 | 18 +++++++-
 15 files changed, 200 insertions(+), 8 deletions(-)

diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index 3a486032d..122e9d50b 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -69,6 +69,7 @@ enum index {
        PRIORITY,
        INGRESS,
        EGRESS,
+       TRANSFER,
 
        /* Validate/create pattern. */
        PATTERN,
@@ -407,6 +408,7 @@ static const enum index next_vc_attr[] = {
        PRIORITY,
        INGRESS,
        EGRESS,
+       TRANSFER,
        PATTERN,
        ZERO,
 };
@@ -960,6 +962,12 @@ static const struct token token_list[] = {
                .next = NEXT(next_vc_attr),
                .call = parse_vc,
        },
+       [TRANSFER] = {
+               .name = "transfer",
+               .help = "apply rule directly to endpoints found in pattern",
+               .next = NEXT(next_vc_attr),
+               .call = parse_vc,
+       },
        /* Validate/create pattern. */
        [PATTERN] = {
                .name = "pattern",
@@ -1945,6 +1953,9 @@ parse_vc(struct context *ctx, const struct token *token,
        case EGRESS:
                out->args.vc.attr.egress = 1;
                return len;
+       case TRANSFER:
+               out->args.vc.attr.transfer = 1;
+               return len;
        case PATTERN:
                out->args.vc.pattern =
                        (void *)RTE_ALIGN_CEIL((uintptr_t)(out + 1),
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index c0fefe475..49ef87782 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1223,6 +1223,7 @@ port_flow_complain(struct rte_flow_error *error)
                [RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY] = "priority field",
                [RTE_FLOW_ERROR_TYPE_ATTR_INGRESS] = "ingress field",
                [RTE_FLOW_ERROR_TYPE_ATTR_EGRESS] = "egress field",
+               [RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER] = "transfer field",
                [RTE_FLOW_ERROR_TYPE_ATTR] = "attributes structure",
                [RTE_FLOW_ERROR_TYPE_ITEM_NUM] = "pattern length",
                [RTE_FLOW_ERROR_TYPE_ITEM_SPEC] = "item specification",
@@ -1488,12 +1489,13 @@ port_flow_list(portid_t port_id, uint32_t n, const 
uint32_t group[n])
                const struct rte_flow_item *item = pf->pattern;
                const struct rte_flow_action *action = pf->actions;
 
-               printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c\t",
+               printf("%" PRIu32 "\t%" PRIu32 "\t%" PRIu32 "\t%c%c%c\t",
                       pf->id,
                       pf->attr.group,
                       pf->attr.priority,
                       pf->attr.ingress ? 'i' : '-',
-                      pf->attr.egress ? 'e' : '-');
+                      pf->attr.egress ? 'e' : '-',
+                      pf->attr.transfer ? 't' : '-');
                while (item->type != RTE_FLOW_ITEM_TYPE_END) {
                        if (item->type != RTE_FLOW_ITEM_TYPE_VOID)
                                printf("%s ", flow_item[item->type].name);
diff --git a/doc/guides/prog_guide/rte_flow.rst 
b/doc/guides/prog_guide/rte_flow.rst
index f1b9d8d76..a4c8f5e3e 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -178,6 +178,20 @@ directions. At least one direction must be specified.
 Specifying both directions at once for a given rule is not recommended but
 may be valid in a few cases (e.g. shared counters).
 
+Attribute: Transfer
+^^^^^^^^^^^^^^^^^^^
+
+Instead of simply matching the properties of traffic as it would appear on a
+given DPDK port ID, enabling this attribute transfers a flow rule to the
+lowest possible level of any device endpoints found in the pattern.
+
+When supported, this effectively enables an application to re-route traffic
+not necessarily intended for it (e.g. coming from or addressed to different
+physical ports, VFs or applications) at the device level.
+
+It complements the behavior of some pattern items such as `Item: PORT`_ and
+is meaningless without them.
+
 Pattern item
 ~~~~~~~~~~~~
 
diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst 
b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
index 25fac8430..a87cd1542 100644
--- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
+++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
@@ -2970,14 +2970,14 @@ following sections.
 - Check whether a flow rule can be created::
 
    flow validate {port_id}
-       [group {group_id}] [priority {level}] [ingress] [egress]
+       [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
        pattern {item} [/ {item} [...]] / end
        actions {action} [/ {action} [...]] / end
 
 - Create a flow rule::
 
    flow create {port_id}
-       [group {group_id}] [priority {level}] [ingress] [egress]
+       [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
        pattern {item} [/ {item} [...]] / end
        actions {action} [/ {action} [...]] / end
 
@@ -3010,7 +3010,7 @@ underlying device in its current state but stops short of 
creating it. It is
 bound to ``rte_flow_validate()``::
 
    flow validate {port_id}
-      [group {group_id}] [priority {level}] [ingress] [egress]
+      [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
       pattern {item} [/ {item} [...]] / end
       actions {action} [/ {action} [...]] / end
 
@@ -3047,7 +3047,7 @@ Creating flow rules
 to ``rte_flow_create()``::
 
    flow create {port_id}
-      [group {group_id}] [priority {level}] [ingress] [egress]
+      [group {group_id}] [priority {level}] [ingress] [egress] [transfer]
       pattern {item} [/ {item} [...]] / end
       actions {action} [/ {action} [...]] / end
 
@@ -3061,7 +3061,7 @@ Otherwise it will show an error message of the form::
 
 Parameters describe in the following order:
 
-- Attributes (*group*, *priority*, *ingress*, *egress* tokens).
+- Attributes (*group*, *priority*, *ingress*, *egress*, *transfer* tokens).
 - A matching pattern, starting with the *pattern* token and terminated by an
   *end* pattern item.
 - Actions, starting with the *actions* token and terminated by an *end*
@@ -3089,6 +3089,7 @@ specified before the ``pattern`` token.
 - ``priority {level}``: priority level within group.
 - ``ingress``: rule applies to ingress traffic.
 - ``egress``: rule applies to egress traffic.
+- ``transfer``: apply rule directly to endpoints found in pattern.
 
 Each instance of an attribute specified several times overrides the previous
 value as shown below (group 4 is used)::
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index a97a8dd46..dedd24166 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -777,6 +777,14 @@ bnxt_flow_parse_attr(const struct rte_flow_attr *attr,
        }
 
        /* Not supported */
+       if (attr->transfer) {
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                  attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
+       /* Not supported */
        if (attr->priority) {
                rte_flow_error_set(error, EINVAL,
                                   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c
index 13f6f2a28..ac0d05bfa 100644
--- a/drivers/net/e1000/igb_flow.c
+++ b/drivers/net/e1000/igb_flow.c
@@ -379,6 +379,15 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
                return -rte_errno;
        }
 
+       /* not supported */
+       if (attr->transfer) {
+               memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                  attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
        if (attr->priority > 0xFFFF) {
                memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
                rte_flow_error_set(error, EINVAL,
@@ -624,6 +633,14 @@ cons_parse_ethertype_filter(const struct rte_flow_attr 
*attr,
        }
 
        /* Not supported */
+       if (attr->transfer) {
+               rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                               attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
+       /* Not supported */
        if (attr->priority) {
                rte_flow_error_set(error, EINVAL,
                                RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
@@ -923,6 +940,15 @@ cons_parse_syn_filter(const struct rte_flow_attr *attr,
                return -rte_errno;
        }
 
+       /* not supported */
+       if (attr->transfer) {
+               memset(filter, 0, sizeof(struct rte_eth_syn_filter));
+               rte_flow_error_set(error, EINVAL,
+                       RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                       attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
        /* Support 2 priorities, the lowest or highest. */
        if (!attr->priority) {
                filter->hig_pri = 0;
@@ -1211,6 +1237,15 @@ cons_parse_flex_filter(const struct rte_flow_attr *attr,
                return -rte_errno;
        }
 
+       /* not supported */
+       if (attr->transfer) {
+               memset(filter, 0, sizeof(struct rte_eth_flex_filter));
+               rte_flow_error_set(error, EINVAL,
+                       RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                       attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
        if (attr->priority > 0xFFFF) {
                memset(filter, 0, sizeof(struct rte_eth_flex_filter));
                rte_flow_error_set(error, EINVAL,
@@ -1361,6 +1396,15 @@ igb_parse_rss_filter(struct rte_eth_dev *dev,
                return -rte_errno;
        }
 
+       /* not supported */
+       if (attr->transfer) {
+               memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                  attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
        if (attr->priority > 0xFFFF) {
                memset(rss_conf, 0, sizeof(struct igb_rte_flow_rss_conf));
                rte_flow_error_set(error, EINVAL,
diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index a413740ab..3ec4de72a 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -1300,6 +1300,12 @@ enic_flow_parse(struct rte_eth_dev *dev,
                                           NULL,
                                           "egress is not supported");
                        return -rte_errno;
+               } else if (attrs->transfer) {
+                       rte_flow_error_set(error, ENOTSUP,
+                                          RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                          NULL,
+                                          "transfer is not supported");
+                       return -rte_errno;
                } else if (!attrs->ingress) {
                        rte_flow_error_set(error, ENOTSUP,
                                           RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c
index c6dd889ad..e374f874b 100644
--- a/drivers/net/i40e/i40e_flow.c
+++ b/drivers/net/i40e/i40e_flow.c
@@ -1917,6 +1917,14 @@ i40e_flow_parse_attr(const struct rte_flow_attr *attr,
        }
 
        /* Not supported */
+       if (attr->transfer) {
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                  attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
+       /* Not supported */
        if (attr->priority) {
                rte_flow_error_set(error, EINVAL,
                                   RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c
index 67d22b382..1f1fa9dc4 100644
--- a/drivers/net/ixgbe/ixgbe_flow.c
+++ b/drivers/net/ixgbe/ixgbe_flow.c
@@ -557,6 +557,15 @@ cons_parse_ntuple_filter(const struct rte_flow_attr *attr,
                return -rte_errno;
        }
 
+       /* not supported */
+       if (attr->transfer) {
+               memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                  attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
        if (attr->priority > 0xFFFF) {
                memset(filter, 0, sizeof(struct rte_eth_ntuple_filter));
                rte_flow_error_set(error, EINVAL,
@@ -787,6 +796,14 @@ cons_parse_ethertype_filter(const struct rte_flow_attr 
*attr,
        }
 
        /* Not supported */
+       if (attr->transfer) {
+               rte_flow_error_set(error, EINVAL,
+                               RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                               attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
+       /* Not supported */
        if (attr->priority) {
                rte_flow_error_set(error, EINVAL,
                                RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY,
@@ -1078,6 +1095,15 @@ cons_parse_syn_filter(const struct rte_flow_attr *attr,
                return -rte_errno;
        }
 
+       /* not supported */
+       if (attr->transfer) {
+               memset(filter, 0, sizeof(struct rte_eth_syn_filter));
+               rte_flow_error_set(error, EINVAL,
+                       RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                       attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
        /* Support 2 priorities, the lowest or highest. */
        if (!attr->priority) {
                filter->hig_pri = 0;
@@ -1250,6 +1276,15 @@ cons_parse_l2_tn_filter(struct rte_eth_dev *dev,
        }
 
        /* not supported */
+       if (attr->transfer) {
+               memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
+               rte_flow_error_set(error, EINVAL,
+                       RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                       attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
+       /* not supported */
        if (attr->priority) {
                memset(filter, 0, sizeof(struct rte_eth_l2_tunnel_conf));
                rte_flow_error_set(error, EINVAL,
@@ -1354,6 +1389,15 @@ ixgbe_parse_fdir_act_attr(const struct rte_flow_attr 
*attr,
        }
 
        /* not supported */
+       if (attr->transfer) {
+               memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
+               rte_flow_error_set(error, EINVAL,
+                       RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                       attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
+       /* not supported */
        if (attr->priority) {
                memset(rule, 0, sizeof(struct ixgbe_fdir_rule));
                rte_flow_error_set(error, EINVAL,
@@ -2829,6 +2873,15 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev,
                return -rte_errno;
        }
 
+       /* not supported */
+       if (attr->transfer) {
+               memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                  attr, "No support for transfer.");
+               return -rte_errno;
+       }
+
        if (attr->priority > 0xFFFF) {
                memset(rss_conf, 0, sizeof(struct ixgbe_rte_flow_rss_conf));
                rte_flow_error_set(error, EINVAL,
diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c
index 779641e11..480442f87 100644
--- a/drivers/net/mlx4/mlx4_flow.c
+++ b/drivers/net/mlx4/mlx4_flow.c
@@ -652,6 +652,10 @@ mlx4_flow_prepare(struct priv *priv,
                return rte_flow_error_set
                        (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_EGRESS,
                         NULL, "egress is not supported");
+       if (attr->transfer)
+               return rte_flow_error_set
+                       (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                        NULL, "transfer is not supported");
        if (!attr->ingress)
                return rte_flow_error_set
                        (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index f03413d32..5c48670c6 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -568,6 +568,13 @@ mlx5_flow_convert_attributes(const struct rte_flow_attr 
*attr,
                                   "egress is not supported");
                return -rte_errno;
        }
+       if (attr->transfer) {
+               rte_flow_error_set(error, ENOTSUP,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                                  NULL,
+                                  "transfer is not supported");
+               return -rte_errno;
+       }
        if (!attr->ingress) {
                rte_flow_error_set(error, ENOTSUP,
                                   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS,
diff --git a/drivers/net/mvpp2/mrvl_flow.c b/drivers/net/mvpp2/mrvl_flow.c
index 6604a411f..4848d5cf9 100644
--- a/drivers/net/mvpp2/mrvl_flow.c
+++ b/drivers/net/mvpp2/mrvl_flow.c
@@ -2188,6 +2188,12 @@ mrvl_flow_parse_attr(struct mrvl_priv *priv __rte_unused,
                                   "Egress is not supported");
                return -rte_errno;
        }
+       if (attr->transfer) {
+               rte_flow_error_set(error, ENOTSUP,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, NULL,
+                                  "Transfer is not supported");
+               return -rte_errno;
+       }
 
        return 0;
 }
diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c
index 515a61325..77598f2a4 100644
--- a/drivers/net/sfc/sfc_flow.c
+++ b/drivers/net/sfc/sfc_flow.c
@@ -1126,6 +1126,12 @@ sfc_flow_parse_attr(const struct rte_flow_attr *attr,
                                   "Egress is not supported");
                return -rte_errno;
        }
+       if (attr->transfer != 0) {
+               rte_flow_error_set(error, ENOTSUP,
+                                  RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, attr,
+                                  "Transfer is not supported");
+               return -rte_errno;
+       }
        if (attr->ingress == 0) {
                rte_flow_error_set(error, ENOTSUP,
                                   RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, attr,
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index e53eff6ce..597945ad2 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -1041,6 +1041,12 @@ priv_flow_process(struct pmd_internals *pmd,
        };
        int action = 0; /* Only one action authorized for now */
 
+       if (attr->transfer) {
+               rte_flow_error_set(
+                       error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER,
+                       NULL, "transfer is not supported");
+               return -rte_errno;
+       }
        if (attr->group > MAX_GROUP) {
                rte_flow_error_set(
                        error, EINVAL, RTE_FLOW_ERROR_TYPE_ATTR_GROUP,
diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
index 15e383f95..cbb9fd53b 100644
--- a/lib/librte_ether/rte_flow.h
+++ b/lib/librte_ether/rte_flow.h
@@ -72,7 +72,22 @@ struct rte_flow_attr {
        uint32_t priority; /**< Priority level within group. */
        uint32_t ingress:1; /**< Rule applies to ingress traffic. */
        uint32_t egress:1; /**< Rule applies to egress traffic. */
-       uint32_t reserved:30; /**< Reserved, must be zero. */
+       /**
+        * Instead of simply matching the properties of traffic as it would
+        * appear on a given DPDK port ID, enabling this attribute transfers
+        * a flow rule to the lowest possible level of any device endpoints
+        * found in the pattern.
+        *
+        * When supported, this effectively enables an application to
+        * re-route traffic not necessarily intended for it (e.g. coming
+        * from or addressed to different physical ports, VFs or
+        * applications) at the device level.
+        *
+        * It complements the behavior of some pattern items such as
+        * RTE_FLOW_ITEM_TYPE_PORT and is meaningless without them.
+        */
+       uint32_t transfer:1;
+       uint32_t reserved:29; /**< Reserved, must be zero. */
 };
 
 /**
@@ -1174,6 +1189,7 @@ enum rte_flow_error_type {
        RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, /**< Priority field. */
        RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, /**< Ingress field. */
        RTE_FLOW_ERROR_TYPE_ATTR_EGRESS, /**< Egress field. */
+       RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, /**< Transfer field. */
        RTE_FLOW_ERROR_TYPE_ATTR, /**< Attributes structure. */
        RTE_FLOW_ERROR_TYPE_ITEM_NUM, /**< Pattern length. */
        RTE_FLOW_ERROR_TYPE_ITEM_SPEC, /**< Item specification. */
-- 
2.11.0

Reply via email to