From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f48.google.com (mail-wm0-f48.google.com [74.125.82.48]) by dpdk.org (Postfix) with ESMTP id 1A1A81CC56 for ; Fri, 6 Apr 2018 15:26:04 +0200 (CEST) Received: by mail-wm0-f48.google.com with SMTP id x4so3342638wmh.5 for ; Fri, 06 Apr 2018 06:26:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=6wind-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=NfBAaNqlhfVEm2QC5OfCEzd6kvkAad/v3fw5E8guO1k=; b=un7ms/Qs2jXFkR1VfODjZIiOvzDVI4kaQ7hDzRPsiDaoSYPmPTSWCB6Y4OCkCAIrTy vFk9NU8W9+QiS80KE3YZZx2xn6VETfreMwWehHrDFOD2rkNpJDnCbXbnZkrAXRnmigga Mc3JxvW4vugJZLHkHYi7y8reJgsYTgA5QqfFbeuFcLe8uzu/S9NADJr9wEQERYtwu/7B cOYig2NXA2uiYQVr0QraV3PRASZnzq2szZggwOgI1eWVP36yTEu8YnwRMZfa8SdTLGVo 9WNqH2qq3DR9mkDLgOSS/751G+JagwXoNhi1PsFlhCU9TR80MkC4mHBi3Gh8nkj9yObm vozA== 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:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=NfBAaNqlhfVEm2QC5OfCEzd6kvkAad/v3fw5E8guO1k=; b=lBLXAS8RkLzAGy5gXYQkiZDQo/XnkmegqPWe+39HhqGguE2VU192GtBRpOKf/r6Na4 I8AnLFYEzh23ZVzqBWvENOEsoaSH+MVDYJU/+/qgnZjuOsoILwAi+4pp2juEco3Yuwhp UIIWhvRooaTsGopXgc5RRP+2hAOc/AAeMHELmtDnvW0IyhVIFHPLgqlQI5cqz+7U6oS+ Oz6wXDpd0uC6xzt+Our1lIlCf4nFxOsI+eSX9M8a7YhVuDas8MfooWhkb6a4e141A49I vKzcvUB7S/Hs/Z4MJyAwEDi2hzdzoeavntFXmSNuo1qUEvW85GEq81iNrzUiEFTa17It Q0lw== X-Gm-Message-State: ALQs6tCgpySCFf5OACGLCrOf2F7lli5teFy3UINkA91zF/9OxTax6fgk 8MsZIXNPjuRMUgcukiStmYpR5w== X-Google-Smtp-Source: AIpwx4+Kmbp9/rmA2HRWm6LmXNSyrxoOLwcI0CsjY43PzQMb42xhtsnNrScUWDHKsRkqBJbBkZmApQ== X-Received: by 10.28.173.4 with SMTP id w4mr1035556wme.54.1523021163448; Fri, 06 Apr 2018 06:26:03 -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 u14sm2329202wri.31.2018.04.06.06.26.02 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Apr 2018 06:26:02 -0700 (PDT) Date: Fri, 6 Apr 2018 15:25:49 +0200 From: Adrien Mazarguil To: Thomas Monjalon , Ferruh Yigit , dev@dpdk.org Message-ID: <20180406131736.19145-12-adrien.mazarguil@6wind.com> References: <20180404150312.12304-1-adrien.mazarguil@6wind.com> <20180406131736.19145-1-adrien.mazarguil@6wind.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20180406131736.19145-1-adrien.mazarguil@6wind.com> X-Mailer: git-send-email 2.11.0 Subject: [dpdk-dev] [PATCH v2 11/15] 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: Fri, 06 Apr 2018 13:26:04 -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 --- 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 c6f16d444..735ce6323 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 51e3e8de4..862e03188 100644 --- a/drivers/net/bnxt/bnxt_filter.c +++ b/drivers/net/bnxt/bnxt_filter.c @@ -750,6 +750,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 d645dfb63..b575d0365 100644 --- a/drivers/net/enic/enic_flow.c +++ b/drivers/net/enic/enic_flow.c @@ -1301,6 +1301,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 e9550b0ce..0a3f93fad 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 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 8863e451c..288610620 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -569,6 +569,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 f61d4ec92..b12a47281 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 b13b0e2e6..b7bdc0469 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. */ }; /** @@ -1175,6 +1190,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