From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f49.google.com (mail-wm0-f49.google.com [74.125.82.49]) by dpdk.org (Postfix) with ESMTP id E99501BB9F for ; Fri, 6 Apr 2018 15:25:59 +0200 (CEST) Received: by mail-wm0-f49.google.com with SMTP id o23so8036832wmf.0 for ; Fri, 06 Apr 2018 06:25:59 -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=91xMz+XxA+a0d0hXwGWm3ObmqEt7UJgEqJ2/dF3x+7k=; b=JdgKZymxD6mFAVwHW3RBhT3CID0UqyZKyB2qpxFgdf1qZJ8l3nGXp/7uLr609rDj+G hjay3ygei0LrfqmG6BPUcoudyfxaUZ5tGWoGjVp7UQFeqeHSnEwskwYs7EDFnq2d8Gzm MELhJ03kNMQHY20PeebSzDO0InIA+xNTJlFvHmJQCnydXSDGtYJpNLXIZTmOihzaplwa GDBqaSS4AvtrQBdwFJJqCcrG5o+Z0s6ATPPYdSEwjULpWUTYtP8in+1IihwaQYg7XXUx Y8TB8yOjPZmEYD4PI3s4iR2k4ZL63RkKaLGz0QFwFzDx2AB7TEcbp/MCFc/4EFIvw5EN st1A== 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=91xMz+XxA+a0d0hXwGWm3ObmqEt7UJgEqJ2/dF3x+7k=; b=E4At+RqaKmMbpGo1XE+QCzjU6qqKnjSE/YLRt3mb+hxEDaRNCWLhEr8hOx/DazEGiv NKFxTG3prUiCnU/I++4A3rMbnltl90ZsgXDDz27Anq8x1fCPOU/FCqCLeVBL5Thiup6P TglybxL5BKg1w4lvcaCONYuuPB/Trk16g6leRzOgGd0EsY4nAd9mbeoYp97W8Yf26c/A qPsFT3suyK2XRQFEAIMQPWdRmgz59VFgb4ijYu1IhGL7r5xG/CoU4xypg1BYyAkA1reO 6SLxXgAkYbCjTP0MNDyT81w9QjN1RpGUGAY7zlWZ6fAsXTYVD3mzZKSQgO/r7HIxdNPe tNpg== X-Gm-Message-State: ALQs6tC40nV2n1D49dqKPDHDdnxFSZZ6JveN/lP6ANqJ+gnZwHcry6vw i61jMY3qbnbVT/KcmzobVGiTPw== X-Google-Smtp-Source: AIpwx49PgZSgp02e4U92ZjL7Ofa1m/XALIRLJvxt1iVxOoTrpVB3eGrbikruFUDIsOebAKraa+xLRA== X-Received: by 10.28.247.16 with SMTP id v16mr12555215wmh.157.1523021159566; Fri, 06 Apr 2018 06:25:59 -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 c15sm14065393wrc.64.2018.04.06.06.25.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Apr 2018 06:25:58 -0700 (PDT) Date: Fri, 6 Apr 2018 15:25:45 +0200 From: Adrien Mazarguil To: Thomas Monjalon , Ferruh Yigit , dev@dpdk.org Cc: Xueming Li , Wenzhuo Lu , Jingjing Wu , Beilei Xing , Qi Zhang , Konstantin Ananyev , Nelio Laranjeiro , Yongseok Koh , Andrew Rybchenko , Pascal Mazon Message-ID: <20180406131736.19145-10-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 09/15] ethdev: add encap level to RSS flow API action 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:00 -0000 RSS hash types (ETH_RSS_* macros defined in rte_ethdev.h) describe the protocol header fields of a packet that must be taken into account while computing RSS. When facing encapsulated (e.g. tunneled) packets, there is an ambiguity as to whether these should apply to inner or outer packets. Applications need the ability to tell exactly "where" RSS must be performed. This is addressed by adding encapsulation level information to the RSS flow action. Its default value is 0 and stands for the usual unspecified behavior. Other values provide a specific encapsulation level. Contrary to the change announced by commit 676b605182a5 ("doc: announce ethdev API change for RSS configuration"), this patch does not affect struct rte_eth_rss_conf but struct rte_flow_action_rss as the former is not used anymore by the RSS flow action. ABI impact is therefore limited to rte_flow. This breaks ABI compatibility for the following public functions: - rte_flow_copy() - rte_flow_create() - rte_flow_query() - rte_flow_validate() Signed-off-by: Adrien Mazarguil Cc: Xueming Li Cc: Ferruh Yigit Cc: Thomas Monjalon Cc: Wenzhuo Lu Cc: Jingjing Wu Cc: Beilei Xing Cc: Qi Zhang Cc: Konstantin Ananyev Cc: Nelio Laranjeiro Cc: Yongseok Koh Cc: Andrew Rybchenko Cc: Pascal Mazon --- app/test-pmd/cmdline_flow.c | 13 ++++++++++++ app/test-pmd/config.c | 1 + doc/guides/prog_guide/rte_flow.rst | 24 ++++++++++++++++++++++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 2 ++ drivers/net/e1000/igb_flow.c | 4 ++++ drivers/net/e1000/igb_rxtx.c | 2 ++ drivers/net/i40e/i40e_ethdev.c | 2 ++ drivers/net/i40e/i40e_flow.c | 4 ++++ drivers/net/ixgbe/ixgbe_flow.c | 4 ++++ drivers/net/ixgbe/ixgbe_rxtx.c | 2 ++ drivers/net/mlx4/mlx4_flow.c | 6 ++++++ drivers/net/mlx5/mlx5_flow.c | 11 ++++++++++ drivers/net/sfc/sfc_flow.c | 3 +++ drivers/net/tap/tap_flow.c | 6 +++++- lib/librte_ether/rte_flow.c | 1 + lib/librte_ether/rte_flow.h | 26 ++++++++++++++++++++++++ 16 files changed, 110 insertions(+), 1 deletion(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 23e10d623..2fbd3d8ef 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -167,6 +167,7 @@ enum index { ACTION_COUNT, ACTION_RSS, ACTION_RSS_FUNC, + ACTION_RSS_LEVEL, ACTION_RSS_FUNC_DEFAULT, ACTION_RSS_FUNC_TOEPLITZ, ACTION_RSS_FUNC_SIMPLE_XOR, @@ -638,6 +639,7 @@ static const enum index action_queue[] = { static const enum index action_rss[] = { ACTION_RSS_FUNC, + ACTION_RSS_LEVEL, ACTION_RSS_TYPES, ACTION_RSS_KEY, ACTION_RSS_KEY_LEN, @@ -1616,6 +1618,16 @@ static const struct token token_list[] = { .help = "simple XOR hash function", .call = parse_vc_action_rss_func, }, + [ACTION_RSS_LEVEL] = { + .name = "level", + .help = "encapsulation level for \"types\"", + .next = NEXT(action_rss, NEXT_ENTRY(UNSIGNED)), + .args = ARGS(ARGS_ENTRY_ARB + (offsetof(struct action_rss_data, conf) + + offsetof(struct rte_flow_action_rss, level), + sizeof(((struct rte_flow_action_rss *)0)-> + level))), + }, [ACTION_RSS_TYPES] = { .name = "types", .help = "RSS hash types", @@ -2107,6 +2119,7 @@ parse_vc_action_rss(struct context *ctx, const struct token *token, *action_rss_data = (struct action_rss_data){ .conf = (struct rte_flow_action_rss){ .func = RTE_ETH_HASH_FUNCTION_DEFAULT, + .level = 0, .types = rss_hf, .key_len = sizeof(action_rss_data->key), .queue_num = RTE_MIN(nb_rxq, ACTION_RSS_QUEUE_NUM), diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index b258c93e8..c0fefe475 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -1085,6 +1085,7 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action) if (dst.rss) *dst.rss = (struct rte_flow_action_rss){ .func = src.rss->func, + .level = src.rss->level, .types = src.rss->types, .key_len = src.rss->key_len, .queue_num = src.rss->queue_num, diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 7a97ced2a..97d429ee5 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1305,6 +1305,28 @@ Note: RSS hash result is stored in the ``hash.rss`` mbuf field which overlaps ``hash.fdir.lo``. Since `Action: MARK`_ sets the ``hash.fdir.hi`` field only, both can be requested simultaneously. +Also, regarding packet encapsulation ``level``: + +- ``0`` requests the default behavior. Depending on the packet type, it can + mean outermost, innermost, anything in between or even no RSS. + + It basically stands for the innermost encapsulation level RSS can be + performed on according to PMD and device capabilities. + +- ``1`` requests RSS to be performed on the outermost packet encapsulation + level. + +- ``2`` and subsequent values request RSS to be performed on the specified + inner packet encapsulation level, from outermost to innermost (lower to + higher values). + +Values other than ``0`` are not necessarily supported. + +Requesting a specific RSS level on unrecognized traffic results in undefined +behavior. For predictable results, it is recommended to make the flow rule +pattern match packet headers up to the requested encapsulation level so that +only matching traffic goes through. + .. _table_rte_flow_action_rss: .. table:: RSS @@ -1314,6 +1336,8 @@ field only, both can be requested simultaneously. +===============+====================================+ | ``func`` | RSS hash function to apply | +---------------+------------------------------------+ + | ``level`` | encapsulation level for ``types`` | + +---------------+------------------------------------+ | ``types`` | RSS hash types (see ``ETH_RSS_*``) | +---------------+------------------------------------+ | ``key_len`` | hash key length in bytes | diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index d9d68ad9b..738461f44 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -3401,6 +3401,8 @@ This section lists supported actions and their attributes, if any. - ``func {hash function}``: RSS hash function to apply, allowed tokens are the same as `set_hash_global_config`_. + - ``level {unsigned}``: encapsulation level for ``types``. + - ``types [{RSS hash type} [...]] end``: RSS hash types, allowed tokens are the same as `set_hash_input_set`_, an empty list means none (0). diff --git a/drivers/net/e1000/igb_flow.c b/drivers/net/e1000/igb_flow.c index 747c524f5..13f6f2a28 100644 --- a/drivers/net/e1000/igb_flow.c +++ b/drivers/net/e1000/igb_flow.c @@ -1314,6 +1314,10 @@ igb_parse_rss_filter(struct rte_eth_dev *dev, return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, "non-default RSS hash functions are not supported"); + if (rss->level) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, + "a nonzero RSS encapsulation level is not supported"); if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key)) return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c index d5c1cd3d3..a3776a0d7 100644 --- a/drivers/net/e1000/igb_rxtx.c +++ b/drivers/net/e1000/igb_rxtx.c @@ -2906,6 +2906,7 @@ igb_rss_conf_init(struct igb_rte_flow_rss_conf *out, return -EINVAL; out->conf = (struct rte_flow_action_rss){ .func = in->func, + .level = in->level, .types = in->types, .key_len = in->key_len, .queue_num = in->queue_num, @@ -2921,6 +2922,7 @@ igb_action_rss_same(const struct rte_flow_action_rss *comp, const struct rte_flow_action_rss *with) { return (comp->func == with->func && + comp->level == with->level && comp->types == with->types && comp->key_len == with->key_len && comp->queue_num == with->queue_num && diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 5e313950c..b104b551c 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -11975,6 +11975,7 @@ i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out, return -EINVAL; out->conf = (struct rte_flow_action_rss){ .func = in->func, + .level = in->level, .types = in->types, .key_len = in->key_len, .queue_num = in->queue_num, @@ -11990,6 +11991,7 @@ i40e_action_rss_same(const struct rte_flow_action_rss *comp, const struct rte_flow_action_rss *with) { return (comp->func == with->func && + comp->level == with->level && comp->types == with->types && comp->key_len == with->key_len && comp->queue_num == with->queue_num && diff --git a/drivers/net/i40e/i40e_flow.c b/drivers/net/i40e/i40e_flow.c index 0a6ed0f2e..c0a2bc4a6 100644 --- a/drivers/net/i40e/i40e_flow.c +++ b/drivers/net/i40e/i40e_flow.c @@ -4330,6 +4330,10 @@ i40e_flow_parse_rss_action(struct rte_eth_dev *dev, return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, "non-default RSS hash functions are not supported"); + if (rss->level) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, + "a nonzero RSS encapsulation level is not supported"); if (rss->key_len && rss->key_len > RTE_DIM(rss_config->key)) return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, diff --git a/drivers/net/ixgbe/ixgbe_flow.c b/drivers/net/ixgbe/ixgbe_flow.c index 10056a0f7..67d22b382 100644 --- a/drivers/net/ixgbe/ixgbe_flow.c +++ b/drivers/net/ixgbe/ixgbe_flow.c @@ -2783,6 +2783,10 @@ ixgbe_parse_rss_filter(struct rte_eth_dev *dev, return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, "non-default RSS hash functions are not supported"); + if (rss->level) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, + "a nonzero RSS encapsulation level is not supported"); if (rss->key_len && rss->key_len != RTE_DIM(rss_conf->key)) return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_ACTION, act, diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c index e17f5a433..23af21712 100644 --- a/drivers/net/ixgbe/ixgbe_rxtx.c +++ b/drivers/net/ixgbe/ixgbe_rxtx.c @@ -5683,6 +5683,7 @@ ixgbe_rss_conf_init(struct ixgbe_rte_flow_rss_conf *out, return -EINVAL; out->conf = (struct rte_flow_action_rss){ .func = in->func, + .level = in->level, .types = in->types, .key_len = in->key_len, .queue_num = in->queue_num, @@ -5698,6 +5699,7 @@ ixgbe_action_rss_same(const struct rte_flow_action_rss *comp, const struct rte_flow_action_rss *with) { return (comp->func == with->func && + comp->level == with->level && comp->types == with->types && comp->key_len == with->key_len && comp->queue_num == with->queue_num && diff --git a/drivers/net/mlx4/mlx4_flow.c b/drivers/net/mlx4/mlx4_flow.c index dcaf8df44..779641e11 100644 --- a/drivers/net/mlx4/mlx4_flow.c +++ b/drivers/net/mlx4/mlx4_flow.c @@ -796,6 +796,11 @@ mlx4_flow_prepare(struct priv *priv, " is Toeplitz"; goto exit_action_not_supported; } + if (rss->level) { + msg = "a nonzero RSS encapsulation level is" + " not supported"; + goto exit_action_not_supported; + } rte_errno = 0; fields = mlx4_conv_rss_types(priv, rss->types); if (fields == (uint64_t)-1 && rte_errno) { @@ -1290,6 +1295,7 @@ mlx4_flow_internal(struct priv *priv, struct rte_flow_error *error) uint16_t queue[queues]; struct rte_flow_action_rss action_rss = { .func = RTE_ETH_HASH_FUNCTION_DEFAULT, + .level = 0, .types = -1, .key_len = MLX4_RSS_HASH_KEY_SIZE, .queue_num = queues, diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 0771ad339..bc1176819 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -644,6 +644,14 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev, " function is Toeplitz"); return -rte_errno; } + if (rss->level) { + rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ACTION, + actions, + "a nonzero RSS encapsulation" + " level is not supported"); + return -rte_errno; + } if (rss->types & MLX5_RSS_HF_MASK) { rte_flow_error_set(error, EINVAL, RTE_FLOW_ERROR_TYPE_ACTION, @@ -694,6 +702,7 @@ mlx5_flow_convert_actions(struct rte_eth_dev *dev, } parser->rss_conf = (struct rte_flow_action_rss){ .func = RTE_ETH_HASH_FUNCTION_DEFAULT, + .level = 0, .types = rss->types, .key_len = rss_key_len, .queue_num = rss->queue_num, @@ -1927,6 +1936,7 @@ mlx5_flow_list_create(struct rte_eth_dev *dev, flow->queues = (uint16_t (*)[])(flow + 1); flow->rss_conf = (struct rte_flow_action_rss){ .func = RTE_ETH_HASH_FUNCTION_DEFAULT, + .level = 0, .types = parser.rss_conf.types, .key_len = parser.rss_conf.key_len, .queue_num = parser.rss_conf.queue_num, @@ -2442,6 +2452,7 @@ mlx5_ctrl_flow_vlan(struct rte_eth_dev *dev, uint16_t queue[priv->reta_idx_n]; struct rte_flow_action_rss action_rss = { .func = RTE_ETH_HASH_FUNCTION_DEFAULT, + .level = 0, .types = priv->rss_conf.rss_hf, .key_len = priv->rss_conf.rss_key_len, .queue_num = priv->reta_idx_n, diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index dbe4c2baa..bc4974edf 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -1264,6 +1264,9 @@ sfc_flow_parse_rss(struct sfc_adapter *sa, if (rss->func) return -EINVAL; + if (rss->level) + return -EINVAL; + if ((rss->types & ~SFC_RSS_OFFLOADS) != 0) return -EINVAL; diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c index 3d91da216..e5eb50fc5 100644 --- a/drivers/net/tap/tap_flow.c +++ b/drivers/net/tap/tap_flow.c @@ -2055,11 +2055,15 @@ static int rss_add_actions(struct rte_flow *flow, struct pmd_internals *pmd, struct rss_key rss_entry = { .hash_fields = 0, .key_size = 0 }; - /* Check supported hash functions */ + /* Check supported RSS features */ if (rss->func) return rte_flow_error_set (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, "non-default RSS hash functions are not supported"); + if (rss->level) + return rte_flow_error_set + (error, ENOTSUP, RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, + "a nonzero RSS encapsulation level is not supported"); /* Get a new map key for a new RSS rule */ err = bpf_rss_key(KEY_CMD_GET, &flow->key_idx); diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c index 0a2c0ac00..1f247d656 100644 --- a/lib/librte_ether/rte_flow.c +++ b/lib/librte_ether/rte_flow.c @@ -331,6 +331,7 @@ flow_action_conf_copy(void *buf, const struct rte_flow_action *action) if (dst.rss) *dst.rss = (struct rte_flow_action_rss){ .func = src.rss->func, + .level = src.rss->level, .types = src.rss->types, .key_len = src.rss->key_len, .queue_num = src.rss->queue_num, diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h index 66cadc74e..fc7e6705d 100644 --- a/lib/librte_ether/rte_flow.h +++ b/lib/librte_ether/rte_flow.h @@ -1040,6 +1040,32 @@ struct rte_flow_query_count { */ struct rte_flow_action_rss { enum rte_eth_hash_function func; /**< RSS hash function to apply. */ + /** + * Packet encapsulation level RSS hash @p types apply to. + * + * - @p 0 requests the default behavior. Depending on the packet + * type, it can mean outermost, innermost, anything in between or + * even no RSS. + * + * It basically stands for the innermost encapsulation level RSS + * can be performed on according to PMD and device capabilities. + * + * - @p 1 requests RSS to be performed on the outermost packet + * encapsulation level. + * + * - @p 2 and subsequent values request RSS to be performed on the + * specified inner packet encapsulation level, from outermost to + * innermost (lower to higher values). + * + * Values other than @p 0 are not necessarily supported. + * + * Requesting a specific RSS level on unrecognized traffic results + * in undefined behavior. For predictable results, it is recommended + * to make the flow rule pattern match packet headers up to the + * requested encapsulation level so that only matching traffic goes + * through. + */ + uint32_t level; uint64_t types; /**< RSS hash types (see ETH_RSS_*). */ uint32_t key_len; /**< Hash key length in bytes. */ uint32_t queue_num; /**< Number of entries in @p queue. */ -- 2.11.0