Commit a2d9831d authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'mlx5-ipsec-fixes'

Leon Romanovsky says:

====================
mlx5 IPsec fixes

The following patches are combination of Jianbo's work on IPsec eswitch mode
together with our internal review toward addition of TCP protocol selectors
support to IPSec packet offload.

Despite not-being fix, the first patch helps us to make second one more
clear, so I'm asking to apply it anyway as part of this series.
====================

Link: https://lore.kernel.org/r/cover.1690803944.git.leonro@nvidia.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 0756384f 62da0833
......@@ -808,9 +808,9 @@ static void setup_fte_upper_proto_match(struct mlx5_flow_spec *spec, struct upsp
}
if (upspec->sport) {
MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_dport,
MLX5_SET(fte_match_set_lyr_2_4, spec->match_criteria, udp_sport,
upspec->sport_mask);
MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_dport, upspec->sport);
MLX5_SET(fte_match_set_lyr_2_4, spec->match_value, udp_sport, upspec->sport);
}
}
......
......@@ -889,7 +889,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
struct fs_node *iter = list_entry(start, struct fs_node, list);
struct mlx5_flow_table *ft = NULL;
if (!root || root->type == FS_TYPE_PRIO_CHAINS)
if (!root)
return NULL;
list_for_each_advance_continue(iter, &root->children, reverse) {
......@@ -905,20 +905,42 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
return ft;
}
/* If reverse is false then return the first flow table in next priority of
* prio in the tree, else return the last flow table in the previous priority
* of prio in the tree.
static struct fs_node *find_prio_chains_parent(struct fs_node *parent,
struct fs_node **child)
{
struct fs_node *node = NULL;
while (parent && parent->type != FS_TYPE_PRIO_CHAINS) {
node = parent;
parent = parent->parent;
}
if (child)
*child = node;
return parent;
}
/* If reverse is false then return the first flow table next to the passed node
* in the tree, else return the last flow table before the node in the tree.
* If skip is true, skip the flow tables in the same prio_chains prio.
*/
static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool reverse)
static struct mlx5_flow_table *find_closest_ft(struct fs_node *node, bool reverse,
bool skip)
{
struct fs_node *prio_chains_parent = NULL;
struct mlx5_flow_table *ft = NULL;
struct fs_node *curr_node;
struct fs_node *parent;
parent = prio->node.parent;
curr_node = &prio->node;
if (skip)
prio_chains_parent = find_prio_chains_parent(node, NULL);
parent = node->parent;
curr_node = node;
while (!ft && parent) {
ft = find_closest_ft_recursive(parent, &curr_node->list, reverse);
if (parent != prio_chains_parent)
ft = find_closest_ft_recursive(parent, &curr_node->list,
reverse);
curr_node = parent;
parent = curr_node->parent;
}
......@@ -926,15 +948,15 @@ static struct mlx5_flow_table *find_closest_ft(struct fs_prio *prio, bool revers
}
/* Assuming all the tree is locked by mutex chain lock */
static struct mlx5_flow_table *find_next_chained_ft(struct fs_prio *prio)
static struct mlx5_flow_table *find_next_chained_ft(struct fs_node *node)
{
return find_closest_ft(prio, false);
return find_closest_ft(node, false, true);
}
/* Assuming all the tree is locked by mutex chain lock */
static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio)
static struct mlx5_flow_table *find_prev_chained_ft(struct fs_node *node)
{
return find_closest_ft(prio, true);
return find_closest_ft(node, true, true);
}
static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
......@@ -946,7 +968,7 @@ static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent);
return find_next_chained_ft(prio);
return find_next_chained_ft(&prio->node);
}
static int connect_fts_in_prio(struct mlx5_core_dev *dev,
......@@ -970,21 +992,55 @@ static int connect_fts_in_prio(struct mlx5_core_dev *dev,
return 0;
}
static struct mlx5_flow_table *find_closet_ft_prio_chains(struct fs_node *node,
struct fs_node *parent,
struct fs_node **child,
bool reverse)
{
struct mlx5_flow_table *ft;
ft = find_closest_ft(node, reverse, false);
if (ft && parent == find_prio_chains_parent(&ft->node, child))
return ft;
return NULL;
}
/* Connect flow tables from previous priority of prio to ft */
static int connect_prev_fts(struct mlx5_core_dev *dev,
struct mlx5_flow_table *ft,
struct fs_prio *prio)
{
struct fs_node *prio_parent, *parent = NULL, *child, *node;
struct mlx5_flow_table *prev_ft;
int err = 0;
prio_parent = find_prio_chains_parent(&prio->node, &child);
/* return directly if not under the first sub ns of prio_chains prio */
if (prio_parent && !list_is_first(&child->list, &prio_parent->children))
return 0;
prev_ft = find_prev_chained_ft(prio);
if (prev_ft) {
prev_ft = find_prev_chained_ft(&prio->node);
while (prev_ft) {
struct fs_prio *prev_prio;
fs_get_obj(prev_prio, prev_ft->node.parent);
return connect_fts_in_prio(dev, prev_prio, ft);
err = connect_fts_in_prio(dev, prev_prio, ft);
if (err)
break;
if (!parent) {
parent = find_prio_chains_parent(&prev_prio->node, &child);
if (!parent)
break;
}
node = child;
prev_ft = find_closet_ft_prio_chains(node, parent, &child, true);
}
return 0;
return err;
}
static int update_root_ft_create(struct mlx5_flow_table *ft, struct fs_prio
......@@ -1123,7 +1179,7 @@ static int connect_flow_table(struct mlx5_core_dev *dev, struct mlx5_flow_table
if (err)
return err;
next_ft = first_ft ? first_ft : find_next_chained_ft(prio);
next_ft = first_ft ? first_ft : find_next_chained_ft(&prio->node);
err = connect_fwd_rules(dev, ft, next_ft);
if (err)
return err;
......@@ -1198,7 +1254,7 @@ static struct mlx5_flow_table *__mlx5_create_flow_table(struct mlx5_flow_namespa
tree_init_node(&ft->node, del_hw_flow_table, del_sw_flow_table);
next_ft = unmanaged ? ft_attr->next_ft :
find_next_chained_ft(fs_prio);
find_next_chained_ft(&fs_prio->node);
ft->def_miss_action = ns->def_miss_action;
ft->ns = ns;
err = root->cmds->create_flow_table(root, ft, ft_attr, next_ft);
......@@ -2195,13 +2251,20 @@ EXPORT_SYMBOL(mlx5_del_flow_rules);
/* Assuming prio->node.children(flow tables) is sorted by level */
static struct mlx5_flow_table *find_next_ft(struct mlx5_flow_table *ft)
{
struct fs_node *prio_parent, *child;
struct fs_prio *prio;
fs_get_obj(prio, ft->node.parent);
if (!list_is_last(&ft->node.list, &prio->node.children))
return list_next_entry(ft, node.list);
return find_next_chained_ft(prio);
prio_parent = find_prio_chains_parent(&prio->node, &child);
if (prio_parent && list_is_first(&child->list, &prio_parent->children))
return find_closest_ft(&prio->node, false, false);
return find_next_chained_ft(&prio->node);
}
static int update_root_ft_destroy(struct mlx5_flow_table *ft)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment