> -----Original Message----- > From: Dekel Peled <dek...@mellanox.com> > Sent: Tuesday, July 2, 2019 17:44 > To: Adrien Mazarguil <adrien.mazarg...@6wind.com>; > wenzhuo...@intel.com; jingjing...@intel.com; > bernard.iremon...@intel.com; Yongseok Koh <ys...@mellanox.com>; > Shahaf Shuler <shah...@mellanox.com>; Slava Ovsiienko > <viachesl...@mellanox.com>; arybche...@solarflare.com > Cc: dev@dpdk.org; Ori Kam <or...@mellanox.com> > Subject: [PATCH v10 3/3] net/mlx5: update modify header using Direct Verbs > > This patch implements additional actions of packet header > modifications. > > Add actions: > - INC_TCP_SEQ - Increase sequence number in the outermost TCP header. > - DEC_TCP_SEQ - Decrease sequence number in the outermost TCP header. > - INC_TCP_ACK - Increase acknowledgment number in the outermost TCP > header. > - DEC_TCP_ACK - Decrease acknowledgment number in the outermost TCP > header. > > Original work by Xiaoyu Min. > > Signed-off-by: Dekel Peled <dek...@mellanox.com> Acked-by: Viacheslav Ovsiienko <viachesl...@mellanox.com>
> --- > doc/guides/rel_notes/release_19_08.rst | 7 + > drivers/net/mlx5/mlx5_flow.h | 10 +- > drivers/net/mlx5/mlx5_flow_dv.c | 237 > +++++++++++++++++++++++++++++++++ > drivers/net/mlx5/mlx5_prm.h | 12 ++ > 4 files changed, 265 insertions(+), 1 deletion(-) > > diff --git a/doc/guides/rel_notes/release_19_08.rst > b/doc/guides/rel_notes/release_19_08.rst > index 3da2667..450d22f 100644 > --- a/doc/guides/rel_notes/release_19_08.rst > +++ b/doc/guides/rel_notes/release_19_08.rst > @@ -74,6 +74,13 @@ New Features > > * Enabled Tx outer/inner L3/L4 checksum offload. > > +* **Updated Mellanox mlx5 driver.** > + > + Updated Mellanox mlx5 driver with new features and improvements, > including: > + > + * Updated the packet header modification feature. Added support of TCP > header > + sequence number and acknowledgment number modification. > + > * **Updated Solarflare network PMD.** > > Updated the Solarflare ``sfc_efx`` driver with changes including: > diff --git a/drivers/net/mlx5/mlx5_flow.h b/drivers/net/mlx5/mlx5_flow.h > index b665420..dc4a56a 100644 > --- a/drivers/net/mlx5/mlx5_flow.h > +++ b/drivers/net/mlx5/mlx5_flow.h > @@ -114,6 +114,10 @@ > #define MLX5_FLOW_ACTION_NVGRE_DECAP (1u << 25) > #define MLX5_FLOW_ACTION_RAW_ENCAP (1u << 26) > #define MLX5_FLOW_ACTION_RAW_DECAP (1u << 27) > +#define MLX5_FLOW_ACTION_INC_TCP_SEQ (1u << 28) > +#define MLX5_FLOW_ACTION_DEC_TCP_SEQ (1u << 29) > +#define MLX5_FLOW_ACTION_INC_TCP_ACK (1u << 30) > +#define MLX5_FLOW_ACTION_DEC_TCP_ACK (1u << 31) > > #define MLX5_FLOW_FATE_ACTIONS \ > (MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \ > @@ -140,7 +144,11 @@ > MLX5_FLOW_ACTION_SET_TTL | \ > MLX5_FLOW_ACTION_DEC_TTL | \ > MLX5_FLOW_ACTION_SET_MAC_SRC | \ > - MLX5_FLOW_ACTION_SET_MAC_DST) > + MLX5_FLOW_ACTION_SET_MAC_DST | \ > + MLX5_FLOW_ACTION_INC_TCP_SEQ | \ > + MLX5_FLOW_ACTION_DEC_TCP_SEQ | \ > + MLX5_FLOW_ACTION_INC_TCP_ACK | \ > + MLX5_FLOW_ACTION_DEC_TCP_ACK) > > #ifndef IPPROTO_MPLS > #define IPPROTO_MPLS 137 > diff --git a/drivers/net/mlx5/mlx5_flow_dv.c > b/drivers/net/mlx5/mlx5_flow_dv.c > index 933ad0b..8f64182 100644 > --- a/drivers/net/mlx5/mlx5_flow_dv.c > +++ b/drivers/net/mlx5/mlx5_flow_dv.c > @@ -136,6 +136,8 @@ struct field_modify_info modify_udp[] = { > struct field_modify_info modify_tcp[] = { > {2, 0, MLX5_MODI_OUT_TCP_SPORT}, > {2, 2, MLX5_MODI_OUT_TCP_DPORT}, > + {4, 4, MLX5_MODI_OUT_TCP_SEQ_NUM}, > + {4, 8, MLX5_MODI_OUT_TCP_ACK_NUM}, > {0, 0, 0}, > }; > > @@ -561,6 +563,96 @@ struct field_modify_info modify_tcp[] = { > } > > /** > + * Convert modify-header increment/decrement TCP Sequence number > + * to DV specification. > + * > + * @param[in,out] resource > + * Pointer to the modify-header resource. > + * @param[in] action > + * Pointer to action specification. > + * @param[out] error > + * Pointer to the error structure. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +static int > +flow_dv_convert_action_modify_tcp_seq > + (struct mlx5_flow_dv_modify_hdr_resource > *resource, > + const struct rte_flow_action *action, > + struct rte_flow_error *error) > +{ > + const rte_be32_t *conf = (const rte_be32_t *)(action->conf); > + uint64_t value = rte_be_to_cpu_32(*conf); > + struct rte_flow_item item; > + struct rte_flow_item_tcp tcp; > + struct rte_flow_item_tcp tcp_mask; > + > + memset(&tcp, 0, sizeof(tcp)); > + memset(&tcp_mask, 0, sizeof(tcp_mask)); > + if (action->type == RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ) > + /* > + * The HW has no decrement operation, only increment > operation. > + * To simulate decrement X from Y using increment operation > + * we need to add UINT32_MAX X times to Y. > + * Each adding of UINT32_MAX decrements Y by 1. > + */ > + value *= UINT32_MAX; > + tcp.hdr.sent_seq = rte_cpu_to_be_32((uint32_t)value); > + tcp_mask.hdr.sent_seq = RTE_BE32(UINT32_MAX); > + item.type = RTE_FLOW_ITEM_TYPE_TCP; > + item.spec = &tcp; > + item.mask = &tcp_mask; > + return flow_dv_convert_modify_action(&item, modify_tcp, > resource, > + > MLX5_MODIFICATION_TYPE_ADD, error); > +} > + > +/** > + * Convert modify-header increment/decrement TCP Acknowledgment > number > + * to DV specification. > + * > + * @param[in,out] resource > + * Pointer to the modify-header resource. > + * @param[in] action > + * Pointer to action specification. > + * @param[out] error > + * Pointer to the error structure. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +static int > +flow_dv_convert_action_modify_tcp_ack > + (struct mlx5_flow_dv_modify_hdr_resource > *resource, > + const struct rte_flow_action *action, > + struct rte_flow_error *error) > +{ > + const rte_be32_t *conf = (const rte_be32_t *)(action->conf); > + uint64_t value = rte_be_to_cpu_32(*conf); > + struct rte_flow_item item; > + struct rte_flow_item_tcp tcp; > + struct rte_flow_item_tcp tcp_mask; > + > + memset(&tcp, 0, sizeof(tcp)); > + memset(&tcp_mask, 0, sizeof(tcp_mask)); > + if (action->type == RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK) > + /* > + * The HW has no decrement operation, only increment > operation. > + * To simulate decrement X from Y using increment operation > + * we need to add UINT32_MAX X times to Y. > + * Each adding of UINT32_MAX decrements Y by 1. > + */ > + value *= UINT32_MAX; > + tcp.hdr.recv_ack = rte_cpu_to_be_32((uint32_t)value); > + tcp_mask.hdr.recv_ack = RTE_BE32(UINT32_MAX); > + item.type = RTE_FLOW_ITEM_TYPE_TCP; > + item.spec = &tcp; > + item.mask = &tcp_mask; > + return flow_dv_convert_modify_action(&item, modify_tcp, > resource, > + > MLX5_MODIFICATION_TYPE_ADD, error); > +} > + > +/** > * Validate META item. > * > * @param[in] dev > @@ -1668,6 +1760,96 @@ struct field_modify_info modify_tcp[] = { > } > > /** > + * Validate the modify-header actions of increment/decrement > + * TCP Sequence-number. > + * > + * @param[in] action_flags > + * Holds the actions detected until now. > + * @param[in] action > + * Pointer to the modify action. > + * @param[in] item_flags > + * Holds the items detected. > + * @param[out] error > + * Pointer to error structure. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +static int > +flow_dv_validate_action_modify_tcp_seq(const uint64_t action_flags, > + const struct rte_flow_action *action, > + const uint64_t item_flags, > + struct rte_flow_error *error) > +{ > + int ret = 0; > + > + ret = flow_dv_validate_action_modify_hdr(action_flags, action, > error); > + if (!ret) { > + if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_TCP)) > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, "no TCP item in" > + " pattern"); > + if ((action->type == RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ > && > + (action_flags & > MLX5_FLOW_ACTION_DEC_TCP_SEQ)) || > + (action->type == RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ > && > + (action_flags & > MLX5_FLOW_ACTION_INC_TCP_SEQ))) > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "cannot decrease and > increase" > + " TCP sequence number" > + " at the same time"); > + } > + return ret; > +} > + > +/** > + * Validate the modify-header actions of increment/decrement > + * TCP Acknowledgment number. > + * > + * @param[in] action_flags > + * Holds the actions detected until now. > + * @param[in] action > + * Pointer to the modify action. > + * @param[in] item_flags > + * Holds the items detected. > + * @param[out] error > + * Pointer to error structure. > + * > + * @return > + * 0 on success, a negative errno value otherwise and rte_errno is set. > + */ > +static int > +flow_dv_validate_action_modify_tcp_ack(const uint64_t action_flags, > + const struct rte_flow_action *action, > + const uint64_t item_flags, > + struct rte_flow_error *error) > +{ > + int ret = 0; > + > + ret = flow_dv_validate_action_modify_hdr(action_flags, action, > error); > + if (!ret) { > + if (!(item_flags & MLX5_FLOW_LAYER_OUTER_L4_TCP)) > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, "no TCP item in" > + " pattern"); > + if ((action->type == RTE_FLOW_ACTION_TYPE_INC_TCP_ACK > && > + (action_flags & > MLX5_FLOW_ACTION_DEC_TCP_ACK)) || > + (action->type == RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK > && > + (action_flags & > MLX5_FLOW_ACTION_INC_TCP_ACK))) > + return rte_flow_error_set(error, EINVAL, > + > RTE_FLOW_ERROR_TYPE_ACTION, > + NULL, > + "cannot decrease and > increase" > + " TCP acknowledgment > number" > + " at the same time"); > + } > + return ret; > +} > + > +/** > * Validate the modify-header TTL actions. > * > * @param[in] action_flags > @@ -2416,6 +2598,40 @@ struct field_modify_info modify_tcp[] = { > ++actions_n; > action_flags |= MLX5_FLOW_ACTION_JUMP; > break; > + case RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ: > + case RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ: > + ret = flow_dv_validate_action_modify_tcp_seq > + > (action_flags, > + actions, > + item_flags, > + error); > + if (ret < 0) > + return ret; > + /* Count all modify-header actions as one action. */ > + if (!(action_flags & > MLX5_FLOW_MODIFY_HDR_ACTIONS)) > + ++actions_n; > + action_flags |= actions->type == > + > RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ ? > + > MLX5_FLOW_ACTION_INC_TCP_SEQ : > + > MLX5_FLOW_ACTION_DEC_TCP_SEQ; > + break; > + case RTE_FLOW_ACTION_TYPE_INC_TCP_ACK: > + case RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK: > + ret = flow_dv_validate_action_modify_tcp_ack > + > (action_flags, > + actions, > + item_flags, > + error); > + if (ret < 0) > + return ret; > + /* Count all modify-header actions as one action. */ > + if (!(action_flags & > MLX5_FLOW_MODIFY_HDR_ACTIONS)) > + ++actions_n; > + action_flags |= actions->type == > + > RTE_FLOW_ACTION_TYPE_INC_TCP_ACK ? > + > MLX5_FLOW_ACTION_INC_TCP_ACK : > + > MLX5_FLOW_ACTION_DEC_TCP_ACK; > + break; > default: > return rte_flow_error_set(error, ENOTSUP, > > RTE_FLOW_ERROR_TYPE_ACTION, > @@ -3895,6 +4111,27 @@ struct field_modify_info modify_tcp[] = { > return -rte_errno; > action_flags |= MLX5_FLOW_ACTION_SET_TTL; > break; > + case RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ: > + case RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ: > + if (flow_dv_convert_action_modify_tcp_seq(&res, > actions, > + error)) > + return -rte_errno; > + action_flags |= actions->type == > + > RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ ? > + MLX5_FLOW_ACTION_INC_TCP_SEQ > : > + > MLX5_FLOW_ACTION_DEC_TCP_SEQ; > + break; > + > + case RTE_FLOW_ACTION_TYPE_INC_TCP_ACK: > + case RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK: > + if (flow_dv_convert_action_modify_tcp_ack(&res, > actions, > + error)) > + return -rte_errno; > + action_flags |= actions->type == > + > RTE_FLOW_ACTION_TYPE_INC_TCP_ACK ? > + MLX5_FLOW_ACTION_INC_TCP_ACK > : > + > MLX5_FLOW_ACTION_DEC_TCP_ACK; > + break; > case RTE_FLOW_ACTION_TYPE_END: > actions_end = true; > if (action_flags & > MLX5_FLOW_MODIFY_HDR_ACTIONS) { > diff --git a/drivers/net/mlx5/mlx5_prm.h b/drivers/net/mlx5/mlx5_prm.h > index 1a19958..7482383 100644 > --- a/drivers/net/mlx5/mlx5_prm.h > +++ b/drivers/net/mlx5/mlx5_prm.h > @@ -347,6 +347,18 @@ enum mlx5_modification_field { > MLX5_MODI_IN_IPV6_HOPLIMIT, > MLX5_MODI_META_DATA_REG_A, > MLX5_MODI_META_DATA_REG_B = 0x50, > + MLX5_MODI_META_REG_C_0, > + MLX5_MODI_META_REG_C_1, > + MLX5_MODI_META_REG_C_2, > + MLX5_MODI_META_REG_C_3, > + MLX5_MODI_META_REG_C_4, > + MLX5_MODI_META_REG_C_5, > + MLX5_MODI_META_REG_C_6, > + MLX5_MODI_META_REG_C_7, > + MLX5_MODI_OUT_TCP_SEQ_NUM, > + MLX5_MODI_IN_TCP_SEQ_NUM, > + MLX5_MODI_OUT_TCP_ACK_NUM, > + MLX5_MODI_IN_TCP_ACK_NUM = 0x5C, > }; > > /* Modification sub command. */ > -- > 1.8.3.1