* Toggle a configured flow rule. * * @param priv * Pointer to private structure. * @param flow * Flow rule handle to toggle. * @param enable * Whether associated Verbs flow must be created or removed. * @param[out] error * Perform verbose error reporting if not NULL. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */
| 1027 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 1028 | */ |
| 1029 | static int |
| 1030 | mlx4_flow_toggle(struct mlx4_priv *priv, |
| 1031 | struct rte_flow *flow, |
| 1032 | int enable, |
| 1033 | struct rte_flow_error *error) |
| 1034 | { |
| 1035 | struct ibv_qp *qp = NULL; |
| 1036 | const char *msg; |
| 1037 | int err; |
| 1038 | |
| 1039 | if (!enable) { |
| 1040 | if (!flow->ibv_flow) |
| 1041 | return 0; |
| 1042 | claim_zero(mlx4_glue->destroy_flow(flow->ibv_flow)); |
| 1043 | flow->ibv_flow = NULL; |
| 1044 | if (flow->drop) |
| 1045 | mlx4_drop_put(priv->drop); |
| 1046 | else if (flow->rss) |
| 1047 | mlx4_rss_detach(flow->rss); |
| 1048 | return 0; |
| 1049 | } |
| 1050 | MLX4_ASSERT(flow->ibv_attr); |
| 1051 | if (!flow->internal && |
| 1052 | !priv->isolated && |
| 1053 | flow->ibv_attr->priority == MLX4_FLOW_PRIORITY_LAST) { |
| 1054 | if (flow->ibv_flow) { |
| 1055 | claim_zero(mlx4_glue->destroy_flow(flow->ibv_flow)); |
| 1056 | flow->ibv_flow = NULL; |
| 1057 | if (flow->drop) |
| 1058 | mlx4_drop_put(priv->drop); |
| 1059 | else if (flow->rss) |
| 1060 | mlx4_rss_detach(flow->rss); |
| 1061 | } |
| 1062 | err = EACCES; |
| 1063 | msg = ("priority level " |
| 1064 | MLX4_STR_EXPAND(MLX4_FLOW_PRIORITY_LAST) |
| 1065 | " is reserved when not in isolated mode"); |
| 1066 | goto error; |
| 1067 | } |
| 1068 | if (flow->rss) { |
| 1069 | struct mlx4_rss *rss = flow->rss; |
| 1070 | int missing = 0; |
| 1071 | unsigned int i; |
| 1072 | |
| 1073 | /* Stop at the first nonexistent target queue. */ |
| 1074 | for (i = 0; i != rss->queues; ++i) |
| 1075 | if (rss->queue_id[i] >= |
| 1076 | ETH_DEV(priv)->data->nb_rx_queues || |
| 1077 | !ETH_DEV(priv)->data->rx_queues[rss->queue_id[i]]) { |
| 1078 | missing = 1; |
| 1079 | break; |
| 1080 | } |
| 1081 | if (flow->ibv_flow) { |
| 1082 | if (missing ^ !flow->drop) |
| 1083 | return 0; |
| 1084 | /* Verbs flow needs updating. */ |
| 1085 | claim_zero(mlx4_glue->destroy_flow(flow->ibv_flow)); |
| 1086 | flow->ibv_flow = NULL; |
no test coverage detected