1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright 2020 Mellanox Technologies, Ltd 3 */ 4 5 #include "mlx5_flow_os.h" 6 #include "mlx5_win_ext.h" 7 8 /** 9 * Verify the @p attributes will be correctly understood by the NIC and store 10 * them in the @p flow if everything is correct. 11 * 12 * @param[in] dev 13 * Pointer to dev struct. 14 * @param[in] attributes 15 * Pointer to flow attributes 16 * @param[in] external 17 * This flow rule is created by request external to PMD. 18 * @param[out] error 19 * Pointer to error structure. 20 * 21 * @return 22 * - 0 on success and non root table (not a valid option for Windows yet). 23 * - 1 on success and root table. 24 * - a negative errno value otherwise and rte_errno is set. 25 */ 26 int 27 mlx5_flow_os_validate_flow_attributes(struct rte_eth_dev *dev, 28 const struct rte_flow_attr *attributes, 29 bool external, 30 struct rte_flow_error *error) 31 { 32 int ret = 1; 33 34 RTE_SET_USED(dev); 35 RTE_SET_USED(external); 36 if (attributes->group) 37 return rte_flow_error_set(error, ENOTSUP, 38 RTE_FLOW_ERROR_TYPE_ATTR_GROUP, 39 NULL, 40 "groups are not supported"); 41 if (attributes->priority) 42 return rte_flow_error_set(error, ENOTSUP, 43 RTE_FLOW_ERROR_TYPE_ATTR_PRIORITY, 44 NULL, 45 "priorities are not supported"); 46 if (attributes->transfer) 47 return rte_flow_error_set(error, ENOTSUP, 48 RTE_FLOW_ERROR_TYPE_ATTR_TRANSFER, 49 NULL, 50 "transfer not supported"); 51 if (!(attributes->ingress)) 52 return rte_flow_error_set(error, ENOTSUP, 53 RTE_FLOW_ERROR_TYPE_ATTR_INGRESS, 54 NULL, "must specify ingress only"); 55 return ret; 56 } 57 58 /** 59 * Create flow matcher in a flow table. 60 * 61 * @param[in] ctx 62 * Pointer to relevant device context. 63 * @param[in] attr 64 * Pointer to relevant attributes. 65 * @param[in] table 66 * Pointer to table object. 67 * @param[out] matcher 68 * Pointer to a valid flow matcher object on success, NULL otherwise. 69 * 70 * @return 71 * 0 on success, or errno on failure. 72 */ 73 int 74 mlx5_flow_os_create_flow_matcher(void *ctx, 75 void *attr, 76 void *table, 77 void **matcher) 78 { 79 struct mlx5dv_flow_matcher_attr *mattr; 80 81 RTE_SET_USED(table); 82 *matcher = NULL; 83 mattr = attr; 84 if (mattr->type != IBV_FLOW_ATTR_NORMAL) { 85 rte_errno = ENOTSUP; 86 return -rte_errno; 87 } 88 struct mlx5_matcher *mlx5_matcher = 89 mlx5_malloc(MLX5_MEM_ZERO, 90 sizeof(struct mlx5_matcher) + 91 MLX5_ST_SZ_BYTES(fte_match_param), 92 0, SOCKET_ID_ANY); 93 if (!mlx5_matcher) { 94 rte_errno = ENOMEM; 95 return -rte_errno; 96 } 97 mlx5_matcher->ctx = ctx; 98 memcpy(&mlx5_matcher->attr, attr, sizeof(mlx5_matcher->attr)); 99 memcpy(&mlx5_matcher->match_buf, 100 mattr->match_mask->match_buf, 101 MLX5_ST_SZ_BYTES(fte_match_param)); 102 *matcher = mlx5_matcher; 103 return 0; 104 } 105 106 /** 107 * Destroy flow matcher. 108 * 109 * @param[in] matcher 110 * Pointer to matcher object to destroy. 111 * 112 * @return 113 * 0 on success, or the value of errno on failure. 114 */ 115 int 116 mlx5_flow_os_destroy_flow_matcher(void *matcher) 117 { 118 mlx5_free(matcher); 119 return 0; 120 } 121 122 /** 123 * Create flow action: dest_devx_tir 124 * 125 * @param[in] tir 126 * Pointer to DevX tir object 127 * @param[out] action 128 * Pointer to a valid action on success, NULL otherwise. 129 * 130 * @return 131 * 0 on success, or errno on failure. 132 */ 133 int 134 mlx5_flow_os_create_flow_action_dest_devx_tir(struct mlx5_devx_obj *tir, 135 void **action) 136 { 137 struct mlx5_action *mlx5_action = 138 mlx5_malloc(MLX5_MEM_ZERO, 139 sizeof(struct mlx5_action), 140 0, SOCKET_ID_ANY); 141 142 if (!mlx5_action) { 143 rte_errno = ENOMEM; 144 return -rte_errno; 145 } 146 mlx5_action->type = MLX5_FLOW_CONTEXT_DEST_TYPE_TIR; 147 mlx5_action->dest_tir.id = tir->id; 148 *action = mlx5_action; 149 return 0; 150 } 151 152 /** 153 * Destroy flow action. 154 * 155 * @param[in] action 156 * Pointer to action object to destroy. 157 * 158 * @return 159 * 0 on success, or the value of errno on failure. 160 */ 161 int 162 mlx5_flow_os_destroy_flow_action(void *action) 163 { 164 mlx5_free(action); 165 return 0; 166 } 167 168 /** 169 * Create flow rule. 170 * 171 * @param[in] matcher 172 * Pointer to match mask structure. 173 * @param[in] match_value 174 * Pointer to match value structure. 175 * @param[in] num_actions 176 * Number of actions in flow rule. 177 * @param[in] actions 178 * Pointer to array of flow rule actions. 179 * @param[out] flow 180 * Pointer to a valid flow rule object on success, NULL otherwise. 181 * 182 * @return 183 * 0 on success, or errno on failure. 184 */ 185 int 186 mlx5_flow_os_create_flow(void *matcher, void *match_value, 187 size_t num_actions, 188 void *actions[], void **flow) 189 { 190 struct mlx5_action *action; 191 size_t i; 192 struct mlx5_matcher *mlx5_matcher = matcher; 193 struct mlx5_flow_dv_match_params *mlx5_match_value = match_value; 194 uint32_t in[MLX5_ST_SZ_DW(devx_fs_rule_add_in)] = {0}; 195 void *matcher_c = MLX5_ADDR_OF(devx_fs_rule_add_in, in, 196 match_criteria); 197 void *matcher_v = MLX5_ADDR_OF(devx_fs_rule_add_in, in, 198 match_value); 199 200 MLX5_ASSERT(mlx5_matcher->ctx); 201 memcpy(matcher_c, mlx5_matcher->match_buf, 202 mlx5_match_value->size); 203 /* Use mlx5_match_value->size for match criteria */ 204 memcpy(matcher_v, mlx5_match_value->buf, 205 mlx5_match_value->size); 206 for (i = 0; i < num_actions; i++) { 207 action = actions[i]; 208 switch (action->type) { 209 case MLX5_FLOW_CONTEXT_DEST_TYPE_TIR: 210 MLX5_SET(devx_fs_rule_add_in, in, 211 dest.destination_type, 212 MLX5_FLOW_CONTEXT_DEST_TYPE_TIR); 213 MLX5_SET(devx_fs_rule_add_in, in, 214 dest.destination_id, 215 action->dest_tir.id); 216 break; 217 default: 218 break; 219 } 220 MLX5_SET(devx_fs_rule_add_in, in, match_criteria_enable, 221 MLX5_MATCH_OUTER_HEADERS); 222 } 223 *flow = mlx5_glue->devx_fs_rule_add(mlx5_matcher->ctx, in, sizeof(in)); 224 return (*flow) ? 0 : -1; 225 } 226 227 /** 228 * Destroy flow rule. 229 * 230 * @param[in] drv_flow_ptr 231 * Pointer to flow rule object. 232 * 233 * @return 234 * 0 on success, errno on failure. 235 */ 236 int 237 mlx5_flow_os_destroy_flow(void *drv_flow_ptr) 238 { 239 return mlx5_glue->devx_fs_rule_del(drv_flow_ptr); 240 } 241