diff --git a/libibverbs/cmd_flow_action.c b/libibverbs/cmd_flow_action.c
index 122ad04..b5878db 100644
--- a/libibverbs/cmd_flow_action.c
+++ b/libibverbs/cmd_flow_action.c
@@ -118,8 +118,8 @@ int ibv_cmd_modify_flow_action_esp(struct verbs_flow_action *flow_action,
 
 int ibv_cmd_destroy_flow_action(struct verbs_flow_action *action)
 {
-	DECLARE_COMMAND_BUFFER(cmd, UVERBS_OBJECT_FLOW_ACTION,
-			       UVERBS_METHOD_FLOW_ACTION_DESTROY, 1);
+	DECLARE_COMMAND_BUFFER_LINK(cmd, UVERBS_OBJECT_FLOW_ACTION,
+				    UVERBS_METHOD_FLOW_ACTION_DESTROY, 1, NULL);
 
 	fill_attr_in_obj(cmd, UVERBS_ATTR_DESTROY_FLOW_ACTION_HANDLE,
 			 action->handle);
diff --git a/providers/mlx5/mlx5.c b/providers/mlx5/mlx5.c
index 39a3971..8878194 100644
--- a/providers/mlx5/mlx5.c
+++ b/providers/mlx5/mlx5.c
@@ -119,16 +119,19 @@ static const struct verbs_context_ops mlx5_ctx_common_ops = {
 	.close_xrcd = mlx5_close_xrcd,
 	.create_cq_ex = mlx5_create_cq_ex,
 	.create_flow = mlx5_create_flow,
+	.create_flow_action_esp = mlx5_create_flow_action_esp,
 	.create_qp_ex = mlx5_create_qp_ex,
 	.create_rwq_ind_table = mlx5_create_rwq_ind_table,
 	.create_srq_ex = mlx5_create_srq_ex,
 	.create_wq = mlx5_create_wq,
 	.dealloc_td = mlx5_dealloc_td,
 	.destroy_flow = mlx5_destroy_flow,
+	.destroy_flow_action = mlx5_destroy_flow_action,
 	.destroy_rwq_ind_table = mlx5_destroy_rwq_ind_table,
 	.destroy_wq = mlx5_destroy_wq,
 	.get_srq_num = mlx5_get_srq_num,
 	.modify_cq = mlx5_modify_cq,
+	.modify_flow_action_esp = mlx5_modify_flow_action_esp,
 	.modify_qp_rate_limit = mlx5_modify_qp_rate_limit,
 	.modify_wq = mlx5_modify_wq,
 	.open_xrcd = mlx5_open_xrcd,
diff --git a/providers/mlx5/mlx5.h b/providers/mlx5/mlx5.h
index 9f640f7..18895db 100644
--- a/providers/mlx5/mlx5.h
+++ b/providers/mlx5/mlx5.h
@@ -807,6 +807,11 @@ struct ibv_srq *mlx5_create_srq_ex(struct ibv_context *context,
 int mlx5_post_srq_ops(struct ibv_srq *srq,
 		      struct ibv_ops_wr *wr,
 		      struct ibv_ops_wr **bad_wr);
+struct ibv_flow_action *mlx5_create_flow_action_esp(struct ibv_context *ctx,
+						    struct ibv_flow_action_esp_attr *attr);
+int mlx5_destroy_flow_action(struct ibv_flow_action *action);
+int mlx5_modify_flow_action_esp(struct ibv_flow_action *action,
+				struct ibv_flow_action_esp_attr *attr);
 
 struct ibv_td *mlx5_alloc_td(struct ibv_context *context, struct ibv_td_init_attr *init_attr);
 int mlx5_dealloc_td(struct ibv_td *td);
diff --git a/providers/mlx5/verbs.c b/providers/mlx5/verbs.c
index 9ef4edd..06f6408 100644
--- a/providers/mlx5/verbs.c
+++ b/providers/mlx5/verbs.c
@@ -2964,3 +2964,61 @@ int mlx5_modify_cq(struct ibv_cq *cq, struct ibv_modify_cq_attr *attr)
 
 	return ibv_cmd_modify_cq(cq, attr, &cmd, sizeof(cmd));
 }
+
+static struct ibv_flow_action *_mlx5_create_flow_action_esp(struct ibv_context *ctx,
+							    struct ibv_flow_action_esp_attr *attr,
+							    struct ibv_command_buffer *driver_attr)
+{
+	struct verbs_flow_action *action;
+	int ret;
+
+	if (!check_comp_mask(attr->comp_mask, IBV_FLOW_ACTION_ESP_MASK_ESN)) {
+		errno = EOPNOTSUPP;
+		return NULL;
+	}
+
+	action = calloc(1, sizeof(*action));
+	if (!action) {
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	ret = ibv_cmd_create_flow_action_esp(ctx, attr, action, driver_attr);
+	if (ret) {
+		free(action);
+		return NULL;
+	}
+
+	return &action->action;
+}
+
+struct ibv_flow_action *mlx5_create_flow_action_esp(struct ibv_context *ctx,
+						    struct ibv_flow_action_esp_attr *attr)
+{
+	return _mlx5_create_flow_action_esp(ctx, attr, NULL);
+}
+
+int mlx5_modify_flow_action_esp(struct ibv_flow_action *action,
+				struct ibv_flow_action_esp_attr *attr)
+{
+	struct verbs_flow_action *vaction =
+		container_of(action, struct verbs_flow_action, action);
+
+	if (!check_comp_mask(attr->comp_mask, IBV_FLOW_ACTION_ESP_MASK_ESN))
+		return EOPNOTSUPP;
+
+	return ibv_cmd_modify_flow_action_esp(vaction, attr, NULL);
+}
+
+int mlx5_destroy_flow_action(struct ibv_flow_action *action)
+{
+	struct verbs_flow_action *vaction =
+		container_of(action, struct verbs_flow_action, action);
+	int ret = ibv_cmd_destroy_flow_action(vaction);
+
+	if (!ret)
+		free(action);
+
+	return ret;
+}
+
