net/mlx5: validate meter profile
authorSuanming Mou <suanmingm@mellanox.com>
Fri, 8 Nov 2019 03:49:11 +0000 (05:49 +0200)
committerFerruh Yigit <ferruh.yigit@intel.com>
Mon, 11 Nov 2019 13:23:02 +0000 (14:23 +0100)
The add meter profile should be validated if it is valid or has been add
to the list. Invalid and exist profile should not be add to the list.

Signed-off-by: Suanming Mou <suanmingm@mellanox.com>
Acked-by: Matan Azrad <matan@mellanox.com>
drivers/net/mlx5/mlx5_flow_meter.c
drivers/net/mlx5/mlx5_prm.h

index b11962f..5ad5e14 100644 (file)
@@ -34,6 +34,71 @@ mlx5_flow_meter_profile_find(struct mlx5_priv *priv, uint32_t meter_profile_id)
        return NULL;
 }
 
+/**
+ * Validate the MTR profile.
+ *
+ * @param[in] dev
+ *   Pointer to Ethernet device.
+ * @param[in] meter_profile_id
+ *   Meter profile id.
+ * @param[in] profile
+ *   Pointer to meter profile detail.
+ * @param[out] error
+ *   Pointer to the error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_meter_profile_validate(struct rte_eth_dev *dev,
+                                uint32_t meter_profile_id,
+                                struct rte_mtr_meter_profile *profile,
+                                struct rte_mtr_error *error)
+{
+       struct mlx5_priv *priv = dev->data->dev_private;
+       struct mlx5_flow_meter_profile *fmp;
+
+       /* Profile must not be NULL. */
+       if (profile == NULL)
+               return -rte_mtr_error_set(error, EINVAL,
+                                         RTE_MTR_ERROR_TYPE_METER_PROFILE,
+                                         NULL, "Meter profile is null.");
+       /* Meter profile ID must be valid. */
+       if (meter_profile_id == UINT32_MAX)
+               return -rte_mtr_error_set(error, EINVAL,
+                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+                                         NULL, "Meter profile id not valid.");
+       /* Meter profile must not exist. */
+       fmp = mlx5_flow_meter_profile_find(priv, meter_profile_id);
+       if (fmp)
+               return -rte_mtr_error_set(error, EEXIST,
+                                         RTE_MTR_ERROR_TYPE_METER_PROFILE_ID,
+                                         NULL,
+                                         "Meter profile already exists.");
+       if (profile->alg == RTE_MTR_SRTCM_RFC2697) {
+               if (priv->config.hca_attr.qos.srtcm_sup) {
+                       /* Verify support for flow meter parameters. */
+                       if (profile->srtcm_rfc2697.cir > 0 &&
+                           profile->srtcm_rfc2697.cir <= MLX5_SRTCM_CIR_MAX &&
+                           profile->srtcm_rfc2697.cbs > 0 &&
+                           profile->srtcm_rfc2697.cbs <= MLX5_SRTCM_CBS_MAX &&
+                           profile->srtcm_rfc2697.ebs <= MLX5_SRTCM_EBS_MAX)
+                               return 0;
+                       else
+                               return -rte_mtr_error_set
+                                            (error, ENOTSUP,
+                                             RTE_MTR_ERROR_TYPE_MTR_PARAMS,
+                                             NULL,
+                                             profile->srtcm_rfc2697.ebs ?
+                                             "Metering value ebs must be 0." :
+                                             "Invalid metering parameters.");
+               }
+       }
+       return -rte_mtr_error_set(error, ENOTSUP,
+                                 RTE_MTR_ERROR_TYPE_METER_PROFILE,
+                                 NULL, "Metering algorithm not supported.");
+}
+
 /**
  * Calculate mantissa and exponent for cir.
  *
@@ -226,6 +291,11 @@ mlx5_flow_meter_profile_add(struct rte_eth_dev *dev,
                return -rte_mtr_error_set(error, ENOTSUP,
                                          RTE_MTR_ERROR_TYPE_UNSPECIFIED, NULL,
                                          "Meter is not support");
+       /* Check input params. */
+       ret = mlx5_flow_meter_profile_validate(dev, meter_profile_id,
+                                              profile, error);
+       if (ret)
+               return ret;
        /* Meter profile memory allocation. */
        fmp = rte_calloc(__func__, 1, sizeof(struct mlx5_flow_meter_profile),
                         RTE_CACHE_LINE_SIZE);
index a0c37c8..3ebf191 100644 (file)
@@ -1768,6 +1768,11 @@ struct mlx5_mini_cqe8 {
        uint32_t byte_cnt;
 };
 
+/* Maximum value of srTCM metering parameters. */
+#define MLX5_SRTCM_CBS_MAX (0xFF * (1ULL << 0x1F))
+#define MLX5_SRTCM_CIR_MAX (8 * (1ULL << 30) * 0xFF)
+#define MLX5_SRTCM_EBS_MAX 0
+
 /**
  * Convert a user mark to flow mark.
  *