From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f45.google.com (mail-wm0-f45.google.com [74.125.82.45]) by dpdk.org (Postfix) with ESMTP id 258CC7F6D for ; Wed, 25 Apr 2018 17:28:17 +0200 (CEST) Received: by mail-wm0-f45.google.com with SMTP id l16so7594230wmh.2 for ; Wed, 25 Apr 2018 08:28:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=E0fcuN5HyxXSSu7zLTw2nup4+MyzoJUYfvXCw13ug0Y=; b=1BIBVX4dXkczkm8ZpeAZCf8jZEkNwsnqzUkCKIq7RzpbmW6V8LoquG4iuWwyHMJGnt lfHaEC+vtKzyDVOpZBZw5Ubmp2RCWTRL/pbTC4QB5Ki4tKXStUtLlAriXJ789uQ45lRG g27QH+7iFFg4b1KaV1w5pfWRJP9Lm4HUANDYio9hpcDUfSmUXcOYhY0dGouDMDQ8g3TD LiluygUXCDYwvwV1zXhLhWx6eB+ydHtQORp3fzJdq6Qq1Toi2nKNFoONU3ZUfcEiDvOh m5dR+ChGHqPKrjtuWTuH/D//lqf9FffRnY19EixgZHH1tUuozkYew5df/2LWmenG3SNT jiFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=E0fcuN5HyxXSSu7zLTw2nup4+MyzoJUYfvXCw13ug0Y=; b=Hh1XIyrpDJJ5BtOkhCLhn9CiO1Tv/uZOupPMxFZAJYKNg25MtGdLcv8w8/Dz8iOx2L mTfBl3myaNgAYuBAloYXiXG5Nkm6eovq6WRfmKJvdOvq4EoyULBZ478pzemEKaLTt+b1 3mNSFUupvv3D9TqnrDZDVU06W0BtSGTrENEKAFCygPCAbA0WZzXPYjNImDuEsPkPZSag FpSzHHqX4X9McwZE4RW5rO+Aw5OWYPQ38pv+vfK4tTEs5gJg3dqzu80bKZvGoh6VzLe5 ncx4f58vkXis45F7CrZcT4jf3hDx33iMeQH06pauUXxJoKg4KtN08Z/nkP+pzYh+py5F epRg== X-Gm-Message-State: ALQs6tDa6RaWGViZqkFopLdRdeqVs4rlHps/G/k+dHe8CNKADuFnsdwk Rxt/9NDgSTi860+N4D7+PTqCVw== X-Google-Smtp-Source: AIpwx49SODTOvUAxdu27xCBAZrahbLKW9jCrz2GkhGs0yewZm5b0toSyp6ME+BjMndMQ+32rklW0dQ== X-Received: by 10.28.10.83 with SMTP id 80mr16192894wmk.70.1524670095684; Wed, 25 Apr 2018 08:28:15 -0700 (PDT) Received: from 6wind.com (host.78.145.23.62.rev.coltfrance.com. [62.23.145.78]) by smtp.gmail.com with ESMTPSA id v191sm8928780wmf.34.2018.04.25.08.28.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Apr 2018 08:28:14 -0700 (PDT) Date: Wed, 25 Apr 2018 17:28:01 +0200 From: Adrien Mazarguil To: Thomas Monjalon , Ferruh Yigit , dev@dpdk.org Cc: Andrew Rybchenko Message-ID: <20180425151852.7676-13-adrien.mazarguil@6wind.com> References: <20180419100848.6178-1-adrien.mazarguil@6wind.com> <20180425151852.7676-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180425151852.7676-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v6 12/16] ethdev: add transfer attribute to flow API X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Apr 2018 15:28:17 -0000 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. It breaks ABI compatibility for the following public functions: - rte_flow_copy() - rte_flow_create() - rte_flow_validate() Signed-off-by: Adrien Mazarguil Cc: Andrew Rybchenko --- v6 changes: Updated API and ABI changes sections in release notes. v3 changes: Clarified definition for ingress and egress following Andrew's comment on subsequent patch. [1] http://dpdk.org/ml/archives/dev/2018-April/095961.html --- app/test-pmd/cmdline_flow.c | 11 +++++ app/test-pmd/config.c | 6 ++- doc/guides/prog_guide/rte_flow.rst | 26 +++++++++++- doc/guides/rel_notes/release_18_05.rst | 7 +++- 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 | 22 +++++++++- 16 files changed, 220 insertions(+), 11 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index f8f2a559e..1c6b5a112 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 4b121aa79..a06514acc 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1256,6 +1256,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", @@ -1521,12 +1522,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 c62a80566..550a4c95b 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -170,7 +170,13 @@ Note that support for more than a single priority level is not guaranteed. Attribute: Traffic direction ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Flow rules can apply to inbound and/or outbound traffic (ingress/egress). +Flow rule patterns apply to inbound and/or outbound traffic. + +In the context of this API, **ingress** and **egress** respectively stand +for **inbound** and **outbound** based on the standpoint of the application +creating a flow rule. + +There are no exceptions to this definition. Several pattern items and actions are valid and can be used in both directions. At least one direction must be specified. @@ -178,6 +184,24 @@ 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 reroute 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. + +When transferring flow rules, **ingress** and **egress** attributes +(`Attribute: Traffic direction`_) keep their original meaning, as if +processing traffic emitted or received by the application. + Pattern item ~~~~~~~~~~~~ diff --git a/doc/guides/rel_notes/release_18_05.rst b/doc/guides/rel_notes/release_18_05.rst index 9aca8b4c8..635b69aa1 100644 --- a/doc/guides/rel_notes/release_18_05.rst +++ b/doc/guides/rel_notes/release_18_05.rst @@ -266,6 +266,8 @@ API Changes * The VLAN pattern item (``struct rte_flow_item_vlan``) was modified to include inner EtherType instead of outer TPID. Its default mask was also modified to cover the VID part (lower 12 bits) of TCI only. + * A new transfer attribute was added to ``struct rte_flow_attr`` in order + to clarify the behavior of some pattern items. ABI Changes @@ -316,8 +318,9 @@ ABI Changes of the unused DUP action (``enum rte_flow_action_type``), modified behavior for flow rule actions (see API changes), removal of C99 flexible array from RAW pattern item (``struct rte_flow_item_raw``), complete - rework of the RSS action definition (``struct rte_flow_action_rss``) and - sanity fix in the VLAN pattern item (``struct rte_flow_item_vlan``). + rework of the RSS action definition (``struct rte_flow_action_rss``), + sanity fix in the VLAN pattern item (``struct rte_flow_item_vlan``) and + new transfer attribute (``struct rte_flow_attr``). Removed Items diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 007b24ff3..454157dd4 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -2994,14 +2994,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 @@ -3034,7 +3034,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 @@ -3071,7 +3071,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 @@ -3085,7 +3085,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* @@ -3113,6 +3113,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 25806bdc0..68deb3445 100644 --- a/drivers/net/bnxt/bnxt_filter.c +++ b/drivers/net/bnxt/bnxt_filter.c @@ -754,6 +754,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 d1c0b4b8d..073852913 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 eea14ee73..525f3dd7c 100644 --- a/drivers/net/enic/enic_flow.c +++ b/drivers/net/enic/enic_flow.c @@ -1318,6 +1318,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 470ab93d6..f416b6a00 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -1918,6 +1918,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 438bfcdfb..eb0644c82 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 ce36ac715..e3d7aa8ef 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 d77598b2d..41a7c6477 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -576,6 +576,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 6478eb2fe..a2e2129cc 100644 --- a/drivers/net/mvpp2/mrvl_flow.c +++ b/drivers/net/mvpp2/mrvl_flow.c @@ -2187,6 +2187,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 cd6a61b39..bcde2c2f7 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1116,6 +1116,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 dff09313a..ad2ba9f4e 100644 --- a/drivers/net/tap/tap_flow.c +++ b/drivers/net/tap/tap_flow.c @@ -1039,6 +1039,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 513734dce..ab2bf2dce 100644 --- a/lib/librte_ether/rte_flow.h +++ b/lib/librte_ether/rte_flow.h @@ -72,7 +72,26 @@ 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. + * + * When transferring flow rules, ingress and egress attributes keep + * their original meaning, as if processing traffic emitted or + * received by the application. + */ + uint32_t transfer:1; + uint32_t reserved:29; /**< Reserved, must be zero. */ }; /** @@ -1181,6 +1200,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