@@ -1,6 +1,8 @@
rdma_man_pages(
+ mlx5dv_create_flow.3.md
mlx5dv_create_flow_action_modify_header.3.md
mlx5dv_create_flow_action_packet_reformat.3.md
+ mlx5dv_create_flow_matcher.3.md
mlx5dv_flow_action_esp.3.md
mlx5dv_get_clock_info.3
mlx5dv_init_obj.3
new file mode 100644
@@ -0,0 +1,76 @@
+---
+layout: page
+title: mlx5dv_create_flow
+section: 3
+tagline: Verbs
+date: 2018-9-19
+header: "mlx5 Programmer's Manual"
+footer: mlx5
+---
+
+# NAME
+mlx5dv_create_flow - creates a steering flow rule
+
+# SYNOPSIS
+
+```c
+#include <infiniband/mlx5dv.h>
+
+struct ibv_flow *
+mlx5dv_create_flow(struct mlx5dv_flow_matcher *flow_matcher,
+ struct mlx5dv_flow_match_parameters *match_value,
+ size_t num_actions,
+ struct mlx5dv_flow_action_attr actions_attr[])
+```
+
+
+# DESCRIPTION
+**mlx5dv_create_flow()** creates a steering flow rule with the ability
+to specify specific driver properties.
+
+# ARGUMENTS
+
+Please see *mlx5dv_create_flow_matcher(3)* for *flow_matcher* and *match_value*.
+
+## num_actions
+ Specifies how many actions are passed in *actions_attr*
+
+## actions_attr
+```c
+struct mlx5dv_flow_action_attr {
+ enum mlx5dv_flow_action_type type;
+ union {
+ struct ibv_qp *qp;
+ struct ibv_counters *counter;
+ struct ibv_flow_action *action;
+ uint32_t tag_value;
+ };
+};
+```
+
+## type
+ MLX5DV_FLOW_ACTION_DEST_IBV_QP
+ The QP passed will receive the matched packets.
+ MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION
+ The flow action to be applied.
+
+## qp
+ QP passed, to be used with *type* *MLX5DV_FLOW_ACTION_DEST_IBV_QP*.
+
+## action
+ Flow action, to be used with *type* *MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION*
+ see *mlx5dv_create_flow_action_modify_header(3)* and *mlx5dv_create_flow_action_packet_reformat(3)*.
+
+# RETURN VALUE
+
+**mlx5dv_create_flow**
+returns a pointer to the created flow rule, or NULL on failure.
+
+# SEE ALSO
+
+*mlx5dv_create_flow_action_modify_header(3)*, *mlx5dv_create_flow_action_packet_reformat(3)*,
+*mlx5dv_create_flow_matcher(3)*, *mlx5dv_create_qp(3)*, *ibv_create_qp_ex(3)*
+
+# AUTHOR
+
+Mark Bloch <marb@mellanox.com>
new file mode 100644
@@ -0,0 +1,90 @@
+---
+layout: page
+title: mlx5dv_create_flow_matcher
+section: 3
+tagline: Verbs
+date: 2018-9-19
+header: "mlx5 Programmer's Manual"
+footer: mlx5
+---
+
+# NAME
+mlx5dv_create_flow_matcher - creates a matcher to be used with *mlx5dv_create_flow(3)*
+
+# SYNOPSIS
+
+```c
+#include <infiniband/mlx5dv.h>
+
+struct mlx5dv_flow_matcher *
+mlx5dv_create_flow_matcher(struct ibv_context *context,
+ struct mlx5dv_flow_matcher_attr *attr)
+```
+
+# DESCRIPTION
+
+**mlx5dv_create_flow_matcher()** creates a flow matcher (mask) to be used
+with *mlx5dv_create_flow(3)*.
+
+# ARGUMENTS
+
+Please see *ibv_open_device(3)* for *context*.
+
+## attr
+```c
+struct mlx5dv_flow_matcher_attr {
+ enum ibv_flow_attr_type type;
+ uint32_t flags; /* From enum ibv_flow_flags */
+ uint16_t priority;
+ uint8_t match_criteria_enable; /* Device spec format */
+ struct mlx5dv_flow_match_parameters *match_mask;
+ uint64_t comp_mask;
+};
+```
+
+## type
+ Type of matcher to be created:
+ IBV_FLOW_ATTR_NORMAL:
+ Normal rule according to specification.
+
+## flags
+ special flags to control rule:
+ 0:
+ Nothing or zero value means matcher will store ingress flow rules.
+ IBV_FLOW_ATTR_FLAGS_EGRESS:
+ Specified this matcher will store egress flow rules.
+
+## priority
+ See *ibv_create_flow(3)*.
+
+## match_criteria_enable
+ What match criteria is configured in *match_mask*, passed in
+ device spec format.
+
+## match_mask
+```c
+struct mlx5dv_flow_match_parameters {
+ size_t match_sz;
+ uint64_t match_buf[]; /* Device spec format */
+};
+```
+
+## match_sz
+ Size in bytes of *match_buf*.
+
+## match_buf
+ Set which mask to be used, passed in
+ device spec format.
+
+# RETURN VALUE
+
+**mlx5dv_create_flow_matcher**
+returns a pointer to *mlx5dv_flow_matcher*, or NULL on failure
+
+# SEE ALSO
+
+*ibv_open_device(3)*, *ibv_create_flow(3)*
+
+# AUTHOR
+
+Mark Bloch <markb@mellanox.com>
@@ -3731,25 +3731,26 @@ int mlx5dv_destroy_flow_matcher(struct mlx5dv_flow_matcher *flow_matcher)
return 0;
}
+#define CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED 8
struct ibv_flow *
mlx5dv_create_flow(struct mlx5dv_flow_matcher *flow_matcher,
struct mlx5dv_flow_match_parameters *match_value,
size_t num_actions,
struct mlx5dv_flow_action_attr actions_attr[])
{
+ uint32_t flow_actions[CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED];
+ struct verbs_flow_action *vaction;
+ int num_flow_actions = 0;
struct mlx5_flow *mflow;
+ bool have_qp = false;
int ret;
+ int i;
DECLARE_COMMAND_BUFFER(cmd, UVERBS_OBJECT_FLOW,
MLX5_IB_METHOD_CREATE_FLOW,
- 4);
+ 5);
struct ib_uverbs_attr *handle;
enum mlx5dv_flow_action_type type;
- if (num_actions != 1) {
- errno = EOPNOTSUPP;
- return NULL;
- }
-
mflow = calloc(1, sizeof(*mflow));
if (!mflow) {
errno = ENOMEM;
@@ -3762,17 +3763,42 @@ mlx5dv_create_flow(struct mlx5dv_flow_matcher *flow_matcher,
match_value->match_sz);
fill_attr_in_obj(cmd, MLX5_IB_ATTR_CREATE_FLOW_MATCHER, flow_matcher->handle);
- type = actions_attr[0].type;
- switch (type) {
- case MLX5DV_FLOW_ACTION_DEST_IBV_QP:
- fill_attr_in_obj(cmd, MLX5_IB_ATTR_CREATE_FLOW_DEST_QP,
- actions_attr[0].qp->handle);
- break;
- default:
- errno = EOPNOTSUPP;
- goto err;
+ for (i = 0; i < num_actions; i++) {
+ type = actions_attr[i].type;
+ switch (type) {
+ case MLX5DV_FLOW_ACTION_DEST_IBV_QP:
+ if (have_qp) {
+ errno = EOPNOTSUPP;
+ goto err;
+ }
+ fill_attr_in_obj(cmd, MLX5_IB_ATTR_CREATE_FLOW_DEST_QP,
+ actions_attr[i].qp->handle);
+ have_qp = true;
+ break;
+ case MLX5DV_FLOW_ACTION_IBV_FLOW_ACTION:
+ if (num_flow_actions ==
+ CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED) {
+ errno = EOPNOTSUPP;
+ goto err;
+ }
+ vaction = container_of(actions_attr[i].action,
+ struct verbs_flow_action,
+ action);
+
+ flow_actions[num_flow_actions] = vaction->handle;
+ num_flow_actions++;
+ break;
+ default:
+ errno = EOPNOTSUPP;
+ goto err;
+ }
}
+ if (num_flow_actions)
+ fill_attr_in_objs_arr(cmd,
+ MLX5_IB_ATTR_CREATE_FLOW_ARR_FLOW_ACTIONS,
+ flow_actions,
+ num_flow_actions);
ret = execute_ioctl(flow_matcher->context, cmd);
if (ret)
goto err;