| @@ -58,12 +58,15 @@ static const struct uverbs_attr_spec mlx5_ib_flow_type[] = { · 57 unmodified lines |
| 58 | }, | 58 | }, |
| 59 | }; | 59 | }; |
| 60 | | 60 | |
| | 61 | #define MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS 2 |
| 61 | static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( | 62 | static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( |
| 62 | struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) | 63 | struct ib_uverbs_file *file, struct uverbs_attr_bundle *attrs) |
| 63 | { | 64 | { |
| 64 | struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG}; | 65 | struct mlx5_flow_act flow_act = {.flow_tag = MLX5_FS_DEFAULT_FLOW_TAG}; |
| 65 | struct mlx5_ib_flow_handler *flow_handler; | 66 | struct mlx5_ib_flow_handler *flow_handler; |
| 66 | struct mlx5_ib_flow_matcher *fs_matcher; | 67 | struct mlx5_ib_flow_matcher *fs_matcher; |
| | 68 | struct ib_uobject **arr_flow_actions; |
| | 69 | struct ib_uflow_resources *uflow_res; |
| 67 | void *devx_obj; | 70 | void *devx_obj; |
| 68 | int dest_id, dest_type; | 71 | int dest_id, dest_type; |
| 69 | void *cmd_in; | 72 | void *cmd_in; |
| @@ -73,6 +76,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · 3 unmodified lines |
| 73 | struct ib_uobject *uobj = | 76 | struct ib_uobject *uobj = |
| 74 | uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_CREATE_FLOW_HANDLE); | 77 | uverbs_attr_get_uobject(attrs, MLX5_IB_ATTR_CREATE_FLOW_HANDLE); |
| 75 | struct mlx5_ib_dev *dev = to_mdev(uobj->context->device); | 78 | struct mlx5_ib_dev *dev = to_mdev(uobj->context->device); |
| | 79 | int len, ret, i; |
| 76 | | 80 | |
| 77 | if (!capable(CAP_NET_RAW)) | 81 | if (!capable(CAP_NET_RAW)) |
| 78 | return -EPERM; | 82 | return -EPERM; |
| @@ -124,15 +128,38 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW)( · 45 unmodified lines |
| 124 | MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE); | 128 | MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE); |
| 125 | fs_matcher = uverbs_attr_get_obj(attrs, | 129 | fs_matcher = uverbs_attr_get_obj(attrs, |
| 126 | MLX5_IB_ATTR_CREATE_FLOW_MATCHER); | 130 | MLX5_IB_ATTR_CREATE_FLOW_MATCHER); |
| | 131 | |
| | 132 | uflow_res = flow_resources_alloc(MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS); |
| | 133 | if (!uflow_res) |
| | 134 | return -ENOMEM; |
| | 135 | |
| | 136 | len = uverbs_attr_get_uobjs_arr(attrs, |
| | 137 | MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS, &arr_flow_actions); |
| | 138 | for (i = 0; i < len; i++) { |
| | 139 | struct mlx5_ib_flow_action *maction = |
| | 140 | to_mflow_act(arr_flow_actions[i]->object); |
| | 141 | |
| | 142 | ret = parse_flow_flow_action(maction, false, &flow_act); |
| | 143 | if (ret) |
| | 144 | goto err_out; |
| | 145 | flow_resources_add(uflow_res, IB_FLOW_SPEC_ACTION_HANDLE, |
| | 146 | arr_flow_actions[i]->object); |
| | 147 | } |
| | 148 | |
| 127 | flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher, &flow_act, | 149 | flow_handler = mlx5_ib_raw_fs_rule_add(dev, fs_matcher, &flow_act, |
| 128 | cmd_in, inlen, | 150 | cmd_in, inlen, |
| 129 | dest_id, dest_type); | 151 | dest_id, dest_type); |
| 130 | if (IS_ERR(flow_handler)) | 152 | if (IS_ERR(flow_handler)) { |
| 131 | return PTR_ERR(flow_handler); | 153 | ret = PTR_ERR(flow_handler); |
| | 154 | goto err_out; |
| | 155 | } |
| 132 | | 156 | |
| 133 | ib_set_flow(uobj, &flow_handler->ibflow, qp, &dev->ib_dev, NULL); | 157 | ib_set_flow(uobj, &flow_handler->ibflow, qp, &dev->ib_dev, uflow_res); |
| 134 | | 158 | |
| 135 | return 0; | 159 | return 0; |
| | 160 | err_out: |
| | 161 | ib_uverbs_flow_resources_free(uflow_res); |
| | 162 | return ret; |
| 136 | } | 163 | } |
| 137 | | 164 | |
| 138 | static int flow_matcher_cleanup(struct ib_uobject *uobject, | 165 | static int flow_matcher_cleanup(struct ib_uobject *uobject, |
| @@ -459,7 +486,12 @@ DECLARE_UVERBS_NAMED_METHOD( · 320 unmodified lines |
| 459 | UVERBS_ACCESS_READ), | 486 | UVERBS_ACCESS_READ), |
| 460 | UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX, | 487 | UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX, |
| 461 | MLX5_IB_OBJECT_DEVX_OBJ, | 488 | MLX5_IB_OBJECT_DEVX_OBJ, |
| 462 | UVERBS_ACCESS_READ)); | 489 | UVERBS_ACCESS_READ), |
| | 490 | UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS, |
| | 491 | UVERBS_OBJECT_FLOW_ACTION, |
| | 492 | UVERBS_ACCESS_READ, 1, |
| | 493 | MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS, |
| | 494 | UA_OPTIONAL)); |
| 463 | | 495 | |
| 464 | DECLARE_UVERBS_NAMED_METHOD_DESTROY( | 496 | DECLARE_UVERBS_NAMED_METHOD_DESTROY( |
| 465 | MLX5_IB_METHOD_DESTROY_FLOW, | 497 | MLX5_IB_METHOD_DESTROY_FLOW, |