net/mlx5: Add support in forward to namespace
Currently, fs_core supports rule of forward the traffic to continue matching in the next priority, now we add support to forward the traffic matching in the next namespace. Signed-off-by: Maor Gottlieb <maorg@mellanox.com> Reviewed-by: Mark Bloch <markb@mellanox.com> Reviewed-by: Mark Zhang <markz@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com>
This commit is contained in:
parent
14c129e301
commit
9254f8ed15
|
@ -384,6 +384,12 @@ static struct fs_prio *find_prio(struct mlx5_flow_namespace *ns,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_fwd_next_action(u32 action)
|
||||||
|
{
|
||||||
|
return action & (MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO |
|
||||||
|
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS);
|
||||||
|
}
|
||||||
|
|
||||||
static bool check_valid_spec(const struct mlx5_flow_spec *spec)
|
static bool check_valid_spec(const struct mlx5_flow_spec *spec)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -502,7 +508,7 @@ static void del_sw_hw_rule(struct fs_node *node)
|
||||||
fs_get_obj(rule, node);
|
fs_get_obj(rule, node);
|
||||||
fs_get_obj(fte, rule->node.parent);
|
fs_get_obj(fte, rule->node.parent);
|
||||||
trace_mlx5_fs_del_rule(rule);
|
trace_mlx5_fs_del_rule(rule);
|
||||||
if (rule->sw_action == MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO) {
|
if (is_fwd_next_action(rule->sw_action)) {
|
||||||
mutex_lock(&rule->dest_attr.ft->lock);
|
mutex_lock(&rule->dest_attr.ft->lock);
|
||||||
list_del(&rule->next_ft);
|
list_del(&rule->next_ft);
|
||||||
mutex_unlock(&rule->dest_attr.ft->lock);
|
mutex_unlock(&rule->dest_attr.ft->lock);
|
||||||
|
@ -826,6 +832,36 @@ static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio)
|
||||||
return find_closest_ft(prio, true);
|
return find_closest_ft(prio, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct fs_prio *find_fwd_ns_prio(struct mlx5_flow_root_namespace *root,
|
||||||
|
struct mlx5_flow_namespace *ns)
|
||||||
|
{
|
||||||
|
struct mlx5_flow_namespace *root_ns = &root->ns;
|
||||||
|
struct fs_prio *iter_prio;
|
||||||
|
struct fs_prio *prio;
|
||||||
|
|
||||||
|
fs_get_obj(prio, ns->node.parent);
|
||||||
|
list_for_each_entry(iter_prio, &root_ns->node.children, node.list) {
|
||||||
|
if (iter_prio == prio &&
|
||||||
|
!list_is_last(&prio->node.children, &iter_prio->node.list))
|
||||||
|
return list_next_entry(iter_prio, node.list);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
|
||||||
|
struct mlx5_flow_act *flow_act)
|
||||||
|
{
|
||||||
|
struct mlx5_flow_root_namespace *root = find_root(&ft->node);
|
||||||
|
struct fs_prio *prio;
|
||||||
|
|
||||||
|
if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS)
|
||||||
|
prio = find_fwd_ns_prio(root, ft->ns);
|
||||||
|
else
|
||||||
|
fs_get_obj(prio, ft->node.parent);
|
||||||
|
|
||||||
|
return (prio) ? find_next_chained_ft(prio) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static int connect_fts_in_prio(struct mlx5_core_dev *dev,
|
static int connect_fts_in_prio(struct mlx5_core_dev *dev,
|
||||||
struct fs_prio *prio,
|
struct fs_prio *prio,
|
||||||
struct mlx5_flow_table *ft)
|
struct mlx5_flow_table *ft)
|
||||||
|
@ -976,6 +1012,10 @@ static int connect_fwd_rules(struct mlx5_core_dev *dev,
|
||||||
list_splice_init(&old_next_ft->fwd_rules, &new_next_ft->fwd_rules);
|
list_splice_init(&old_next_ft->fwd_rules, &new_next_ft->fwd_rules);
|
||||||
mutex_unlock(&old_next_ft->lock);
|
mutex_unlock(&old_next_ft->lock);
|
||||||
list_for_each_entry(iter, &new_next_ft->fwd_rules, next_ft) {
|
list_for_each_entry(iter, &new_next_ft->fwd_rules, next_ft) {
|
||||||
|
if ((iter->sw_action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS) &&
|
||||||
|
iter->ft->ns == new_next_ft->ns)
|
||||||
|
continue;
|
||||||
|
|
||||||
err = _mlx5_modify_rule_destination(iter, &dest);
|
err = _mlx5_modify_rule_destination(iter, &dest);
|
||||||
if (err)
|
if (err)
|
||||||
pr_err("mlx5_core: failed to modify rule to point on flow table %d\n",
|
pr_err("mlx5_core: failed to modify rule to point on flow table %d\n",
|
||||||
|
@ -1077,6 +1117,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
|
||||||
next_ft = unmanaged ? ft_attr->next_ft :
|
next_ft = unmanaged ? ft_attr->next_ft :
|
||||||
find_next_chained_ft(fs_prio);
|
find_next_chained_ft(fs_prio);
|
||||||
ft->def_miss_action = ns->def_miss_action;
|
ft->def_miss_action = ns->def_miss_action;
|
||||||
|
ft->ns = ns;
|
||||||
err = root->cmds->create_flow_table(root, ft, log_table_sz, next_ft);
|
err = root->cmds->create_flow_table(root, ft, log_table_sz, next_ft);
|
||||||
if (err)
|
if (err)
|
||||||
goto free_ft;
|
goto free_ft;
|
||||||
|
@ -1903,21 +1944,19 @@ mlx5_add_flow_rules(struct mlx5_flow_table *ft,
|
||||||
struct mlx5_flow_table *next_ft = NULL;
|
struct mlx5_flow_table *next_ft = NULL;
|
||||||
struct mlx5_flow_handle *handle = NULL;
|
struct mlx5_flow_handle *handle = NULL;
|
||||||
u32 sw_action = flow_act->action;
|
u32 sw_action = flow_act->action;
|
||||||
struct fs_prio *prio;
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!spec)
|
if (!spec)
|
||||||
spec = &zero_spec;
|
spec = &zero_spec;
|
||||||
|
|
||||||
if (!(sw_action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO))
|
if (!is_fwd_next_action(sw_action))
|
||||||
return _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest);
|
return _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest);
|
||||||
|
|
||||||
if (!fwd_next_prio_supported(ft))
|
if (!fwd_next_prio_supported(ft))
|
||||||
return ERR_PTR(-EOPNOTSUPP);
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
|
||||||
mutex_lock(&root->chain_lock);
|
mutex_lock(&root->chain_lock);
|
||||||
fs_get_obj(prio, ft->node.parent);
|
next_ft = find_next_fwd_ft(ft, flow_act);
|
||||||
next_ft = find_next_chained_ft(prio);
|
|
||||||
if (!next_ft) {
|
if (!next_ft) {
|
||||||
handle = ERR_PTR(-EOPNOTSUPP);
|
handle = ERR_PTR(-EOPNOTSUPP);
|
||||||
goto unlock;
|
goto unlock;
|
||||||
|
@ -1936,8 +1975,8 @@ mlx5_add_flow_rules(struct mlx5_flow_table *ft,
|
||||||
gen_dest[i].ft = next_ft;
|
gen_dest[i].ft = next_ft;
|
||||||
dest = gen_dest;
|
dest = gen_dest;
|
||||||
num_dest++;
|
num_dest++;
|
||||||
flow_act->action &=
|
flow_act->action &= ~(MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO |
|
||||||
~MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
|
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS);
|
||||||
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||||
handle = _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest);
|
handle = _mlx5_add_flow_rules(ft, spec, flow_act, dest, num_dest);
|
||||||
if (IS_ERR(handle))
|
if (IS_ERR(handle))
|
||||||
|
@ -1948,8 +1987,8 @@ mlx5_add_flow_rules(struct mlx5_flow_table *ft,
|
||||||
list_add(&handle->rule[num_dest - 1]->next_ft,
|
list_add(&handle->rule[num_dest - 1]->next_ft,
|
||||||
&next_ft->fwd_rules);
|
&next_ft->fwd_rules);
|
||||||
mutex_unlock(&next_ft->lock);
|
mutex_unlock(&next_ft->lock);
|
||||||
handle->rule[num_dest - 1]->sw_action =
|
handle->rule[num_dest - 1]->sw_action = sw_action;
|
||||||
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO;
|
handle->rule[num_dest - 1]->ft = ft;
|
||||||
}
|
}
|
||||||
unlock:
|
unlock:
|
||||||
mutex_unlock(&root->chain_lock);
|
mutex_unlock(&root->chain_lock);
|
||||||
|
|
|
@ -138,6 +138,7 @@ struct fs_node {
|
||||||
|
|
||||||
struct mlx5_flow_rule {
|
struct mlx5_flow_rule {
|
||||||
struct fs_node node;
|
struct fs_node node;
|
||||||
|
struct mlx5_flow_table *ft;
|
||||||
struct mlx5_flow_destination dest_attr;
|
struct mlx5_flow_destination dest_attr;
|
||||||
/* next_ft should be accessed under chain_lock and only of
|
/* next_ft should be accessed under chain_lock and only of
|
||||||
* destination type is FWD_NEXT_fT.
|
* destination type is FWD_NEXT_fT.
|
||||||
|
@ -175,6 +176,7 @@ struct mlx5_flow_table {
|
||||||
u32 flags;
|
u32 flags;
|
||||||
struct rhltable fgs_hash;
|
struct rhltable fgs_hash;
|
||||||
enum mlx5_flow_table_miss_action def_miss_action;
|
enum mlx5_flow_table_miss_action def_miss_action;
|
||||||
|
struct mlx5_flow_namespace *ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_ft_underlay_qp {
|
struct mlx5_ft_underlay_qp {
|
||||||
|
|
|
@ -42,6 +42,7 @@ enum {
|
||||||
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO = 1 << 16,
|
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_PRIO = 1 << 16,
|
||||||
MLX5_FLOW_CONTEXT_ACTION_ENCRYPT = 1 << 17,
|
MLX5_FLOW_CONTEXT_ACTION_ENCRYPT = 1 << 17,
|
||||||
MLX5_FLOW_CONTEXT_ACTION_DECRYPT = 1 << 18,
|
MLX5_FLOW_CONTEXT_ACTION_DECRYPT = 1 << 18,
|
||||||
|
MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS = 1 << 19,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
Loading…
Reference in New Issue