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
;
45 static const struct uverbs_attr_spec mlx5_ib_flow_type
[] = {
46 [MLX5_IB_FLOW_TYPE_NORMAL
] = {
47 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
49 .len
= sizeof(u16
), /* data is priority */
50 .min_len
= sizeof(u16
),
53 [MLX5_IB_FLOW_TYPE_SNIFFER
] = {
54 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
55 UVERBS_ATTR_NO_DATA(),
57 [MLX5_IB_FLOW_TYPE_ALL_DEFAULT
] = {
58 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
59 UVERBS_ATTR_NO_DATA(),
61 [MLX5_IB_FLOW_TYPE_MC_DEFAULT
] = {
62 .type
= UVERBS_ATTR_TYPE_PTR_IN
,
63 UVERBS_ATTR_NO_DATA(),
67 #define MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS 2
68 static int UVERBS_HANDLER(MLX5_IB_METHOD_CREATE_FLOW
)(
69 struct uverbs_attr_bundle
*attrs
)
71 struct mlx5_flow_context flow_context
= {.flow_tag
= MLX5_FS_DEFAULT_FLOW_TAG
};
72 struct mlx5_ib_flow_handler
*flow_handler
;
73 struct mlx5_ib_flow_matcher
*fs_matcher
;
74 struct ib_uobject
**arr_flow_actions
;
75 struct ib_uflow_resources
*uflow_res
;
76 struct mlx5_flow_act flow_act
= {};
78 int dest_id
, dest_type
;
81 bool dest_devx
, dest_qp
;
82 struct ib_qp
*qp
= NULL
;
83 struct ib_uobject
*uobj
=
84 uverbs_attr_get_uobject(attrs
, MLX5_IB_ATTR_CREATE_FLOW_HANDLE
);
85 struct mlx5_ib_dev
*dev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
91 if (!capable(CAP_NET_RAW
))
95 uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX
);
96 dest_qp
= uverbs_attr_is_valid(attrs
,
97 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP
);
99 fs_matcher
= uverbs_attr_get_obj(attrs
,
100 MLX5_IB_ATTR_CREATE_FLOW_MATCHER
);
101 if (fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_BYPASS
&&
102 ((dest_devx
&& dest_qp
) || (!dest_devx
&& !dest_qp
)))
105 /* Allow only DEVX object as dest when inserting to FDB */
106 if (fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_FDB
&& !dest_devx
)
109 /* Allow only DEVX object or QP as dest when inserting to RDMA_RX */
110 if ((fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_RDMA_RX
) &&
111 ((!dest_devx
&& !dest_qp
) || (dest_devx
&& dest_qp
)))
115 devx_obj
= uverbs_attr_get_obj(
116 attrs
, MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX
);
117 if (IS_ERR(devx_obj
))
118 return PTR_ERR(devx_obj
);
120 /* Verify that the given DEVX object is a flow
121 * steering destination.
123 if (!mlx5_ib_devx_is_flow_dest(devx_obj
, &dest_id
, &dest_type
))
125 /* Allow only flow table as dest when inserting to FDB or RDMA_RX */
126 if ((fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_FDB
||
127 fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_RDMA_RX
) &&
128 dest_type
!= MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE
)
130 } else if (dest_qp
) {
131 struct mlx5_ib_qp
*mqp
;
133 qp
= uverbs_attr_get_obj(attrs
,
134 MLX5_IB_ATTR_CREATE_FLOW_DEST_QP
);
138 if (qp
->qp_type
!= IB_QPT_RAW_PACKET
)
142 if (mqp
->flags
& MLX5_IB_QP_RSS
)
143 dest_id
= mqp
->rss_qp
.tirn
;
145 dest_id
= mqp
->raw_packet_qp
.rq
.tirn
;
146 dest_type
= MLX5_FLOW_DESTINATION_TYPE_TIR
;
148 dest_type
= MLX5_FLOW_DESTINATION_TYPE_PORT
;
151 len
= uverbs_attr_get_uobjs_arr(attrs
,
152 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX
, &arr_flow_actions
);
154 devx_obj
= arr_flow_actions
[0]->object
;
156 if (uverbs_attr_is_valid(attrs
,
157 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
)) {
159 int num_offsets
= uverbs_attr_ptr_get_array_size(
161 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
,
164 if (num_offsets
!= 1)
167 offset_attr
= uverbs_attr_get_alloced_ptr(
169 MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
);
170 offset
= *offset_attr
;
173 if (!mlx5_ib_devx_is_flow_counter(devx_obj
, offset
,
177 flow_act
.action
|= MLX5_FLOW_CONTEXT_ACTION_COUNT
;
180 if (dest_type
== MLX5_FLOW_DESTINATION_TYPE_TIR
&&
181 fs_matcher
->ns_type
== MLX5_FLOW_NAMESPACE_EGRESS
)
184 cmd_in
= uverbs_attr_get_alloced_ptr(
185 attrs
, MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE
);
186 inlen
= uverbs_attr_get_len(attrs
,
187 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE
);
189 uflow_res
= flow_resources_alloc(MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS
);
193 len
= uverbs_attr_get_uobjs_arr(attrs
,
194 MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS
, &arr_flow_actions
);
195 for (i
= 0; i
< len
; i
++) {
196 struct mlx5_ib_flow_action
*maction
=
197 to_mflow_act(arr_flow_actions
[i
]->object
);
199 ret
= parse_flow_flow_action(maction
, false, &flow_act
);
202 flow_resources_add(uflow_res
, IB_FLOW_SPEC_ACTION_HANDLE
,
203 arr_flow_actions
[i
]->object
);
206 ret
= uverbs_copy_from(&flow_context
.flow_tag
, attrs
,
207 MLX5_IB_ATTR_CREATE_FLOW_TAG
);
209 if (flow_context
.flow_tag
>= BIT(24)) {
213 flow_context
.flags
|= FLOW_CONTEXT_HAS_TAG
;
216 flow_handler
= mlx5_ib_raw_fs_rule_add(dev
, fs_matcher
,
222 if (IS_ERR(flow_handler
)) {
223 ret
= PTR_ERR(flow_handler
);
227 ib_set_flow(uobj
, &flow_handler
->ibflow
, qp
, &dev
->ib_dev
, uflow_res
);
231 ib_uverbs_flow_resources_free(uflow_res
);
235 static int flow_matcher_cleanup(struct ib_uobject
*uobject
,
236 enum rdma_remove_reason why
,
237 struct uverbs_attr_bundle
*attrs
)
239 struct mlx5_ib_flow_matcher
*obj
= uobject
->object
;
242 ret
= ib_destroy_usecnt(&obj
->usecnt
, why
, uobject
);
250 static int mlx5_ib_matcher_ns(struct uverbs_attr_bundle
*attrs
,
251 struct mlx5_ib_flow_matcher
*obj
)
253 enum mlx5_ib_uapi_flow_table_type ft_type
=
254 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX
;
258 /* New users should use MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE and older
259 * users should switch to it. We leave this to not break userspace
261 if (uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
) &&
262 uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
))
265 if (uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
)) {
266 err
= uverbs_get_const(&ft_type
, attrs
,
267 MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
);
271 err
= mlx5_ib_ft_type_to_namespace(ft_type
, &obj
->ns_type
);
278 if (uverbs_attr_is_valid(attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
)) {
279 err
= uverbs_get_flags32(&flags
, attrs
,
280 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
,
281 IB_FLOW_ATTR_FLAGS_EGRESS
);
286 mlx5_ib_ft_type_to_namespace(
287 MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX
,
293 obj
->ns_type
= MLX5_FLOW_NAMESPACE_BYPASS
;
298 static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_MATCHER_CREATE
)(
299 struct uverbs_attr_bundle
*attrs
)
301 struct ib_uobject
*uobj
= uverbs_attr_get_uobject(
302 attrs
, MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE
);
303 struct mlx5_ib_dev
*dev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
304 struct mlx5_ib_flow_matcher
*obj
;
307 obj
= kzalloc(sizeof(struct mlx5_ib_flow_matcher
), GFP_KERNEL
);
311 obj
->mask_len
= uverbs_attr_get_len(
312 attrs
, MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK
);
313 err
= uverbs_copy_from(&obj
->matcher_mask
,
315 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK
);
319 obj
->flow_type
= uverbs_attr_get_enum_id(
320 attrs
, MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE
);
322 if (obj
->flow_type
== MLX5_IB_FLOW_TYPE_NORMAL
) {
323 err
= uverbs_copy_from(&obj
->priority
,
325 MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE
);
330 err
= uverbs_copy_from(&obj
->match_criteria_enable
,
332 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA
);
336 err
= mlx5_ib_matcher_ns(attrs
, obj
);
341 obj
->mdev
= dev
->mdev
;
342 atomic_set(&obj
->usecnt
, 0);
350 void mlx5_ib_destroy_flow_action_raw(struct mlx5_ib_flow_action
*maction
)
352 switch (maction
->flow_action_raw
.sub_type
) {
353 case MLX5_IB_FLOW_ACTION_MODIFY_HEADER
:
354 mlx5_modify_header_dealloc(maction
->flow_action_raw
.dev
->mdev
,
355 maction
->flow_action_raw
.modify_hdr
);
357 case MLX5_IB_FLOW_ACTION_PACKET_REFORMAT
:
358 mlx5_packet_reformat_dealloc(maction
->flow_action_raw
.dev
->mdev
,
359 maction
->flow_action_raw
.pkt_reformat
);
361 case MLX5_IB_FLOW_ACTION_DECAP
:
368 static struct ib_flow_action
*
369 mlx5_ib_create_modify_header(struct mlx5_ib_dev
*dev
,
370 enum mlx5_ib_uapi_flow_table_type ft_type
,
371 u8 num_actions
, void *in
)
373 enum mlx5_flow_namespace_type
namespace;
374 struct mlx5_ib_flow_action
*maction
;
377 ret
= mlx5_ib_ft_type_to_namespace(ft_type
, &namespace);
379 return ERR_PTR(-EINVAL
);
381 maction
= kzalloc(sizeof(*maction
), GFP_KERNEL
);
383 return ERR_PTR(-ENOMEM
);
385 maction
->flow_action_raw
.modify_hdr
=
386 mlx5_modify_header_alloc(dev
->mdev
, namespace, num_actions
, in
);
388 if (IS_ERR(maction
->flow_action_raw
.modify_hdr
)) {
389 ret
= PTR_ERR(maction
->flow_action_raw
.modify_hdr
);
393 maction
->flow_action_raw
.sub_type
=
394 MLX5_IB_FLOW_ACTION_MODIFY_HEADER
;
395 maction
->flow_action_raw
.dev
= dev
;
397 return &maction
->ib_action
;
400 static bool mlx5_ib_modify_header_supported(struct mlx5_ib_dev
*dev
)
402 return MLX5_CAP_FLOWTABLE_NIC_RX(dev
->mdev
,
403 max_modify_header_actions
) ||
404 MLX5_CAP_FLOWTABLE_NIC_TX(dev
->mdev
, max_modify_header_actions
);
407 static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER
)(
408 struct uverbs_attr_bundle
*attrs
)
410 struct ib_uobject
*uobj
= uverbs_attr_get_uobject(
411 attrs
, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE
);
412 struct mlx5_ib_dev
*mdev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
413 enum mlx5_ib_uapi_flow_table_type ft_type
;
414 struct ib_flow_action
*action
;
419 if (!mlx5_ib_modify_header_supported(mdev
))
422 in
= uverbs_attr_get_alloced_ptr(attrs
,
423 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM
);
425 num_actions
= uverbs_attr_ptr_get_array_size(
426 attrs
, MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM
,
427 MLX5_UN_SZ_BYTES(set_action_in_add_action_in_auto
));
431 ret
= uverbs_get_const(&ft_type
, attrs
,
432 MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE
);
435 action
= mlx5_ib_create_modify_header(mdev
, ft_type
, num_actions
, in
);
437 return PTR_ERR(action
);
439 uverbs_flow_action_fill_action(action
, uobj
, &mdev
->ib_dev
,
440 IB_FLOW_ACTION_UNSPECIFIED
);
445 static bool mlx5_ib_flow_action_packet_reformat_valid(struct mlx5_ib_dev
*ibdev
,
446 u8 packet_reformat_type
,
449 switch (packet_reformat_type
) {
450 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL
:
451 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX
)
452 return MLX5_CAP_FLOWTABLE(ibdev
->mdev
,
453 encap_general_header
);
455 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL
:
456 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_TX
)
457 return MLX5_CAP_FLOWTABLE_NIC_TX(ibdev
->mdev
,
458 reformat_l2_to_l3_tunnel
);
460 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2
:
461 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX
)
462 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev
->mdev
,
463 reformat_l3_tunnel_to_l2
);
465 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2
:
466 if (ft_type
== MLX5_IB_UAPI_FLOW_TABLE_TYPE_NIC_RX
)
467 return MLX5_CAP_FLOWTABLE_NIC_RX(ibdev
->mdev
, decap
);
476 static int mlx5_ib_dv_to_prm_packet_reforamt_type(u8 dv_prt
, u8
*prm_prt
)
479 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L2_TUNNEL
:
480 *prm_prt
= MLX5_REFORMAT_TYPE_L2_TO_L2_TUNNEL
;
482 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L3_TUNNEL_TO_L2
:
483 *prm_prt
= MLX5_REFORMAT_TYPE_L3_TUNNEL_TO_L2
;
485 case MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TO_L3_TUNNEL
:
486 *prm_prt
= MLX5_REFORMAT_TYPE_L2_TO_L3_TUNNEL
;
495 static int mlx5_ib_flow_action_create_packet_reformat_ctx(
496 struct mlx5_ib_dev
*dev
,
497 struct mlx5_ib_flow_action
*maction
,
498 u8 ft_type
, u8 dv_prt
,
499 void *in
, size_t len
)
501 enum mlx5_flow_namespace_type
namespace;
505 ret
= mlx5_ib_ft_type_to_namespace(ft_type
, &namespace);
509 ret
= mlx5_ib_dv_to_prm_packet_reforamt_type(dv_prt
, &prm_prt
);
513 maction
->flow_action_raw
.pkt_reformat
=
514 mlx5_packet_reformat_alloc(dev
->mdev
, prm_prt
, len
,
516 if (IS_ERR(maction
->flow_action_raw
.pkt_reformat
)) {
517 ret
= PTR_ERR(maction
->flow_action_raw
.pkt_reformat
);
521 maction
->flow_action_raw
.sub_type
=
522 MLX5_IB_FLOW_ACTION_PACKET_REFORMAT
;
523 maction
->flow_action_raw
.dev
= dev
;
528 static int UVERBS_HANDLER(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT
)(
529 struct uverbs_attr_bundle
*attrs
)
531 struct ib_uobject
*uobj
= uverbs_attr_get_uobject(attrs
,
532 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE
);
533 struct mlx5_ib_dev
*mdev
= mlx5_udata_to_mdev(&attrs
->driver_udata
);
534 enum mlx5_ib_uapi_flow_action_packet_reformat_type dv_prt
;
535 enum mlx5_ib_uapi_flow_table_type ft_type
;
536 struct mlx5_ib_flow_action
*maction
;
539 ret
= uverbs_get_const(&ft_type
, attrs
,
540 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE
);
544 ret
= uverbs_get_const(&dv_prt
, attrs
,
545 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE
);
549 if (!mlx5_ib_flow_action_packet_reformat_valid(mdev
, dv_prt
, ft_type
))
552 maction
= kzalloc(sizeof(*maction
), GFP_KERNEL
);
557 MLX5_IB_UAPI_FLOW_ACTION_PACKET_REFORMAT_TYPE_L2_TUNNEL_TO_L2
) {
558 maction
->flow_action_raw
.sub_type
=
559 MLX5_IB_FLOW_ACTION_DECAP
;
560 maction
->flow_action_raw
.dev
= mdev
;
565 in
= uverbs_attr_get_alloced_ptr(attrs
,
566 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF
);
572 len
= uverbs_attr_get_len(attrs
,
573 MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF
);
575 ret
= mlx5_ib_flow_action_create_packet_reformat_ctx(mdev
,
576 maction
, ft_type
, dv_prt
, in
, len
);
581 uverbs_flow_action_fill_action(&maction
->ib_action
, uobj
, &mdev
->ib_dev
,
582 IB_FLOW_ACTION_UNSPECIFIED
);
590 DECLARE_UVERBS_NAMED_METHOD(
591 MLX5_IB_METHOD_CREATE_FLOW
,
592 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE
,
597 MLX5_IB_ATTR_CREATE_FLOW_MATCH_VALUE
,
598 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params
)),
601 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_MATCHER
,
602 MLX5_IB_OBJECT_FLOW_MATCHER
,
605 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_QP
,
608 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_DEST_DEVX
,
609 MLX5_IB_OBJECT_DEVX_OBJ
,
611 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS
,
612 UVERBS_OBJECT_FLOW_ACTION
,
613 UVERBS_ACCESS_READ
, 1,
614 MLX5_IB_CREATE_FLOW_MAX_FLOW_ACTIONS
,
616 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_TAG
,
617 UVERBS_ATTR_TYPE(u32
),
619 UVERBS_ATTR_IDRS_ARR(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX
,
620 MLX5_IB_OBJECT_DEVX_OBJ
,
621 UVERBS_ACCESS_READ
, 1, 1,
623 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_FLOW_ARR_COUNTERS_DEVX_OFFSET
,
624 UVERBS_ATTR_MIN_SIZE(sizeof(u32
)),
628 DECLARE_UVERBS_NAMED_METHOD_DESTROY(
629 MLX5_IB_METHOD_DESTROY_FLOW
,
630 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_FLOW_HANDLE
,
632 UVERBS_ACCESS_DESTROY
,
635 ADD_UVERBS_METHODS(mlx5_ib_fs
,
637 &UVERBS_METHOD(MLX5_IB_METHOD_CREATE_FLOW
),
638 &UVERBS_METHOD(MLX5_IB_METHOD_DESTROY_FLOW
));
640 DECLARE_UVERBS_NAMED_METHOD(
641 MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER
,
642 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_HANDLE
,
643 UVERBS_OBJECT_FLOW_ACTION
,
646 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_ACTIONS_PRM
,
647 UVERBS_ATTR_MIN_SIZE(MLX5_UN_SZ_BYTES(
648 set_action_in_add_action_in_auto
)),
651 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_MODIFY_HEADER_FT_TYPE
,
652 enum mlx5_ib_uapi_flow_table_type
,
655 DECLARE_UVERBS_NAMED_METHOD(
656 MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT
,
657 UVERBS_ATTR_IDR(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_HANDLE
,
658 UVERBS_OBJECT_FLOW_ACTION
,
661 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_DATA_BUF
,
662 UVERBS_ATTR_MIN_SIZE(1),
665 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_TYPE
,
666 enum mlx5_ib_uapi_flow_action_packet_reformat_type
,
668 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_CREATE_PACKET_REFORMAT_FT_TYPE
,
669 enum mlx5_ib_uapi_flow_table_type
,
673 mlx5_ib_flow_actions
,
674 UVERBS_OBJECT_FLOW_ACTION
,
675 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_MODIFY_HEADER
),
676 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_ACTION_CREATE_PACKET_REFORMAT
));
678 DECLARE_UVERBS_NAMED_METHOD(
679 MLX5_IB_METHOD_FLOW_MATCHER_CREATE
,
680 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_CREATE_HANDLE
,
681 MLX5_IB_OBJECT_FLOW_MATCHER
,
685 MLX5_IB_ATTR_FLOW_MATCHER_MATCH_MASK
,
686 UVERBS_ATTR_SIZE(1, sizeof(struct mlx5_ib_match_params
)),
688 UVERBS_ATTR_ENUM_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_TYPE
,
691 UVERBS_ATTR_PTR_IN(MLX5_IB_ATTR_FLOW_MATCHER_MATCH_CRITERIA
,
692 UVERBS_ATTR_TYPE(u8
),
694 UVERBS_ATTR_FLAGS_IN(MLX5_IB_ATTR_FLOW_MATCHER_FLOW_FLAGS
,
697 UVERBS_ATTR_CONST_IN(MLX5_IB_ATTR_FLOW_MATCHER_FT_TYPE
,
698 enum mlx5_ib_uapi_flow_table_type
,
701 DECLARE_UVERBS_NAMED_METHOD_DESTROY(
702 MLX5_IB_METHOD_FLOW_MATCHER_DESTROY
,
703 UVERBS_ATTR_IDR(MLX5_IB_ATTR_FLOW_MATCHER_DESTROY_HANDLE
,
704 MLX5_IB_OBJECT_FLOW_MATCHER
,
705 UVERBS_ACCESS_DESTROY
,
708 DECLARE_UVERBS_NAMED_OBJECT(MLX5_IB_OBJECT_FLOW_MATCHER
,
709 UVERBS_TYPE_ALLOC_IDR(flow_matcher_cleanup
),
710 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_CREATE
),
711 &UVERBS_METHOD(MLX5_IB_METHOD_FLOW_MATCHER_DESTROY
));
713 const struct uapi_definition mlx5_ib_flow_defs
[] = {
714 UAPI_DEF_CHAIN_OBJ_TREE_NAMED(
715 MLX5_IB_OBJECT_FLOW_MATCHER
),
716 UAPI_DEF_CHAIN_OBJ_TREE(
719 UAPI_DEF_CHAIN_OBJ_TREE(UVERBS_OBJECT_FLOW_ACTION
,
720 &mlx5_ib_flow_actions
),