|
@@ -360,8 +360,8 @@ static void del_rule(struct fs_node *node)
|
|
|
memcpy(match_value, fte->val, sizeof(fte->val));
|
|
|
fs_get_obj(ft, fg->node.parent);
|
|
|
list_del(&rule->node.list);
|
|
|
- fte->dests_size--;
|
|
|
- if (fte->dests_size) {
|
|
|
+ if ((fte->action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) &&
|
|
|
+ --fte->dests_size) {
|
|
|
err = mlx5_cmd_update_fte(dev, ft,
|
|
|
fg->id, fte);
|
|
|
if (err)
|
|
@@ -763,7 +763,8 @@ static struct mlx5_flow_rule *alloc_rule(struct mlx5_flow_destination *dest)
|
|
|
return NULL;
|
|
|
|
|
|
rule->node.type = FS_TYPE_FLOW_DEST;
|
|
|
- memcpy(&rule->dest_attr, dest, sizeof(*dest));
|
|
|
+ if (dest)
|
|
|
+ memcpy(&rule->dest_attr, dest, sizeof(*dest));
|
|
|
|
|
|
return rule;
|
|
|
}
|
|
@@ -785,8 +786,9 @@ static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
|
|
|
/* Add dest to dests list- added as first element after the head */
|
|
|
tree_init_node(&rule->node, 1, del_rule);
|
|
|
list_add_tail(&rule->node.list, &fte->node.children);
|
|
|
- fte->dests_size++;
|
|
|
- if (fte->dests_size == 1)
|
|
|
+ if (dest)
|
|
|
+ fte->dests_size++;
|
|
|
+ if (fte->dests_size == 1 || !dest)
|
|
|
err = mlx5_cmd_create_fte(get_dev(&ft->node),
|
|
|
ft, fg->id, fte);
|
|
|
else
|
|
@@ -802,7 +804,8 @@ static struct mlx5_flow_rule *add_rule_fte(struct fs_fte *fte,
|
|
|
free_rule:
|
|
|
list_del(&rule->node.list);
|
|
|
kfree(rule);
|
|
|
- fte->dests_size--;
|
|
|
+ if (dest)
|
|
|
+ fte->dests_size--;
|
|
|
return ERR_PTR(err);
|
|
|
}
|
|
|
|
|
@@ -996,6 +999,9 @@ mlx5_add_flow_rule(struct mlx5_flow_table *ft,
|
|
|
struct mlx5_flow_group *g;
|
|
|
struct mlx5_flow_rule *rule;
|
|
|
|
|
|
+ if ((action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) && !dest)
|
|
|
+ return ERR_PTR(-EINVAL);
|
|
|
+
|
|
|
nested_lock_ref_node(&ft->node, FS_MUTEX_GRANDPARENT);
|
|
|
fs_for_each_fg(g, ft)
|
|
|
if (compare_match_criteria(g->mask.match_criteria_enable,
|