[PATCH v3 0/3] support match icmpv6 ID and sequence
Currently, rte_flow API does not support matching ID and sequence fields of icmp6 echo packets. This patchset is used to support match icmpv6 ID and sequence in rte_flow. It adds needed API in rte_flow, and gives corresponding implementation for mlx5 pmd. --- v2: * rebase 23.03 --- v3: * Merge content of rte_icmp6.h into rte_icmp.h. Just keep one header file(rte_icmp.h) for icmp. * Correct some code style problems. Leo Xu (3): ethdev: add ICMPv6 ID and sequence net/mlx5: add ICMPv6 ID and sequence match support net/mlx5/hws: add ICMPv6 ID and sequence match support .mailmap| 1 + app/test-pmd/cmdline_flow.c | 70 doc/guides/nics/features/default.ini| 2 + doc/guides/nics/features/mlx5.ini | 2 + doc/guides/nics/mlx5.rst| 4 +- doc/guides/prog_guide/rte_flow.rst | 14 doc/guides/rel_notes/release_23_03.rst | 9 +++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 +++ drivers/net/mlx5/hws/mlx5dr_definer.c | 88 + drivers/net/mlx5/mlx5_flow.c| 61 ++ drivers/net/mlx5/mlx5_flow.h| 4 + drivers/net/mlx5/mlx5_flow_dv.c | 76 ++ drivers/net/mlx5/mlx5_flow_hw.c | 2 + lib/ethdev/rte_flow.c | 2 + lib/ethdev/rte_flow.h | 24 ++ lib/net/rte_icmp.h | 22 ++ 16 files changed, 389 insertions(+), 2 deletions(-) -- 2.27.0
[PATCH v3 1/3] ethdev: add ICMPv6 ID and sequence
This patch adds API support for ICMPv6 ID and sequence. 1: Add two new pattern item types for ICMPv6 echo request and reply: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY 2: Add new structures for ICMP packet definitions. struct rte_icmp_base_hdr; # For basic header of all ICMP/ICMPv6 header struct rte_icmp_echo_hdr; # For ICMP/ICMPv6 echo header The existing struct rte_icmp_hdr should not be used in new code. It should be set to be deprecated in future. The reason for that is, icmp_ident/icmp_seq_nb are not common fields of ICMP/ICMPv6 packets. 3: Enhance testpmd flow pattern to support ICMPv6 identifier and sequence. Example of ICMPv6 echo pattern in testpmd command: pattern eth / ipv6 / icmp6_echo_request / end pattern eth / ipv6 / icmp6_echo_reply / end pattern eth / ipv6 / icmp6_echo_request ident is 20 seq is 30 / end Signed-off-by: Leo Xu Acked-by: Ori Kam --- .mailmap| 1 + app/test-pmd/cmdline_flow.c | 70 + doc/guides/nics/features/default.ini| 2 + doc/guides/prog_guide/rte_flow.rst | 14 + doc/guides/rel_notes/release_23_03.rst | 5 ++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 +++ lib/ethdev/rte_flow.c | 2 + lib/ethdev/rte_flow.h | 24 +++ lib/net/rte_icmp.h | 22 +++ 9 files changed, 150 insertions(+) diff --git a/.mailmap b/.mailmap index 75884b6fe2..310853bd5e 100644 --- a/.mailmap +++ b/.mailmap @@ -728,6 +728,7 @@ Lei Gong Lei Ji Lei Yao Leonid Myravjev +Leo Xu Leszek Zygo Levend Sayar Lev Faerman diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 88108498e0..97ab742abd 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -360,6 +360,12 @@ enum index { ITEM_ICMP6, ITEM_ICMP6_TYPE, ITEM_ICMP6_CODE, + ITEM_ICMP6_ECHO_REQUEST, + ITEM_ICMP6_ECHO_REQUEST_ID, + ITEM_ICMP6_ECHO_REQUEST_SEQ, + ITEM_ICMP6_ECHO_REPLY, + ITEM_ICMP6_ECHO_REPLY_ID, + ITEM_ICMP6_ECHO_REPLY_SEQ, ITEM_ICMP6_ND_NS, ITEM_ICMP6_ND_NS_TARGET_ADDR, ITEM_ICMP6_ND_NA, @@ -1327,6 +1333,8 @@ static const enum index next_item[] = { ITEM_IPV6_EXT, ITEM_IPV6_FRAG_EXT, ITEM_ICMP6, + ITEM_ICMP6_ECHO_REQUEST, + ITEM_ICMP6_ECHO_REPLY, ITEM_ICMP6_ND_NS, ITEM_ICMP6_ND_NA, ITEM_ICMP6_ND_OPT, @@ -1575,6 +1583,20 @@ static const enum index item_icmp6[] = { ZERO, }; +static const enum index item_icmp6_echo_request[] = { + ITEM_ICMP6_ECHO_REQUEST_ID, + ITEM_ICMP6_ECHO_REQUEST_SEQ, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_echo_reply[] = { + ITEM_ICMP6_ECHO_REPLY_ID, + ITEM_ICMP6_ECHO_REPLY_SEQ, + ITEM_NEXT, + ZERO, +}; + static const enum index item_icmp6_nd_ns[] = { ITEM_ICMP6_ND_NS_TARGET_ADDR, ITEM_NEXT, @@ -4323,6 +4345,54 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, code)), }, + [ITEM_ICMP6_ECHO_REQUEST] = { + .name = "icmp6_echo_request", + .help = "match ICMPv6 echo request", + .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, + sizeof(struct rte_flow_item_icmp6_echo)), + .next = NEXT(item_icmp6_echo_request), + .call = parse_vc, + }, + [ITEM_ICMP6_ECHO_REQUEST_ID] = { + .name = "ident", + .help = "ICMPv6 echo request identifier", + .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +hdr.identifier)), + }, + [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { + .name = "seq", + .help = "ICMPv6 echo request sequence", + .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +hdr.sequence)), + }, + [ITEM_ICMP6_ECHO_REPLY] = { + .name = "icmp6_echo_reply", + .help = "match ICMPv6 echo reply", + .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, + sizeof(struct rte_flow_item_icmp6_echo)), + .next = NEXT(item_icmp6_echo_reply), + .call = parse_vc, + }, + [ITEM_ICMP6_ECHO_REPLY_ID] = { + .name = "ident", +
[PATCH v3 2/3] net/mlx5: add ICMPv6 ID and sequence match support
This patch adds ICMPv6 ID and sequence match support. Since type and code of ICMPv6 echo is already specified by ITEM type: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY mlx5 pmd will set appropriate type and code automatically: Echo request: type(128), code(0) Echo reply: type(129), code(0) type and code provided by application will be ignored. Signed-off-by: Leo Xu --- doc/guides/nics/features/mlx5.ini | 2 + doc/guides/nics/mlx5.rst | 4 +- doc/guides/rel_notes/release_23_03.rst | 4 ++ drivers/net/mlx5/mlx5_flow.c | 61 + drivers/net/mlx5/mlx5_flow.h | 4 ++ drivers/net/mlx5/mlx5_flow_dv.c| 76 ++ drivers/net/mlx5/mlx5_flow_hw.c| 2 + 7 files changed, 151 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/features/mlx5.ini b/doc/guides/nics/features/mlx5.ini index 62fd330e2b..eb016f34da 100644 --- a/doc/guides/nics/features/mlx5.ini +++ b/doc/guides/nics/features/mlx5.ini @@ -69,6 +69,8 @@ gtp = Y gtp_psc = Y icmp = Y icmp6= Y +icmp6_echo_request = Y +icmp6_echo_reply = Y integrity= Y ipv4 = Y ipv6 = Y diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index f137f156f9..9c6f1cca19 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -405,8 +405,8 @@ Limitations - The input buffer, providing the removal size, is not validated. - The buffer size must match the length of the headers to be removed. -- ICMP(code/type/identifier/sequence number) / ICMP6(code/type) matching, IP-in-IP and MPLS flow matching are all - mutually exclusive features which cannot be supported together +- ICMP(code/type/identifier/sequence number) / ICMP6(code/type/identifier/sequence number) matching, + IP-in-IP and MPLS flow matching are all mutually exclusive features which cannot be supported together (see :ref:`mlx5_firmware_config`). - LRO: diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index 3f5c7af3b6..cac69e3173 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -74,6 +74,10 @@ New Features * Added flow items to match ICMPv6 echo request and reply packets. Matching patterns can include ICMP identifier and sequence numbers. +* **Updated Mellanox mlx5 driver.** + + * Added support for matching on ICMPv6 ID and sequence fields. + Removed Items - diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index f5e2831480..b38062c70e 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2352,6 +2352,67 @@ mlx5_flow_validate_item_icmp6(const struct rte_flow_item *item, return 0; } +/** + * Validate ICMP6 echo request/reply item. + * + * @param[in] item + * Item specification. + * @param[in] item_flags + * Bit-fields that holds the items detected until now. + * @param[in] ext_vlan_sup + * Whether extended VLAN features are supported or not. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_validate_item_icmp6_echo(const struct rte_flow_item *item, + uint64_t item_flags, + uint8_t target_protocol, + struct rte_flow_error *error) +{ + const struct rte_flow_item_icmp6_echo *mask = item->mask; + const struct rte_flow_item_icmp6_echo nic_mask = { + .hdr.base.type = 0xff, + .hdr.base.code = 0xff, + .hdr.identifier = RTE_BE16(0x), + .hdr.sequence = RTE_BE16(0x), + }; + const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : + MLX5_FLOW_LAYER_OUTER_L3_IPV6; + const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 : + MLX5_FLOW_LAYER_OUTER_L4; + int ret; + + if (target_protocol != 0xFF && target_protocol != IPPROTO_ICMPV6) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "protocol filtering not compatible" + " with ICMP6 layer"); + if (!(item_flags & l3m)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "IPv6 is mandatory to filter on" + " ICMP6"); + if (item_flags &am
[PATCH v3 3/3] net/mlx5/hws: add ICMPv6 ID and sequence match support
This patch adds ICMPv6 ID and sequence match support for HWS. Since type and code of ICMPv6 echo is already specified by ITEM type: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY mlx5 pmd will set appropriate type and code automatically: Echo request: type(128), code(0) Echo reply: type(129), code(0) type and code provided by application will be ignored Signed-off-by: Leo Xu --- drivers/net/mlx5/hws/mlx5dr_definer.c | 88 +++ 1 file changed, 88 insertions(+) diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 6b98eb8c96..d56e85631d 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -368,6 +368,47 @@ mlx5dr_definer_icmp6_dw1_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_icmp6_echo_dw1_mask_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {0xFF, 0xFF, 0x0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_request_dw1_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REQUEST, 0, 0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_reply_dw1_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REPLY, 0, 0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_dw2_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6_echo *v = item_spec; + rte_be32_t dw2; + + dw2 = (rte_be_to_cpu_16(v->hdr.identifier) << __mlx5_dw_bit_off(header_icmp, ident)) | + (rte_be_to_cpu_16(v->hdr.sequence) << __mlx5_dw_bit_off(header_icmp, seq_nb)); + + DR_SET(tag, dw2, fc->byte_off, fc->bit_off, fc->bit_mask); +} + static void mlx5dr_definer_ipv6_flow_label_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -1441,6 +1482,48 @@ mlx5dr_definer_conv_item_icmp6(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +mlx5dr_definer_conv_item_icmp6_echo(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_icmp6_echo *m = item->mask; + struct mlx5dr_definer_fc *fc; + bool inner = cd->tunnel; + + if (!cd->relaxed) { + /* Overwrite match on L4 type ICMP6 */ + fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_icmp_protocol_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + DR_CALC_SET(fc, eth_l2, l4_type, inner); + + /* Set fixed type and code for icmp6 echo request/reply */ + fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW1]; + fc->item_idx = item_idx; + fc->tag_mask_set = &mlx5dr_definer_icmp6_echo_dw1_mask_set; + if (item->type == RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST) + fc->tag_set = &mlx5dr_definer_icmp6_echo_request_dw1_set; + else /* RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY */ + fc->tag_set = &mlx5dr_definer_icmp6_echo_reply_dw1_set; + DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw1); + } + + if (!m) + return 0; + + /* Set identifier & sequence into icmp_dw2 */ + if (m->hdr.identifier || m->hdr.sequence) { + fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW2]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_icmp6_echo_dw2_set; + DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw2); + } + + return 0; +} + static int mlx5dr_definer_conv_item_meter_color(struct mlx5dr_definer_conv_data *cd, struct rte_flow_item *item, @@ -1577,6 +1660,11 @@ mlx5dr_definer_conv_items_to_hl(struct mlx5dr_context *ctx, ret = mlx5dr_definer_conv_item_icmp6(&cd, items, i); it
[PATCH 0/3] support match icmpv6 id and sequence
Currently, rte_flow API does not support matching id and sequence fields of icmp6 echo packets. This patchset is used to support match icmpv6 id and sequence in rte_flow. It adds needed API in rte_flow, and gives corresponding implementation for mlx5 pmd. Leo Xu (3): ethdev: add ICMPv6 id and sequence net/mlx5: add ICMPv6 id and sequence match support net/mlx5/hws: add ICMPv6 id and sequence match support app/test-pmd/cmdline_flow.c | 70 + doc/guides/nics/mlx5.rst| 2 +- doc/guides/prog_guide/rte_flow.rst | 14 +++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 ++ drivers/net/mlx5/mlx5_flow.c| 61 +++ drivers/net/mlx5/mlx5_flow.h| 4 + drivers/net/mlx5/mlx5_flow_dv.c | 76 ++ drivers/net/mlx5/mlx5_flow_hw.c | 2 + drivers/net/mlx5/steering/mlx5dr_definer.c | 110 ++-- drivers/net/mlx5/steering/mlx5dr_definer.h | 6 +- lib/librte_ethdev/rte_flow.c| 4 + lib/librte_ethdev/rte_flow.h| 25 + lib/librte_net/meson.build | 3 +- lib/librte_net/rte_icmp6.h | 48 + 14 files changed, 419 insertions(+), 16 deletions(-) create mode 100644 lib/librte_net/rte_icmp6.h -- 2.27.0
[PATCH 1/3] ethdev: add ICMPv6 id and sequence
This patch adds API support for ICMPv6 id and sequence. 1: Add two new pattern item types for ICMPv6 echo request and reply: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY 2: Add new header file rte_icmp6.h for ICMPv6 packet definitions. 3: Enhance testpmd flow pattern to support ICMPv6 identifier and sequence. Example of ICMPv6 echo pattern in testpmd command: pattern eth / ipv6 / icmp6_echo_request / end pattern eth / ipv6 / icmp6_echo_reply / end pattern eth / ipv6 / icmp6_echo_request ident is 20 seq is 30 / end Signed-off-by: Leo Xu Signed-off-by: Bing Zhao --- app/test-pmd/cmdline_flow.c | 70 + doc/guides/prog_guide/rte_flow.rst | 14 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 +++ lib/librte_ethdev/rte_flow.c| 4 ++ lib/librte_ethdev/rte_flow.h| 25 lib/librte_net/meson.build | 3 +- lib/librte_net/rte_icmp6.h | 48 ++ 7 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 lib/librte_net/rte_icmp6.h diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index ce8035cb46..413ef905f2 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -375,6 +375,12 @@ enum index { ITEM_ICMP6, ITEM_ICMP6_TYPE, ITEM_ICMP6_CODE, + ITEM_ICMP6_ECHO_REQUEST, + ITEM_ICMP6_ECHO_REQUEST_ID, + ITEM_ICMP6_ECHO_REQUEST_SEQ, + ITEM_ICMP6_ECHO_REPLY, + ITEM_ICMP6_ECHO_REPLY_ID, + ITEM_ICMP6_ECHO_REPLY_SEQ, ITEM_ICMP6_ND_NS, ITEM_ICMP6_ND_NS_TARGET_ADDR, ITEM_ICMP6_ND_NA, @@ -1373,6 +1379,8 @@ static const enum index next_item[] = { ITEM_IPV6_EXT, ITEM_IPV6_FRAG_EXT, ITEM_ICMP6, + ITEM_ICMP6_ECHO_REQUEST, + ITEM_ICMP6_ECHO_REPLY, ITEM_ICMP6_ND_NS, ITEM_ICMP6_ND_NA, ITEM_ICMP6_ND_OPT, @@ -1629,6 +1637,20 @@ static const enum index item_icmp6[] = { ZERO, }; +static const enum index item_icmp6_echo_request[] = { + ITEM_ICMP6_ECHO_REQUEST_ID, + ITEM_ICMP6_ECHO_REQUEST_SEQ, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_echo_reply[] = { + ITEM_ICMP6_ECHO_REPLY_ID, + ITEM_ICMP6_ECHO_REPLY_SEQ, + ITEM_NEXT, + ZERO, +}; + static const enum index item_icmp6_nd_ns[] = { ITEM_ICMP6_ND_NS_TARGET_ADDR, ITEM_NEXT, @@ -4432,6 +4454,54 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, code)), }, + [ITEM_ICMP6_ECHO_REQUEST] = { + .name = "icmp6_echo_request", + .help = "match ICMPv6 echo request", + .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, + sizeof(struct rte_flow_item_icmp6_echo)), + .next = NEXT(item_icmp6_echo_request), + .call = parse_vc, + }, + [ITEM_ICMP6_ECHO_REQUEST_ID] = { + .name = "ident", + .help = "ICMPv6 echo request identifier", + .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +echo.identifier)), + }, + [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { + .name = "seq", + .help = "ICMPv6 echo request sequence", + .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +echo.sequence)), + }, + [ITEM_ICMP6_ECHO_REPLY] = { + .name = "icmp6_echo_reply", + .help = "match ICMPv6 echo reply", + .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, + sizeof(struct rte_flow_item_icmp6_echo)), + .next = NEXT(item_icmp6_echo_reply), + .call = parse_vc, + }, + [ITEM_ICMP6_ECHO_REPLY_ID] = { + .name = "ident", + .help = "ICMPv6 echo reply identifier", + .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +echo.identifier)), + }, + [ITEM_ICMP6_ECHO_REPLY_SEQ] = { + .name = "seq", + .help = "ICMPv6 echo reply sequence", + .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(UNSIGNED)
[PATCH 2/3] net/mlx5: add ICMPv6 id and sequence match support
This patch adds ICMPv6 id and sequence match support. Since type and code of ICMPv6 echo is already specified by ITEM type: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY mlx5 pmd will set appropriate type and code automatically: Echo request: type(128), code(0) Echo reply: type(129), code(0) type and code provided by application will be ignored. Signed-off-by: Leo Xu --- doc/guides/nics/mlx5.rst| 2 +- drivers/net/mlx5/mlx5_flow.c| 61 ++ drivers/net/mlx5/mlx5_flow.h| 4 ++ drivers/net/mlx5/mlx5_flow_dv.c | 76 + drivers/net/mlx5/mlx5_flow_hw.c | 2 + 5 files changed, 144 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 328c728f13..d17bb1fe47 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -328,7 +328,7 @@ Limitations - The input buffer, providing the removal size, is not validated. - The buffer size must match the length of the headers to be removed. -- ICMP(code/type/identifier/sequence number) / ICMP6(code/type) matching, IP-in-IP and MPLS flow matching are all +- ICMP(code/type/identifier/sequence number) / ICMP6(code/type/identifier/sequence number) matching, IP-in-IP and MPLS flow matching are all mutually exclusive features which cannot be supported together (see :ref:`mlx5_firmware_config`). diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index 114451b872..bf6a3010ca 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2442,6 +2442,67 @@ mlx5_flow_validate_item_icmp6(const struct rte_flow_item *item, return 0; } +/** + * Validate ICMP6 echo request/reply item. + * + * @param[in] item + * Item specification. + * @param[in] item_flags + * Bit-fields that holds the items detected until now. + * @param[in] ext_vlan_sup + * Whether extended VLAN features are supported or not. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_validate_item_icmp6_echo(const struct rte_flow_item *item, + uint64_t item_flags, + uint8_t target_protocol, + struct rte_flow_error *error) +{ + const struct rte_flow_item_icmp6_echo *mask = item->mask; + const struct rte_flow_item_icmp6_echo nic_mask = { + .echo.hdr.type = 0xff, + .echo.hdr.code = 0xff, + .echo.identifier = RTE_BE16(0x), + .echo.sequence = RTE_BE16(0x), + }; + const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : + MLX5_FLOW_LAYER_OUTER_L3_IPV6; + const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 : + MLX5_FLOW_LAYER_OUTER_L4; + int ret; + + if (target_protocol != 0xFF && target_protocol != IPPROTO_ICMPV6) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "protocol filtering not compatible" + " with ICMP6 layer"); + if (!(item_flags & l3m)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "IPv6 is mandatory to filter on" + " ICMP6"); + if (item_flags & l4m) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "multiple L4 layers not supported"); + if (!mask) + mask = &nic_mask; + ret = mlx5_flow_item_acceptable + (item, (const uint8_t *)mask, +(const uint8_t *)&nic_mask, +sizeof(struct rte_flow_item_icmp6_echo), +MLX5_ITEM_RANGE_NOT_ACCEPTED, error); + if (ret < 0) + return ret; + return 0; +} + /** * Validate ICMP item. * diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h index 322ffc5651..e9d763cd4c 100644 --- a/drivers/net/mlx5/mlx5_flow.h +++ b/drivers/net/mlx5/mlx5_flow.h @@ -2333,6 +2333,10 @@ int mlx5_flow_validate_item_icmp6(const struct rte_flow_item *item, uint64_t item_flags, uint8_t target_protocol, struct rte_flow_error *error); +int mlx5_flow_validate_item_icmp6_echo(const struct rte_flow_item *item, +
[PATCH 3/3] net/mlx5/hws: add ICMPv6 id and sequence match support
This patch adds ICMPv6 id and sequence match support for HWS. Since type and code of ICMPv6 echo is already specified by ITEM type: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY mlx5 pmd will set appropriate type and code automatically: Echo request: type(128), code(0) Echo reply: type(129), code(0) type and code provided by application will be ignored This patch also fixes these issues in ICMP definer. 1. Parsing inner ICMP item gets and overwrites the outer IP_PROTOCOL function, which will remove the outer L4 match incorrectly. Fix this by getting correct inner function. 2. Member order of mlx5_ifc_header_icmp_bits doesn't follow ICMP format. Reorder them to make it more consistent. Signed-off-by: Leo Xu Signed-off-by: Shun Hao --- drivers/net/mlx5/steering/mlx5dr_definer.c | 110 ++--- drivers/net/mlx5/steering/mlx5dr_definer.h | 6 +- 2 files changed, 102 insertions(+), 14 deletions(-) diff --git a/drivers/net/mlx5/steering/mlx5dr_definer.c b/drivers/net/mlx5/steering/mlx5dr_definer.c index 9bb0f3b117..96da706ee2 100644 --- a/drivers/net/mlx5/steering/mlx5dr_definer.c +++ b/drivers/net/mlx5/steering/mlx5dr_definer.c @@ -316,9 +316,9 @@ mlx5dr_definer_icmp_dw1_set(struct mlx5dr_definer_fc *fc, icmp_dw1 = (v->hdr.icmp_type << __mlx5_dw_bit_off(header_icmp, type)) | (v->hdr.icmp_code << __mlx5_dw_bit_off(header_icmp, code)) | - (v->hdr.icmp_cksum << __mlx5_dw_bit_off(header_icmp, cksum)); + (rte_be_to_cpu_16(v->hdr.icmp_cksum) << __mlx5_dw_bit_off(header_icmp, cksum)); - DR_SET_BE32(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask); + DR_SET(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask); } static void @@ -329,10 +329,10 @@ mlx5dr_definer_icmp_dw2_set(struct mlx5dr_definer_fc *fc, const struct rte_flow_item_icmp *v = item_spec; rte_be32_t icmp_dw2; - icmp_dw2 = (v->hdr.icmp_ident << __mlx5_dw_bit_off(header_icmp, ident)) | - (v->hdr.icmp_seq_nb << __mlx5_dw_bit_off(header_icmp, seq_nb)); + icmp_dw2 = (rte_be_to_cpu_16(v->hdr.icmp_ident) << __mlx5_dw_bit_off(header_icmp, ident)) | + (rte_be_to_cpu_16(v->hdr.icmp_seq_nb) << __mlx5_dw_bit_off(header_icmp, seq_nb)); - DR_SET_BE32(tag, icmp_dw2, fc->byte_off, fc->bit_off, fc->bit_mask); + DR_SET(tag, icmp_dw2, fc->byte_off, fc->bit_off, fc->bit_mask); } static void @@ -345,9 +345,50 @@ mlx5dr_definer_icmp6_dw1_set(struct mlx5dr_definer_fc *fc, icmp_dw1 = (v->type << __mlx5_dw_bit_off(header_icmp, type)) | (v->code << __mlx5_dw_bit_off(header_icmp, code)) | - (v->checksum << __mlx5_dw_bit_off(header_icmp, cksum)); + (rte_be_to_cpu_16(v->checksum) << __mlx5_dw_bit_off(header_icmp, cksum)); - DR_SET_BE32(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask); + DR_SET(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask); +} + +static void +mlx5dr_definer_icmp6_echo_dw1_mask_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {0xFF, 0xFF, 0x0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_request_dw1_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REQUEST, 0, 0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_reply_dw1_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REPLY, 0, 0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_dw2_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6_echo *v = item_spec; + rte_be32_t dw2; + + dw2 = (rte_be_to_cpu_16(v->echo.identifier) << __mlx5_dw_bit_off(header_icmp, ident)) | + (rte_be_to_cpu_16(v->echo.sequence) << __mlx5_dw_bit_off(header_icmp, seq_nb)); + + DR_SET(tag, dw2, fc->byte_off, fc->bit_off, fc->bit_mask); } static void @@ -1419,9 +1460,9 @@ mlx5dr_definer_conv_item_icmp(struct mlx5dr_definer_conv_data *cd, struct mlx5dr
[PATCH v2 0/3] support match icmpv6 ID and sequence
Currently, rte_flow API does not support matching ID and sequence fields of icmp6 echo packets. This patchset is used to support match icmpv6 ID and sequence in rte_flow. It adds needed API in rte_flow, and gives corresponding implementation for mlx5 pmd. Leo Xu (3): ethdev: add ICMPv6 ID and sequence net/mlx5: add ICMPv6 ID and sequence match support net/mlx5/hws: add ICMPv6 ID and sequence match support --- v2: * rebase 23.03 app/test-pmd/cmdline_flow.c | 70 doc/guides/nics/mlx5.rst| 2 +- doc/guides/prog_guide/rte_flow.rst | 14 doc/guides/rel_notes/release_23_03.rst | 10 +++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 +++ drivers/net/mlx5/hws/mlx5dr_definer.c | 88 + drivers/net/mlx5/mlx5_flow.c| 61 ++ drivers/net/mlx5/mlx5_flow.h| 4 + drivers/net/mlx5/mlx5_flow_dv.c | 76 ++ drivers/net/mlx5/mlx5_flow_hw.c | 2 + lib/ethdev/rte_flow.c | 4 + lib/ethdev/rte_flow.h | 25 ++ lib/net/meson.build | 1 + lib/net/rte_icmp6.h | 48 +++ 14 files changed, 414 insertions(+), 1 deletion(-) create mode 100644 lib/net/rte_icmp6.h -- 2.27.0
[PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence
This patch adds API support for ICMPv6 ID and sequence. 1: Add two new pattern item types for ICMPv6 echo request and reply: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY 2: Add new header file rte_icmp6.h for ICMPv6 packet definitions. 3: Enhance testpmd flow pattern to support ICMPv6 identifier and sequence. Example of ICMPv6 echo pattern in testpmd command: pattern eth / ipv6 / icmp6_echo_request / end pattern eth / ipv6 / icmp6_echo_reply / end pattern eth / ipv6 / icmp6_echo_request ident is 20 seq is 30 / end Signed-off-by: Leo Xu Signed-off-by: Bing Zhao --- app/test-pmd/cmdline_flow.c | 70 + doc/guides/prog_guide/rte_flow.rst | 14 + doc/guides/rel_notes/release_23_03.rst | 4 ++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 +++ lib/ethdev/rte_flow.c | 4 ++ lib/ethdev/rte_flow.h | 25 lib/net/meson.build | 1 + lib/net/rte_icmp6.h | 48 ++ 8 files changed, 176 insertions(+) create mode 100644 lib/net/rte_icmp6.h diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 88108498e0..7dc1528899 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -360,6 +360,12 @@ enum index { ITEM_ICMP6, ITEM_ICMP6_TYPE, ITEM_ICMP6_CODE, + ITEM_ICMP6_ECHO_REQUEST, + ITEM_ICMP6_ECHO_REQUEST_ID, + ITEM_ICMP6_ECHO_REQUEST_SEQ, + ITEM_ICMP6_ECHO_REPLY, + ITEM_ICMP6_ECHO_REPLY_ID, + ITEM_ICMP6_ECHO_REPLY_SEQ, ITEM_ICMP6_ND_NS, ITEM_ICMP6_ND_NS_TARGET_ADDR, ITEM_ICMP6_ND_NA, @@ -1327,6 +1333,8 @@ static const enum index next_item[] = { ITEM_IPV6_EXT, ITEM_IPV6_FRAG_EXT, ITEM_ICMP6, + ITEM_ICMP6_ECHO_REQUEST, + ITEM_ICMP6_ECHO_REPLY, ITEM_ICMP6_ND_NS, ITEM_ICMP6_ND_NA, ITEM_ICMP6_ND_OPT, @@ -1575,6 +1583,20 @@ static const enum index item_icmp6[] = { ZERO, }; +static const enum index item_icmp6_echo_request[] = { + ITEM_ICMP6_ECHO_REQUEST_ID, + ITEM_ICMP6_ECHO_REQUEST_SEQ, + ITEM_NEXT, + ZERO, +}; + +static const enum index item_icmp6_echo_reply[] = { + ITEM_ICMP6_ECHO_REPLY_ID, + ITEM_ICMP6_ECHO_REPLY_SEQ, + ITEM_NEXT, + ZERO, +}; + static const enum index item_icmp6_nd_ns[] = { ITEM_ICMP6_ND_NS_TARGET_ADDR, ITEM_NEXT, @@ -4323,6 +4345,54 @@ static const struct token token_list[] = { .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, code)), }, + [ITEM_ICMP6_ECHO_REQUEST] = { + .name = "icmp6_echo_request", + .help = "match ICMPv6 echo request", + .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, + sizeof(struct rte_flow_item_icmp6_echo)), + .next = NEXT(item_icmp6_echo_request), + .call = parse_vc, + }, + [ITEM_ICMP6_ECHO_REQUEST_ID] = { + .name = "ident", + .help = "ICMPv6 echo request identifier", + .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +echo.identifier)), + }, + [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { + .name = "seq", + .help = "ICMPv6 echo request sequence", + .next = NEXT(item_icmp6_echo_request, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +echo.sequence)), + }, + [ITEM_ICMP6_ECHO_REPLY] = { + .name = "icmp6_echo_reply", + .help = "match ICMPv6 echo reply", + .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, + sizeof(struct rte_flow_item_icmp6_echo)), + .next = NEXT(item_icmp6_echo_reply), + .call = parse_vc, + }, + [ITEM_ICMP6_ECHO_REPLY_ID] = { + .name = "ident", + .help = "ICMPv6 echo reply identifier", + .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), +item_param), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, +echo.identifier)), + }, + [ITEM_ICMP6_ECHO_REPLY_SEQ] = { + .name = "seq", + .help = "ICMPv6 echo reply sequence", + .next = NEXT(item_icmp6_echo_reply, NE
[PATCH v2 2/3] net/mlx5: add ICMPv6 ID and sequence match support
This patch adds ICMPv6 ID and sequence match support. Since type and code of ICMPv6 echo is already specified by ITEM type: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY mlx5 pmd will set appropriate type and code automatically: Echo request: type(128), code(0) Echo reply: type(129), code(0) type and code provided by application will be ignored. Signed-off-by: Leo Xu --- doc/guides/nics/mlx5.rst | 2 +- doc/guides/rel_notes/release_23_03.rst | 6 ++ drivers/net/mlx5/mlx5_flow.c | 61 + drivers/net/mlx5/mlx5_flow.h | 4 ++ drivers/net/mlx5/mlx5_flow_dv.c| 76 ++ drivers/net/mlx5/mlx5_flow_hw.c| 2 + 6 files changed, 150 insertions(+), 1 deletion(-) diff --git a/doc/guides/nics/mlx5.rst b/doc/guides/nics/mlx5.rst index 51f51259e3..78693d19b0 100644 --- a/doc/guides/nics/mlx5.rst +++ b/doc/guides/nics/mlx5.rst @@ -405,7 +405,7 @@ Limitations - The input buffer, providing the removal size, is not validated. - The buffer size must match the length of the headers to be removed. -- ICMP(code/type/identifier/sequence number) / ICMP6(code/type) matching, IP-in-IP and MPLS flow matching are all +- ICMP(code/type/identifier/sequence number) / ICMP6(code/type/identifier/sequence number) matching, IP-in-IP and MPLS flow matching are all mutually exclusive features which cannot be supported together (see :ref:`mlx5_firmware_config`). diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index 5af9c43dd9..011c2489f7 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -60,6 +60,12 @@ New Features Added ``icmp6_echo`` item in rte_flow to support ID and sequence matching in ICMPv6 echo request/reply packets. +* **Updated Mellanox mlx5 driver.** + + Updated the Mellanox mlx5 driver with new features and improvements, including: + + * Added support for matching on ICMPv6 ID and sequence fields. + Removed Items - diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index a0cf677fb0..8eea78251e 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -2352,6 +2352,67 @@ mlx5_flow_validate_item_icmp6(const struct rte_flow_item *item, return 0; } +/** + * Validate ICMP6 echo request/reply item. + * + * @param[in] item + * Item specification. + * @param[in] item_flags + * Bit-fields that holds the items detected until now. + * @param[in] ext_vlan_sup + * Whether extended VLAN features are supported or not. + * @param[out] error + * Pointer to error structure. + * + * @return + * 0 on success, a negative errno value otherwise and rte_errno is set. + */ +int +mlx5_flow_validate_item_icmp6_echo(const struct rte_flow_item *item, + uint64_t item_flags, + uint8_t target_protocol, + struct rte_flow_error *error) +{ + const struct rte_flow_item_icmp6_echo *mask = item->mask; + const struct rte_flow_item_icmp6_echo nic_mask = { + .echo.hdr.type = 0xff, + .echo.hdr.code = 0xff, + .echo.identifier = RTE_BE16(0x), + .echo.sequence = RTE_BE16(0x), + }; + const int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + const uint64_t l3m = tunnel ? MLX5_FLOW_LAYER_INNER_L3_IPV6 : + MLX5_FLOW_LAYER_OUTER_L3_IPV6; + const uint64_t l4m = tunnel ? MLX5_FLOW_LAYER_INNER_L4 : + MLX5_FLOW_LAYER_OUTER_L4; + int ret; + + if (target_protocol != 0xFF && target_protocol != IPPROTO_ICMPV6) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "protocol filtering not compatible" + " with ICMP6 layer"); + if (!(item_flags & l3m)) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "IPv6 is mandatory to filter on" + " ICMP6"); + if (item_flags & l4m) + return rte_flow_error_set(error, EINVAL, + RTE_FLOW_ERROR_TYPE_ITEM, item, + "multiple L4 layers not supported"); + if (!mask) + mask = &nic_mask; + ret = mlx5_flow_item_acceptable + (item, (const uint8_t *)mask, +(const uint8_t *)&nic_mask, +sizeof(struct rte_flow_item_icmp6_echo), +MLX5_ITEM_RANGE_NOT_AC
[PATCH v2 3/3] net/mlx5/hws: add ICMPv6 ID and sequence match support
This patch adds ICMPv6 ID and sequence match support for HWS. Since type and code of ICMPv6 echo is already specified by ITEM type: RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY mlx5 pmd will set appropriate type and code automatically: Echo request: type(128), code(0) Echo reply: type(129), code(0) type and code provided by application will be ignored This patch also fixes these issues in ICMP definer. 1. Parsing inner ICMP item gets and overwrites the outer IP_PROTOCOL function, which will remove the outer L4 match incorrectly. Fix this by getting correct inner function. 2. Member order of mlx5_ifc_header_icmp_bits doesn't follow ICMP format. Reorder them to make it more consistent. Signed-off-by: Leo Xu --- drivers/net/mlx5/hws/mlx5dr_definer.c | 88 +++ 1 file changed, 88 insertions(+) diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 6b98eb8c96..8fbc40ff15 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -368,6 +368,47 @@ mlx5dr_definer_icmp6_dw1_set(struct mlx5dr_definer_fc *fc, DR_SET(tag, icmp_dw1, fc->byte_off, fc->bit_off, fc->bit_mask); } +static void +mlx5dr_definer_icmp6_echo_dw1_mask_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {0xFF, 0xFF, 0x0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_request_dw1_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REQUEST, 0, 0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_reply_dw1_set(struct mlx5dr_definer_fc *fc, + __rte_unused const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6 spec = {RTE_ICMP6_ECHO_REPLY, 0, 0}; + mlx5dr_definer_icmp6_dw1_set(fc, &spec, tag); +} + +static void +mlx5dr_definer_icmp6_echo_dw2_set(struct mlx5dr_definer_fc *fc, + const void *item_spec, + uint8_t *tag) +{ + const struct rte_flow_item_icmp6_echo *v = item_spec; + rte_be32_t dw2; + + dw2 = (rte_be_to_cpu_16(v->echo.identifier) << __mlx5_dw_bit_off(header_icmp, ident)) | + (rte_be_to_cpu_16(v->echo.sequence) << __mlx5_dw_bit_off(header_icmp, seq_nb)); + + DR_SET(tag, dw2, fc->byte_off, fc->bit_off, fc->bit_mask); +} + static void mlx5dr_definer_ipv6_flow_label_set(struct mlx5dr_definer_fc *fc, const void *item_spec, @@ -1441,6 +1482,48 @@ mlx5dr_definer_conv_item_icmp6(struct mlx5dr_definer_conv_data *cd, return 0; } +static int +mlx5dr_definer_conv_item_icmp6_echo(struct mlx5dr_definer_conv_data *cd, + struct rte_flow_item *item, + int item_idx) +{ + const struct rte_flow_item_icmp6_echo *m = item->mask; + struct mlx5dr_definer_fc *fc; + bool inner = cd->tunnel; + + if (!cd->relaxed) { + /* Overwrite match on L4 type ICMP6 */ + fc = &cd->fc[DR_CALC_FNAME(IP_PROTOCOL, inner)]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_icmp_protocol_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + DR_CALC_SET(fc, eth_l2, l4_type, inner); + + /* Set fixed type and code for icmp6 echo request/reply */ + fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW1]; + fc->item_idx = item_idx; + fc->tag_mask_set = &mlx5dr_definer_icmp6_echo_dw1_mask_set; + if (item->type == RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST) + fc->tag_set = &mlx5dr_definer_icmp6_echo_request_dw1_set; + else /* RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY */ + fc->tag_set = &mlx5dr_definer_icmp6_echo_reply_dw1_set; + DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw1); + } + + if (!m) + return 0; + + /* Set identifier & sequence into icmp_dw2 */ + if (m->echo.identifier || m->echo.sequence) { + fc = &cd->fc[MLX5DR_DEFINER_FNAME_ICMP_DW2]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_icmp6_echo_dw2_set; + DR_CALC_SET_HDR(fc, tcp_icmp, icmp_dw2); + } + + return 0; +} + static int mlx
RE: [PATCH v2 0/3] support match icmpv6 ID and sequence
Hi, PSB > -Original Message- > From: Ferruh Yigit > Sent: Thursday, January 26, 2023 6:47 PM > To: Leo Xu (Networking SW) > Cc: Matan Azrad ; dev@dpdk.org; Slava Ovsiienko > > Subject: Re: [PATCH v2 0/3] support match icmpv6 ID and sequence > > External email: Use caution opening links or attachments > > > On 12/20/2022 7:44 AM, Leo Xu wrote: > > Currently, rte_flow API does not support matching ID and sequence > > fields of icmp6 echo packets. > > > > This patchset is used to support match icmpv6 ID and sequence in > > rte_flow. It adds needed API in rte_flow, and gives corresponding > > implementation for mlx5 pmd. > > > > Leo Xu (3): > > ethdev: add ICMPv6 ID and sequence > > net/mlx5: add ICMPv6 ID and sequence match support > > net/mlx5/hws: add ICMPv6 ID and sequence match support > > > > --- > > v2: > > * rebase 23.03 > > > > mlx patches are giving following warning: > $ ./devtools/check-doc-vs-code.sh > rte_flow doc out of sync for mlx5 > item icmp6_echo_reply > item icmp6_echo_request Thanks for the catch, will fix it in next PATCH. > > Also can you please make sure driver patches are acked by driver maintainers, > so we can merge all set with ethdev and driver patches together.
RE: [PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence
Hi, PSB > -Original Message- > From: Ferruh Yigit > Sent: Thursday, January 26, 2023 6:45 PM > To: Leo Xu (Networking SW) ; dev@dpdk.org > Cc: Bing Zhao ; Ori Kam ; Aman Singh > ; Yuying Zhang ; > NBU-Contact-Thomas Monjalon (EXTERNAL) ; Andrew > Rybchenko ; Olivier Matz > > Subject: Re: [PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence > > External email: Use caution opening links or attachments > > > On 12/20/2022 7:44 AM, Leo Xu wrote: > > This patch adds API support for ICMPv6 ID and sequence. > > 1: Add two new pattern item types for ICMPv6 echo request and reply: > > RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST > > RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY > > > > 2: Add new header file rte_icmp6.h for ICMPv6 packet definitions. > > 3: Enhance testpmd flow pattern to support ICMPv6 identifier and sequence. > > > > Example of ICMPv6 echo pattern in testpmd command: > > > > pattern eth / ipv6 / icmp6_echo_request / end > > pattern eth / ipv6 / icmp6_echo_reply / end > > pattern eth / ipv6 / icmp6_echo_request ident is 20 seq is 30 / end > > > > Signed-off-by: Leo Xu > > Signed-off-by: Bing Zhao > > --- > > app/test-pmd/cmdline_flow.c | 70 + > > doc/guides/prog_guide/rte_flow.rst | 14 + > > doc/guides/rel_notes/release_23_03.rst | 4 ++ > > doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 +++ > > lib/ethdev/rte_flow.c | 4 ++ > > lib/ethdev/rte_flow.h | 25 > > lib/net/meson.build | 1 + > > lib/net/rte_icmp6.h | 48 ++ > > 8 files changed, 176 insertions(+) > > create mode 100644 lib/net/rte_icmp6.h > > Please update .mailmap with in this patch. Thanks, will update it in next patch. > > > > > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c > > index 88108498e0..7dc1528899 100644 > > --- a/app/test-pmd/cmdline_flow.c > > +++ b/app/test-pmd/cmdline_flow.c > > @@ -360,6 +360,12 @@ enum index { > > ITEM_ICMP6, > > ITEM_ICMP6_TYPE, > > ITEM_ICMP6_CODE, > > + ITEM_ICMP6_ECHO_REQUEST, > > + ITEM_ICMP6_ECHO_REQUEST_ID, > > + ITEM_ICMP6_ECHO_REQUEST_SEQ, > > + ITEM_ICMP6_ECHO_REPLY, > > + ITEM_ICMP6_ECHO_REPLY_ID, > > + ITEM_ICMP6_ECHO_REPLY_SEQ, > > ITEM_ICMP6_ND_NS, > > ITEM_ICMP6_ND_NS_TARGET_ADDR, > > ITEM_ICMP6_ND_NA, > > @@ -1327,6 +1333,8 @@ static const enum index next_item[] = { > > ITEM_IPV6_EXT, > > ITEM_IPV6_FRAG_EXT, > > ITEM_ICMP6, > > + ITEM_ICMP6_ECHO_REQUEST, > > + ITEM_ICMP6_ECHO_REPLY, > > ITEM_ICMP6_ND_NS, > > ITEM_ICMP6_ND_NA, > > ITEM_ICMP6_ND_OPT, > > @@ -1575,6 +1583,20 @@ static const enum index item_icmp6[] = { > > ZERO, > > }; > > > > +static const enum index item_icmp6_echo_request[] = { > > + ITEM_ICMP6_ECHO_REQUEST_ID, > > + ITEM_ICMP6_ECHO_REQUEST_SEQ, > > + ITEM_NEXT, > > + ZERO, > > +}; > > + > > +static const enum index item_icmp6_echo_reply[] = { > > + ITEM_ICMP6_ECHO_REPLY_ID, > > + ITEM_ICMP6_ECHO_REPLY_SEQ, > > + ITEM_NEXT, > > + ZERO, > > +}; > > + > > static const enum index item_icmp6_nd_ns[] = { > > ITEM_ICMP6_ND_NS_TARGET_ADDR, > > ITEM_NEXT, > > @@ -4323,6 +4345,54 @@ static const struct token token_list[] = { > > .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, > >code)), > > }, > > + [ITEM_ICMP6_ECHO_REQUEST] = { > > + .name = "icmp6_echo_request", > > + .help = "match ICMPv6 echo request", > > + .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, > > + sizeof(struct rte_flow_item_icmp6_echo)), > > + .next = NEXT(item_icmp6_echo_request), > > + .call = parse_vc, > > + }, > > + [ITEM_ICMP6_ECHO_REQUEST_ID] = { > > + .name = "ident", > > + .help = "ICMPv6 echo request identifier", > > + .next = NEXT(item_icmp6_echo_request, > NEXT_ENTRY(COMMON_UNSIGNED), > > + item_param), > > + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, > > + echo.identifier)), > > +
RE: [PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence
Hi Thomas, Thanks for those comments. PSB > -Original Message- > From: Thomas Monjalon > Sent: Wednesday, January 18, 2023 5:31 PM > To: Leo Xu (Networking SW) > Cc: dev@dpdk.org; Bing Zhao ; Ori Kam > ; Aman Singh ; Yuying > Zhang ; Ferruh Yigit ; > Andrew Rybchenko ; Olivier Matz > ; david.march...@redhat.com > Subject: Re: [PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence > > External email: Use caution opening links or attachments > > > 20/12/2022 08:44, Leo Xu: > > +* **Added rte_flow support for matching ICMPv6 ID and sequence > > +fields.** > > + > > + Added ``icmp6_echo`` item in rte_flow to support ID and sequence > > + matching in ICMPv6 echo request/reply packets. > > Easier to read: > " > Added flow items to match ICMPv6 echo request and reply packets. > Matching patterns can include ICMP identifier and sequence numbers. > " Thanks for that good sentence, will update accordingly. > > > + /** > > + * Matches an ICMPv6 echo request. > > + * > > + * See struct rte_flow_item_icmp6_echo. > > + */ > > + RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST, > > + > > + /** > > + * Matches an ICMPv6 echo reply. > > + * > > + * See struct rte_flow_item_icmp6_echo. > > + */ > > + RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY, > > It is better to use @see doxygen syntax. Ok, thanks. > > > +/** > > + * RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST > > + * RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY > > + * > > + * Matches an ICMPv6 echo request or reply. > > + */ > > +struct rte_flow_item_icmp6_echo { > > + struct rte_icmp6_echo echo; > > +}; > > Other items are defined with "hdr" as first field (instead of the name "echo" > here). > > > --- a/lib/net/meson.build > > +++ b/lib/net/meson.build > > @@ -22,6 +22,7 @@ headers = files( > > 'rte_geneve.h', > > 'rte_l2tpv2.h', > > 'rte_ppp.h', > > +'rte_icmp6.h', > > ) > > Please insert it after rte_icmp.h. Will merge the rte_icmp6.h into rte_icmp.h, then no rte_icmp6.h any more. > > > +#ifndef _RTE_ICMP6_H_ > > +#define _RTE_ICMP6_H_ > > No need of underscores at the beginning and end, it is not reserved. > Will merge the rte_icmp6.h into rte_icmp.h, then no rte_icmp6.h any more. > [...] > > +/** > > + * ICMP6 header > > + */ > > +struct rte_icmp6_hdr { > > + uint8_t type; > > + uint8_t code; > > + rte_be16_t checksum; > > +} __rte_packed; > > + > > +/** > > + * ICMP6 echo > > + */ > > +struct rte_icmp6_echo { > > + struct rte_icmp6_hdr hdr; > > + rte_be16_t identifier; > > + rte_be16_t sequence; > > +} __rte_packed; > > It is exactly the same as struct rte_icmp_hdr. > Why not reuse it? > Maybe introduce struct rte_icmp_base_hdr and define rte_icmp_echo_hdr as > rte_icmp_hdr? Hi Thomas, Looks like, using rte_icmp_hdr as base header for both icmp and icmpv6 is not that good. since, rte_icmp_hdr default their headers always having id and sequence fields, which is not applicable for most other icmp6/icmp types packets. I may suggest to keep icmp and icmp6 structures independent against each other, because, looks like these two protocols definitions do not share common base. > > > +/* ICMP6 packet types */ > > +#define RTE_ICMP6_ECHO_REQUEST 128 > > +#define RTE_ICMP6_ECHO_REPLY 129 > > Can we avoid adding this file and add only these defines to rte_icmp.h? > Yes, good idea. rte_ip.h does not have independent v6 header file either. We should not create v6 header file for icmp.
RE: [PATCH v2 3/3] net/mlx5/hws: add ICMPv6 ID and sequence match support
Hi Thomas, PSB > -Original Message- > From: Thomas Monjalon > Sent: Wednesday, January 18, 2023 4:58 PM > To: Leo Xu (Networking SW) > Cc: dev@dpdk.org; Matan Azrad ; Slava Ovsiienko > > Subject: Re: [PATCH v2 3/3] net/mlx5/hws: add ICMPv6 ID and sequence match > support > > External email: Use caution opening links or attachments > > > 20/12/2022 08:44, Leo Xu: > > This patch adds ICMPv6 ID and sequence match support for HWS. > > Since type and code of ICMPv6 echo is already specified by ITEM type: > > RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST > > RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY > > mlx5 pmd will set appropriate type and code automatically: > > Echo request: type(128), code(0) > > Echo reply: type(129), code(0) > > type and code provided by application will be ignored > > > > This patch also fixes these issues in ICMP definer. > > 1. Parsing inner ICMP item gets and overwrites the outer IP_PROTOCOL > > function, which will remove the outer L4 match incorrectly. Fix this > > by getting correct inner function. > > 2. Member order of mlx5_ifc_header_icmp_bits doesn't follow ICMP format. > > Reorder them to make it more consistent. > > Please don't fix stuff in the same patch as a new feature. > You should have one patch per fix. > The code for the new feature may be squashed in the other mlx5 patch for the > feature. > Thanks for that good catch. Actually, those "fix stuff" related sentences should be removed. I leave it there by accident. Will remove them, in next patch
RE: [PATCH v2 2/3] net/mlx5: add ICMPv6 ID and sequence match support
Hi Thomas, PSB > -Original Message- > From: Thomas Monjalon > Sent: Wednesday, January 18, 2023 4:55 PM > To: Leo Xu (Networking SW) > Cc: dev@dpdk.org; Matan Azrad ; Slava Ovsiienko > > Subject: Re: [PATCH v2 2/3] net/mlx5: add ICMPv6 ID and sequence match > support > > External email: Use caution opening links or attachments > > > 20/12/2022 08:44, Leo Xu: > > --- a/doc/guides/nics/mlx5.rst > > +++ b/doc/guides/nics/mlx5.rst > > @@ -405,7 +405,7 @@ Limitations > >- The input buffer, providing the removal size, is not validated. > >- The buffer size must match the length of the headers to be removed. > > > > -- ICMP(code/type/identifier/sequence number) / ICMP6(code/type) > matching, IP-in-IP and MPLS flow matching are all > > +- ICMP(code/type/identifier/sequence number) / > ICMP6(code/type/identifier/sequence number) matching, IP-in-IP and MPLS > flow matching are all > > You can split the line after the comma. Ok, thanks. > > >mutually exclusive features which cannot be supported together > >(see :ref:`mlx5_firmware_config`). > > > > diff --git a/doc/guides/rel_notes/release_23_03.rst > b/doc/guides/rel_notes/release_23_03.rst > > index 5af9c43dd9..011c2489f7 100644 > > --- a/doc/guides/rel_notes/release_23_03.rst > > +++ b/doc/guides/rel_notes/release_23_03.rst > > @@ -60,6 +60,12 @@ New Features > >Added ``icmp6_echo`` item in rte_flow to support ID and sequence > >matching in ICMPv6 echo request/reply packets. > > > > +* **Updated Mellanox mlx5 driver.** > > + > > + Updated the Mellanox mlx5 driver with new features and improvements, > including: > > This sentence above can be removed. > We don't have this in recent release notes to keep it short. Ok, thanks, will update it in next patch. > > > + > > + * Added support for matching on ICMPv6 ID and sequence fields. > >
RE: [PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence
Hi Thomas PSB > 31/01/2023 07:53, Leo Xu (Networking SW): > > From: Thomas Monjalon > > > 20/12/2022 08:44, Leo Xu: > > > > +/** > > > > + * ICMP6 header > > > > + */ > > > > +struct rte_icmp6_hdr { > > > > + uint8_t type; > > > > + uint8_t code; > > > > + rte_be16_t checksum; > > > > +} __rte_packed; > > > > + > > > > +/** > > > > + * ICMP6 echo > > > > + */ > > > > +struct rte_icmp6_echo { > > > > + struct rte_icmp6_hdr hdr; > > > > + rte_be16_t identifier; > > > > + rte_be16_t sequence; > > > > +} __rte_packed; > > > > > > It is exactly the same as struct rte_icmp_hdr. > > > Why not reuse it? > > > Maybe introduce struct rte_icmp_base_hdr and define > > > rte_icmp_echo_hdr as rte_icmp_hdr? > > > > Hi Thomas, > > Looks like, using rte_icmp_hdr as base header for both icmp and icmpv6 is > not that good. > > since, rte_icmp_hdr default their headers always having id and sequence > fields, which is not applicable for most other icmp6/icmp types packets. > > > > I may suggest to keep icmp and icmp6 structures independent against each > other, because, looks like these two protocols definitions do not share common > base. > > What about introducing rte_icmp_base_hdr? > We should try to avoid duplicating things. > You mean introduce rte_icmp_base_hdr like following? struct rte_icmp_base_hdr { uint8_t icmp_type; uint8_t icmp_code; rte_be16_t icmp_cksum; } __rte_packed; And change the existing rte_icmp_hdr to be: struct rte_icmp_hdr { rte_icmp_base_hdr bash_hdr; rte_be16_t icmp_ident; rte_be16_t icmp_seq_nb; } __rte_packed; #define rte_icmp6_echo struct rte_icmp_hdr; If it is, there will be some compatibilities issues, since we changed existing structure. Or, maybe I'm missing something. Would you help to give more details about above comment?
RE: [PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence
> 02/02/2023 19:33, Leo Xu (Networking SW): > > > 31/01/2023 07:53, Leo Xu (Networking SW): > > > > From: Thomas Monjalon > > > > > 20/12/2022 08:44, Leo Xu: > > > > > > +/** > > > > > > + * ICMP6 header > > > > > > + */ > > > > > > +struct rte_icmp6_hdr { > > > > > > + uint8_t type; > > > > > > + uint8_t code; > > > > > > + rte_be16_t checksum; > > > > > > +} __rte_packed; > > > > > > + > > > > > > +/** > > > > > > + * ICMP6 echo > > > > > > + */ > > > > > > +struct rte_icmp6_echo { > > > > > > + struct rte_icmp6_hdr hdr; > > > > > > + rte_be16_t identifier; > > > > > > + rte_be16_t sequence; > > > > > > +} __rte_packed; > > > > > > > > > > It is exactly the same as struct rte_icmp_hdr. > > > > > Why not reuse it? > > > > > Maybe introduce struct rte_icmp_base_hdr and define > > > > > rte_icmp_echo_hdr as rte_icmp_hdr? > > > > > > > > Hi Thomas, > > > > Looks like, using rte_icmp_hdr as base header for both icmp and > > > > icmpv6 is > > > not that good. > > > > since, rte_icmp_hdr default their headers always having id and > > > > sequence > > > fields, which is not applicable for most other icmp6/icmp types packets. > > > > > > > > I may suggest to keep icmp and icmp6 structures independent > > > > against each > > > other, because, looks like these two protocols definitions do not > > > share common base. > > > > > > What about introducing rte_icmp_base_hdr? > > > We should try to avoid duplicating things. > > > > > > > You mean introduce rte_icmp_base_hdr like following? > > struct rte_icmp_base_hdr { > > uint8_t icmp_type; > > uint8_t icmp_code; > > rte_be16_t icmp_cksum; > > } __rte_packed; > > > > And change the existing rte_icmp_hdr to be: > > struct rte_icmp_hdr { > > rte_icmp_base_hdr bash_hdr; > > rte_be16_t icmp_ident; > > rte_be16_t icmp_seq_nb; > > } __rte_packed; > > #define rte_icmp6_echo struct rte_icmp_hdr; > > > > If it is, there will be some compatibilities issues, since we changed > > existing > structure. > > > > Or, maybe I'm missing something. > > Would you help to give more details about above comment? > > Currently we have this: > struct rte_icmp_hdr { > uint8_t icmp_type; /* ICMP packet type. */ > uint8_t icmp_code; /* ICMP packet code. */ > rte_be16_t icmp_cksum; /* ICMP packet checksum. */ > rte_be16_t icmp_ident; /* ICMP packet identifier. */ > rte_be16_t icmp_seq_nb; /* ICMP packet sequence number. */ } > __rte_packed; > > I agree we can move some fields in a base struct, it would change the API. > We could manage with a union, but we would lose the benefit. > It looks like we need to keep rte_icmp_hdr as is. > So we need to duplicate and define new structs. > > What about removing the "6" from the new structs, so it would apply both to > IPv4 and IPv6? > > struct rte_icmp_base_hdr { > uint8_t type; > uint8_t code; > rte_be16_t checksum; > } __rte_packed; > > struct rte_icmp_echo_hdr { > struct rte_icmp_base_hdr base; > rte_be16_t identifier; > rte_be16_t sequence; > } __rte_packed; > > I agree with that proposal. Then, we can deem existing struct rte_icmp_hdr as old one, which should not be used in new app. And looks like, these new defined structures can cover all ICMP4/6 formats. Good idea! I will update accordingly, in next patch.