[dpdk-dev] [PATCH 2/3] net/mlx5: add flow rule match for IPv4 IHL field
From: Gregory Etelson <hidden>
Date: 2021-06-30 07:05:28
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Provide flow rules capability to match on IPv4 IHL field. Minimal HCA firmware version requiredto offload IPv4 IHL is xx_30_2000. Signed-off-by: Gregory Etelson <redacted> Acked-by: Viacheslav Ovsiienko <redacted> --- drivers/net/mlx5/mlx5_flow_dv.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/drivers/net/mlx5/mlx5_flow_dv.c b/drivers/net/mlx5/mlx5_flow_dv.c
index c5d4b01e57..155f686ad1 100644
--- a/drivers/net/mlx5/mlx5_flow_dv.c
+++ b/drivers/net/mlx5/mlx5_flow_dv.c@@ -2451,19 +2451,19 @@ flow_dv_validate_item_gtp_psc(const struct rte_flow_item *item, * 0 on success, a negative errno value otherwise and rte_errno is set. */ static int -flow_dv_validate_item_ipv4(const struct rte_flow_item *item, - uint64_t item_flags, - uint64_t last_item, - uint16_t ether_type, - struct rte_flow_error *error) +flow_dv_validate_item_ipv4(struct rte_eth_dev *dev, + const struct rte_flow_item *item, + uint64_t item_flags, uint64_t last_item, + uint16_t ether_type, struct rte_flow_error *error) { int ret; + struct mlx5_priv *priv = dev->data->dev_private; const struct rte_flow_item_ipv4 *spec = item->spec; const struct rte_flow_item_ipv4 *last = item->last; const struct rte_flow_item_ipv4 *mask = item->mask; rte_be16_t fragment_offset_spec = 0; rte_be16_t fragment_offset_last = 0; - const struct rte_flow_item_ipv4 nic_ipv4_mask = { + struct rte_flow_item_ipv4 nic_ipv4_mask = { .hdr = { .src_addr = RTE_BE32(0xffffffff), .dst_addr = RTE_BE32(0xffffffff),
@@ -2474,6 +2474,17 @@ flow_dv_validate_item_ipv4(const struct rte_flow_item *item, }, }; + if (mask && (mask->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK)) { + int tunnel = !!(item_flags & MLX5_FLOW_LAYER_TUNNEL); + bool ihl_cap = !tunnel ? priv->config.hca_attr.outer_ipv4_ihl : + priv->config.hca_attr.inner_ipv4_ihl; + if (!ihl_cap) + return rte_flow_error_set(error, ENOTSUP, + RTE_FLOW_ERROR_TYPE_ITEM, + item, + "IPV4 ihl offload not supported"); + nic_ipv4_mask.hdr.version_ihl = mask->hdr.version_ihl; + } ret = mlx5_flow_validate_item_ipv4(item, item_flags, last_item, ether_type, &nic_ipv4_mask, MLX5_ITEM_RANGE_ACCEPTED, error);
@@ -6771,7 +6782,7 @@ flow_dv_validate(struct rte_eth_dev *dev, const struct rte_flow_attr *attr, case RTE_FLOW_ITEM_TYPE_IPV4: mlx5_flow_tunnel_ip_check(items, next_protocol, &item_flags, &tunnel); - ret = flow_dv_validate_item_ipv4(items, item_flags, + ret = flow_dv_validate_item_ipv4(dev, items, item_flags, last_item, ether_type, error); if (ret < 0)
@@ -8154,7 +8165,7 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, void *headers_v; char *l24_m; char *l24_v; - uint8_t tos; + uint8_t tos, ihl_m, ihl_v; if (inner) { headers_m = MLX5_ADDR_OF(fte_match_param, matcher,
@@ -8183,6 +8194,10 @@ flow_dv_translate_item_ipv4(void *matcher, void *key, *(uint32_t *)l24_m = ipv4_m->hdr.src_addr; *(uint32_t *)l24_v = ipv4_m->hdr.src_addr & ipv4_v->hdr.src_addr; tos = ipv4_m->hdr.type_of_service & ipv4_v->hdr.type_of_service; + ihl_m = ipv4_m->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK; + ihl_v = ipv4_v->hdr.version_ihl & RTE_IPV4_HDR_IHL_MASK; + MLX5_SET(fte_match_set_lyr_2_4, headers_m, ipv4_ihl, ihl_m); + MLX5_SET(fte_match_set_lyr_2_4, headers_v, ipv4_ihl, ihl_m & ihl_v); MLX5_SET(fte_match_set_lyr_2_4, headers_m, ip_ecn, ipv4_m->hdr.type_of_service); MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn, tos);
--
2.31.1