]> git.droids-corp.org - dpdk.git/commitdiff
net/mlx5: support flow matchng on IPv4 IHL
authorGregory Etelson <getelson@nvidia.com>
Mon, 5 Jul 2021 11:40:35 +0000 (14:40 +0300)
committerRaslan Darawsheh <rasland@nvidia.com>
Thu, 15 Jul 2021 14:22:20 +0000 (16:22 +0200)
Query MLX5 port hardware if it is capable to offload IPv4
IHL field.

Provide flow rules capability to match on IPv4 IHL field.
Minimal HCA firmware version required to offload IPv4 IHL is
xx_30_2000.

Signed-off-by: Gregory Etelson <getelson@nvidia.com>
Acked-by: Viacheslav Ovsiienko <viacheslavo@nvidia.com>
doc/guides/nics/mlx5.rst
doc/guides/rel_notes/release_21_08.rst
drivers/common/mlx5/mlx5_devx_cmds.c
drivers/common/mlx5/mlx5_devx_cmds.h
drivers/net/mlx5/mlx5_flow_dv.c

index 4d989686db971e77f24d2a833c106d0669fef31d..f5b727c1eed48d62eb74e531ccfd0ac27bca4103 100644 (file)
@@ -99,6 +99,7 @@ Features
 - Hardware LRO.
 - Hairpin.
 - Multiple-thread flow insertion.
+- Matching on IPv4 Internet Header Length (IHL).
 - Matching on GTP extension header with raw encap/decap action.
 - Matching on Geneve TLV option header with raw encap/decap action.
 - RSS support in sample action.
index fadaa7108703872cceefa171639b188436e303e5..1b38b1aa51eff83894c6308b46913ebdab9ba0f3 100644 (file)
@@ -88,6 +88,7 @@ New Features
 
   * Added support for meter hierarchy.
   * Added devargs options ``allow_duplicate_pattern``.
+  * Added matching on IPv4 Internet Header Length (IHL).
   * Added support for matching on VXLAN header last 8-bits reserved field.
   * Optimized multi-thread flow rule insertion rate.
 
index 63ae95832d8f4f4f97be5baaaf554e62211aa490..10a02d13ee88d55a4f4628dcd75f424c6a3251cd 100644 (file)
@@ -951,6 +951,12 @@ mlx5_devx_cmd_query_hca_attr(void *ctx,
                (flow_table_nic_cap, hcattr,
                 ft_field_support_2_nic_receive.tunnel_header_0_1);
        attr->pkt_integrity_match = mlx5_devx_query_pkt_integrity_match(hcattr);
+       attr->inner_ipv4_ihl = MLX5_GET
+               (flow_table_nic_cap, hcattr,
+                ft_field_support_2_nic_receive.inner_ipv4_ihl);
+       attr->outer_ipv4_ihl = MLX5_GET
+               (flow_table_nic_cap, hcattr,
+                ft_field_support_2_nic_receive.outer_ipv4_ihl);
        /* Query HCA offloads for Ethernet protocol. */
        memset(in, 0, sizeof(in));
        memset(out, 0, sizeof(out));
index 124f43e852c26607fa21e70cf0f117b3c1426c72..c11ca6586f40745c4e5ccd31873fffdb72ec1555 100644 (file)
@@ -153,6 +153,8 @@ struct mlx5_hca_attr {
        uint32_t crypto_login:1; /* General obj type CRYPTO_LOGIN supported. */
        uint32_t regexp_num_of_engines;
        uint32_t log_max_ft_sampler_num:8;
+       uint32_t inner_ipv4_ihl:1;
+       uint32_t outer_ipv4_ihl:1;
        uint32_t geneve_tlv_opt;
        uint32_t cqe_compression:1;
        uint32_t mini_cqe_resp_flow_tag:1;
index eb0465a65094d7a6a8d9671d4925eff020901cfd..996106b051399b9052881757de8aec8dd975584b 100644 (file)
@@ -2492,19 +2492,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),
@@ -2515,6 +2515,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);
@@ -6996,7 +7007,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)
@@ -8375,7 +8386,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,
@@ -8404,6 +8415,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);