1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
3 * Copyright (c) 2018, Mellanox Technologies inc. All rights reserved.
6 #include <rdma/ib_user_verbs.h>
7 #include <rdma/ib_verbs.h>
8 #include <rdma/uverbs_types.h>
9 #include <rdma/uverbs_ioctl.h>
10 #include <rdma/uverbs_std_types.h>
11 #include <rdma/mlx5_user_ioctl_cmds.h>
12 #include <rdma/mlx5_user_ioctl_verbs.h>
13 #include <rdma/ib_umem.h>
14 #include <linux/mlx5/driver.h>
15 #include <linux/mlx5/fs.h>
18 #define UVERBS_MODULE_NAME mlx5_ib
19 #include <rdma/uverbs_named_ioctl.h>
22 mlx5_ib_ft_type_to_namespace(enum mlx5_ib_uapi_flow_table_type table_type
,
23 enum mlx5_flow_namespace_type
*namespace)
26 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX
:
27 *namespace = MLX5_FLOW_NAMESPACE_BYPASS
;
29 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX
:
30 *namespace = MLX5_FLOW_NAMESPACE_EGRESS
;
32 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_FDB
:
33 *namespace = MLX5_FLOW_NAMESPACE_FDB
;
35 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_RX
:
36 *namespace = MLX5_FLOW_NAMESPACE_RDMA_RX
;
38 case MLX5_IB_UAPI_FLOW_TABLE_TYPE_RDMA_TX
:
39 *namespace = MLX5_FLOW_NAMESPACE_RDMA_TX
;
48 static const struct uverbs_attr_spec mlx5_ib_flow_type
[] = {
49 [MLX5_IB_FLOW_TYPE_NORMAL
] = {
50 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
52 .len
= sizeof(u16
), /* data is priority */
53 .min_len
= sizeof(u16
),
56 [MLX5_IB_FLOW_TYPE_SNIFFER
] = {
57 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
58 UVERBS_ATTR_NO_DATA(),
60 [MLX5_IB_FLOW_TYPE_ALL_DEFAULT
] = {
61 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
62 UVERBS_ATTR_NO_DATA(),
64 [MLX5_IB_FLOW_TYPE_MC_DEFAULT
] = {
65 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
66 UVERBS_ATTR_NO_DATA(),
70 #define MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS 2
71 static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW
)(
72 struct uverbs_attr_bundle
*attrs
)
74 struct mlx5_flow_context flow_context
= {.flow_tag
= MLX5_FS_DEFAULT_FLOW_TAG
};
75 struct mlx5_ib_flow_handler
*flow_handler
;
76 struct mlx5_ib_flow_matcher
*fs_matcher
;
77 struct ib_uobject
**arr_flow_actions
;
78 struct ib_uflow_resources
*uflow_res
;
79 struct mlx5_flow_act flow_act
= {};
81 int dest_id
, dest_type
;
84 bool dest_devx
, dest_qp
;
85 struct ib_qp
*qp
= NULL
;
86 struct ib_uobject
*uobj
=
87 uverbs_attr_get_uobject(attrs
, MLX5_IB_ATTR_CREATE_FLOW_HANDLE
);
88 struct mlx5_ib_dev
*dev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
94 if (!capable(CAP_NET_RAW
))
98 uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX
);
99 dest_qp
= uverbs_attr_is_valid(attrs
,
100 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP
);
102 fs_matcher
= uverbs_attr_get_obj(attrs
,
103 MLX5_IB_ATTR_CREATE_FLOW_MATCHER
);
104 if (fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_BYPASS
&&
105 ((dest_devx
&& dest_qp
) || (!dest_devx
&& !dest_qp
)))
108 /* Allow only DEVX object as dest when inserting to FDB */
109 if (fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_FDB
&& !dest_devx
)
112 /* Allow only DEVX object or QP as dest when inserting to RDMA_RX */
113 if ((fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_RDMA_RX
) &&
114 ((!dest_devx
&& !dest_qp
) || (dest_devx
&& dest_qp
)))
118 devx_obj
= uverbs_attr_get_obj(
119 attrs
, MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX
);
120 if (IS_ERR(devx_obj
))
121 return PTR_ERR(devx_obj
);
123 /* Verify that the given DEVX object is a flow
124 * steering destination.
126 if (!mlx5_ib_devx_is_flow_dest(devx_obj
, &dest_id
, &dest_type
))
128 /* Allow only flow table as dest when inserting to FDB or RDMA_RX */
129 if ((fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_FDB
||
130 fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_RDMA_RX
) &&
131 dest_type
!= MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE
)
133 } else if (dest_qp
) {
134 struct mlx5_ib_qp
*mqp
;
136 qp
= uverbs_attr_get_obj(attrs
,
137 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP
);
141 if (qp
->qp_type
!= IB_QPT_RAW_PACKET
)
145 if (mqp
->flags
& MLX5_IB_QP_RSS
)
146 dest_id
= mqp
->rss_qp
.tirn
;
148 dest_id
= mqp
->raw_packet_qp
.rq
.tirn
;
149 dest_type
= MLX5_FLOW_DESTINATION_TYPE_TIR
;
151 dest_type
= MLX5_FLOW_DESTINATION_TYPE_PORT
;
154 len
= uverbs_attr_get_uobjs_arr(attrs
,
155 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX
, &arr_flow_actions
);
157 devx_obj
= arr_flow_actions
[0]->object
;
159 if (uverbs_attr_is_valid(attrs
,
160 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
)) {
162 int num_offsets
= uverbs_attr_ptr_get_array_size(
164 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
,
167 if (num_offsets
!= 1)
170 offset_attr
= uverbs_attr_get_alloced_ptr(
172 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
);
173 offset
= *offset_attr
;
176 if (!mlx5_ib_devx_is_flow_counter(devx_obj
, offset
,
180 flow_act
.action
|= MLX5_FLOW_CONTEXT_ACTION_COUNT
;
183 if (dest_type
== MLX5_FLOW_DESTINATION_TYPE_TIR
&&
184 fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_EGRESS
)
187 cmd_in
= uverbs_attr_get_alloced_ptr(
188 attrs
, MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE
);
189 inlen
= uverbs_attr_get_len(attrs
,
190 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE
);
192 uflow_res
= flow_resources_alloc(MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS
);
196 len
= uverbs_attr_get_uobjs_arr(attrs
,
197 MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS
, &arr_flow_actions
);
198 for (i
= 0; i
< len
; i
++) {
199 struct mlx5_ib_flow_action
*maction
=
200 to_mflow_act(arr_flow_actions
[i
]->object
);
202 ret
= parse_flow_flow_action(maction
, false, &flow_act
);
205 flow_resources_add(uflow_res
, IB_FLOW_SPEC_ACTION_HANDLE
,
206 arr_flow_actions
[i
]->object
);
209 ret
= uverbs_copy_from(&flow_context
.flow_tag
, attrs
,
210 MLX5_IB_ATTR_CREATE_FLOW_TAG
);
212 if (flow_context
.flow_tag
>= BIT(24)) {
216 flow_context
.flags
|= FLOW_CONTEXT_HAS_TAG
;
219 flow_handler
= mlx5_ib_raw_fs_rule_add(dev
, fs_matcher
,
225 if (IS_ERR(flow_handler
)) {
226 ret
= PTR_ERR(flow_handler
);
230 ib_set_flow(uobj
, &flow_handler
->ibflow
, qp
, &dev
->ib_dev
, uflow_res
);
234 ib_uverbs_flow_resources_free(uflow_res
);
238 static int flow_matcher_cleanup(struct ib_uobject
*uobject
,
239 enum rdma_remove_reason why
,
240 struct uverbs_attr_bundle
*attrs
)
242 struct mlx5_ib_flow_matcher
*obj
= uobject
->object
;
245 ret
= ib_destroy_usecnt(&obj
->usecnt
, why
, uobject
);
253 static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle
*attrs
,
254 struct mlx5_ib_flow_matcher
*obj
)
256 enum mlx5_ib_uapi_flow_table_type ft_type
=
257 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX
;
261 /* New users should use MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE and older
262 * users should switch to it. We leave this to not break userspace
264 if (uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
) &&
265 uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
))
268 if (uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
)) {
269 err
= uverbs_get_const(&ft_type
, attrs
,
270 MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
);
274 err
= mlx5_ib_ft_type_to_namespace(ft_type
, &obj
->ns_type
);
281 if (uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
)) {
282 err
= uverbs_get_flags32(&flags
, attrs
,
283 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
,
284 IB_FLOW_ATTR_FLAGS_EGRESS
);
289 mlx5_ib_ft_type_to_namespace(
290 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX
,
296 obj
->ns_type
= MLX5_FLOW_NAMESPACE_BYPASS
;
301 static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE
)(
302 struct uverbs_attr_bundle
*attrs
)
304 struct ib_uobject
*uobj
= uverbs_attr_get_uobject(
305 attrs
, MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE
);
306 struct mlx5_ib_dev
*dev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
307 struct mlx5_ib_flow_matcher
*obj
;
310 obj
= kzalloc(sizeof(struct mlx5_ib_flow_matcher
), GFP_KERNEL
);
314 obj
->mask_len
= uverbs_attr_get_len(
315 attrs
, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK
);
316 err
= uverbs_copy_from(&obj
->matcher_mask
,
318 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK
);
322 obj
->flow_type
= uverbs_attr_get_enum_id(
323 attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE
);
325 if (obj
->flow_type
== MLX5_IB_FLOW_TYPE_NORMAL
) {
326 err
= uverbs_copy_from(&obj
->priority
,
328 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE
);
333 err
= uverbs_copy_from(&obj
->match_criteria_enable
,
335 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA
);
339 err
= mlx5_ib_matcher_ns(attrs
, obj
);
344 obj
->mdev
= dev
->mdev
;
345 atomic_set(&obj
->usecnt
, 0);
353 void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action
*maction
)
355 switch (maction
->flow_action_raw
.sub_type
) {
356 case MLX5_IB_FLOW_ACTION_MODIFY_HEADER
:
357 mlx5_modify_header_dealloc(maction
->flow_action_raw
.dev
->mdev
,
358 maction
->flow_action_raw
.modify_hdr
);
360 case MLX5_IB_FLOW_ACTION_PACKET_REFORMAT
:
361 mlx5_packet_reformat_dealloc(maction
->flow_action_raw
.dev
->mdev
,
362 maction
->flow_action_raw
.pkt_reformat
);
364 case MLX5_IB_FLOW_ACTION_DECAP
:
371 static struct ib_flow_action
*
372 mlx5_ib_create_modify_header(struct mlx5_ib_dev
*dev
,
373 enum mlx5_ib_uapi_flow_table_type ft_type
,
374 u8 num_actions
, void *in
)
376 enum mlx5_flow_namespace_type
namespace;
377 struct mlx5_ib_flow_action
*maction
;
380 ret
= mlx5_ib_ft_type_to_namespace(ft_type
, &namespace);
382 return ERR_PTR(-EINVAL
);
384 maction
= kzalloc(sizeof(*maction
), GFP_KERNEL
);
386 return ERR_PTR(-ENOMEM
);
388 maction
->flow_action_raw
.modify_hdr
=
389 mlx5_modify_header_alloc(dev
->mdev
, namespace, num_actions
, in
);
391 if (IS_ERR(maction
->flow_action_raw
.modify_hdr
)) {
392 ret
= PTR_ERR(maction
->flow_action_raw
.modify_hdr
);
396 maction
->flow_action_raw
.sub_type
=
397 MLX5_IB_FLOW_ACTION_MODIFY_HEADER
;
398 maction
->flow_action_raw
.dev
= dev
;
400 return &maction
->ib_action
;
403 static bool mlx5_ib_modify_header_supported(struct mlx5_ib_dev
*dev
)
405 return MLX5_CAP_FLOWTABLE_NIC_RX(dev
->mdev
,
406 max_modify_header_actions
) ||
407 MLX5_CAP_FLOWTABLE_NIC_TX(dev
->mdev
, max_modify_header_actions
);
410 static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER
)(
411 struct uverbs_attr_bundle
*attrs
)
413 struct ib_uobject
*uobj
= uverbs_attr_get_uobject(
414 attrs
, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE
);
415 struct mlx5_ib_dev
*mdev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
416 enum mlx5_ib_uapi_flow_table_type ft_type
;
417 struct ib_flow_action
*action
;
422 if (!mlx5_ib_modify_header_supported(mdev
))
425 in
= uverbs_attr_get_alloced_ptr(attrs
,
426 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM
);
428 num_actions
= uverbs_attr_ptr_get_array_size(
429 attrs
, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM
,
430 MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto
));
434 ret
= uverbs_get_const(&ft_type
, attrs
,
435 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE
);
438 action
= mlx5_ib_create_modify_header(mdev
, ft_type
, num_actions
, in
);
440 return PTR_ERR(action
);
442 uverbs_flow_action_fill_action(action
, uobj
, &mdev
->ib_dev
,
443 IB_FLOW_ACTION_UNSPECIFIED
);
448 static bool mlx5_ib_flow_action_packet_reformat_valid(struct mlx5_ib_dev
*ibdev
,
449 u8 packet_reformat_type
,
452 switch (packet_reformat_type
) {
453 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL
:
454 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX
)
455 return MLX5_CAP_FLOWTABLE(ibdev
->mdev
,
456 encap_general_header
);
458 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL
:
459 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX
)
460 return MLX5_CAP_FLOWTABLE_NIC_TX(ibdev
->mdev
,
461 reformat_l2_to_l3_tunnel
);
463 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2
:
464 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX
)
465 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev
->mdev
,
466 reformat_l3_tunnel_to_l2
);
468 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2
:
469 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX
)
470 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev
->mdev
, decap
);
479 static int mlx5_ib_dv_to_prm_packet_reforamt_type(u8 dv_prt
, u8
*prm_prt
)
482 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL
:
483 *prm_prt
= MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL
;
485 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2
:
486 *prm_prt
= MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2
;
488 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL
:
489 *prm_prt
= MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL
;
498 static int mlx5_ib_flow_action_create_packet_reformat_ctx(
499 struct mlx5_ib_dev
*dev
,
500 struct mlx5_ib_flow_action
*maction
,
501 u8 ft_type
, u8 dv_prt
,
502 void *in
, size_t len
)
504 enum mlx5_flow_namespace_type
namespace;
508 ret
= mlx5_ib_ft_type_to_namespace(ft_type
, &namespace);
512 ret
= mlx5_ib_dv_to_prm_packet_reforamt_type(dv_prt
, &prm_prt
);
516 maction
->flow_action_raw
.pkt_reformat
=
517 mlx5_packet_reformat_alloc(dev
->mdev
, prm_prt
, len
,
519 if (IS_ERR(maction
->flow_action_raw
.pkt_reformat
)) {
520 ret
= PTR_ERR(maction
->flow_action_raw
.pkt_reformat
);
524 maction
->flow_action_raw
.sub_type
=
525 MLX5_IB_FLOW_ACTION_PACKET_REFORMAT
;
526 maction
->flow_action_raw
.dev
= dev
;
531 static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT
)(
532 struct uverbs_attr_bundle
*attrs
)
534 struct ib_uobject
*uobj
= uverbs_attr_get_uobject(attrs
,
535 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE
);
536 struct mlx5_ib_dev
*mdev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
537 enum mlx5_ib_uapi_flow_action_packet_reformat_type dv_prt
;
538 enum mlx5_ib_uapi_flow_table_type ft_type
;
539 struct mlx5_ib_flow_action
*maction
;
542 ret
= uverbs_get_const(&ft_type
, attrs
,
543 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE
);
547 ret
= uverbs_get_const(&dv_prt
, attrs
,
548 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE
);
552 if (!mlx5_ib_flow_action_packet_reformat_valid(mdev
, dv_prt
, ft_type
))
555 maction
= kzalloc(sizeof(*maction
), GFP_KERNEL
);
560 MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2
) {
561 maction
->flow_action_raw
.sub_type
=
562 MLX5_IB_FLOW_ACTION_DECAP
;
563 maction
->flow_action_raw
.dev
= mdev
;
568 in
= uverbs_attr_get_alloced_ptr(attrs
,
569 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF
);
575 len
= uverbs_attr_get_len(attrs
,
576 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF
);
578 ret
= mlx5_ib_flow_action_create_packet_reformat_ctx(mdev
,
579 maction
, ft_type
, dv_prt
, in
, len
);
584 uverbs_flow_action_fill_action(&maction
->ib_action
, uobj
, &mdev
->ib_dev
,
585 IB_FLOW_ACTION_UNSPECIFIED
);
593 DECLARE_UVERBS_NAMED_METHOD(
594 MLX5_IB_METHOD_CREATE_FLOW
,
595 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE
,
600 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE
,
601 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params
)),
604 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_MATCHER
,
605 MLX5_IB_OBJECT_FLOW_MATCHER
,
608 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_QP
,
611 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX
,
612 MLX5_IB_OBJECT_DEVX_OBJ
,
614 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS
,
615 UVERBS_OBJECT_FLOW_ACTION
,
616 UVERBS_ACCESS_READ
, 1,
617 MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS
,
619 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_TAG
,
620 UVERBS_ATTR_TYPE(u32
),
622 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX
,
623 MLX5_IB_OBJECT_DEVX_OBJ
,
624 UVERBS_ACCESS_READ
, 1, 1,
626 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
,
627 UVERBS_ATTR_MIN_SIZE(sizeof(u32
)),
631 DECLARE_UVERBS_NAMED_METHOD_DESTROY(
632 MLX5_IB_METHOD_DESTROY_FLOW
,
633 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE
,
635 UVERBS_ACCESS_DESTROY
,
638 ADD_UVERBS_METHODS(mlx5_ib_fs
,
640 &UVERBS_METHOD(MLX5_IB_METHOD_CREATE_FLOW
),
641 &UVERBS_METHOD(MLX5_IB_METHOD_DESTROY_FLOW
));
643 DECLARE_UVERBS_NAMED_METHOD(
644 MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER
,
645 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE
,
646 UVERBS_OBJECT_FLOW_ACTION
,
649 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM
,
650 UVERBS_ATTR_MIN_SIZE(MLX5_UN_SZ_BYTES(
651 set_action_in_add_action_in_auto
)),
654 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE
,
655 enum mlx5_ib_uapi_flow_table_type
,
658 DECLARE_UVERBS_NAMED_METHOD(
659 MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT
,
660 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE
,
661 UVERBS_OBJECT_FLOW_ACTION
,
664 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF
,
665 UVERBS_ATTR_MIN_SIZE(1),
668 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE
,
669 enum mlx5_ib_uapi_flow_action_packet_reformat_type
,
671 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE
,
672 enum mlx5_ib_uapi_flow_table_type
,
676 mlx5_ib_flow_actions
,
677 UVERBS_OBJECT_FLOW_ACTION
,
678 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER
),
679 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT
));
681 DECLARE_UVERBS_NAMED_METHOD(
682 MLX5_IB_METHOD_FLOW_MATCHER_CREATE
,
683 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE
,
684 MLX5_IB_OBJECT_FLOW_MATCHER
,
688 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK
,
689 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params
)),
691 UVERBS_ATTR_ENUM_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE
,
694 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA
,
695 UVERBS_ATTR_TYPE(u8
),
697 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
,
700 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
,
701 enum mlx5_ib_uapi_flow_table_type
,
704 DECLARE_UVERBS_NAMED_METHOD_DESTROY(
705 MLX5_IB_METHOD_FLOW_MATCHER_DESTROY
,
706 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE
,
707 MLX5_IB_OBJECT_FLOW_MATCHER
,
708 UVERBS_ACCESS_DESTROY
,
711 DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER
,
712 UVERBS_TYPE_ALLOC_IDR(flow_matcher_cleanup
),
713 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_CREATE
),
714 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_DESTROY
));
716 const struct uapi_definition mlx5_ib_flow_defs
[] = {
717 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
718 MLX5_IB_OBJECT_FLOW_MATCHER
),
719 UAPI_DEF_CHAIN_OBJ_TREE(
722 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION
,
723 &mlx5_ib_flow_actions
),