mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 19:13:47 +02:00
net/mlx5e: CT: Update connection tracking steering entries
Previously, replacing a connection tracking steering entry was done by adding a new rule (with the same tag but possibly different mod hdr actions/labels) then removing the old rule. This approach doesn't work in hardware steering because two steering entries with the same tag cannot coexist in a hardware steering table. This commit prepares for that by adding a new ct_rule_update operation on the ct_fs_ops struct which is used instead of add+delete. Implementations for both dmfs (firmware steering) and smfs (software steering) are provided, which simply add the new rule and delete the old one. Signed-off-by: Cosmin Ratiu <cratiu@nvidia.com> Signed-off-by: Tariq Toukan <tariqt@nvidia.com> Link: https://patch.msgid.link/20240808055927.2059700-12-tariqt@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
486aeb2db5
commit
6b5662b759
|
|
@ -25,6 +25,8 @@ struct mlx5_ct_fs_ops {
|
|||
struct mlx5_flow_attr *attr,
|
||||
struct flow_rule *flow_rule);
|
||||
void (*ct_rule_del)(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule);
|
||||
int (*ct_rule_update)(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule,
|
||||
struct mlx5_flow_spec *spec, struct mlx5_flow_attr *attr);
|
||||
|
||||
size_t priv_size;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -65,9 +65,30 @@ mlx5_ct_fs_dmfs_ct_rule_del(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_ru
|
|||
kfree(dmfs_rule);
|
||||
}
|
||||
|
||||
static int mlx5_ct_fs_dmfs_ct_rule_update(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule,
|
||||
struct mlx5_flow_spec *spec, struct mlx5_flow_attr *attr)
|
||||
{
|
||||
struct mlx5_ct_fs_dmfs_rule *dmfs_rule = container_of(fs_rule,
|
||||
struct mlx5_ct_fs_dmfs_rule,
|
||||
fs_rule);
|
||||
struct mlx5e_priv *priv = netdev_priv(fs->netdev);
|
||||
struct mlx5_flow_handle *rule;
|
||||
|
||||
rule = mlx5_tc_rule_insert(priv, spec, attr);
|
||||
if (IS_ERR(rule))
|
||||
return PTR_ERR(rule);
|
||||
mlx5_tc_rule_delete(priv, dmfs_rule->rule, dmfs_rule->attr);
|
||||
|
||||
dmfs_rule->rule = rule;
|
||||
dmfs_rule->attr = attr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mlx5_ct_fs_ops dmfs_ops = {
|
||||
.ct_rule_add = mlx5_ct_fs_dmfs_ct_rule_add,
|
||||
.ct_rule_del = mlx5_ct_fs_dmfs_ct_rule_del,
|
||||
.ct_rule_update = mlx5_ct_fs_dmfs_ct_rule_update,
|
||||
|
||||
.init = mlx5_ct_fs_dmfs_init,
|
||||
.destroy = mlx5_ct_fs_dmfs_destroy,
|
||||
|
|
|
|||
|
|
@ -368,9 +368,35 @@ mlx5_ct_fs_smfs_ct_rule_del(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_ru
|
|||
kfree(smfs_rule);
|
||||
}
|
||||
|
||||
static int mlx5_ct_fs_smfs_ct_rule_update(struct mlx5_ct_fs *fs, struct mlx5_ct_fs_rule *fs_rule,
|
||||
struct mlx5_flow_spec *spec, struct mlx5_flow_attr *attr)
|
||||
{
|
||||
struct mlx5_ct_fs_smfs_rule *smfs_rule = container_of(fs_rule,
|
||||
struct mlx5_ct_fs_smfs_rule,
|
||||
fs_rule);
|
||||
struct mlx5_ct_fs_smfs *fs_smfs = mlx5_ct_fs_priv(fs);
|
||||
struct mlx5dr_action *actions[3]; /* We only need to create 3 actions, see below. */
|
||||
struct mlx5dr_rule *rule;
|
||||
|
||||
actions[0] = smfs_rule->count_action;
|
||||
actions[1] = attr->modify_hdr->action.dr_action;
|
||||
actions[2] = fs_smfs->fwd_action;
|
||||
|
||||
rule = mlx5_smfs_rule_create(smfs_rule->smfs_matcher->dr_matcher, spec,
|
||||
ARRAY_SIZE(actions), actions, spec->flow_context.flow_source);
|
||||
if (!rule)
|
||||
return -EINVAL;
|
||||
|
||||
mlx5_smfs_rule_destroy(smfs_rule->rule);
|
||||
smfs_rule->rule = rule;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mlx5_ct_fs_ops fs_smfs_ops = {
|
||||
.ct_rule_add = mlx5_ct_fs_smfs_ct_rule_add,
|
||||
.ct_rule_del = mlx5_ct_fs_smfs_ct_rule_del,
|
||||
.ct_rule_update = mlx5_ct_fs_smfs_ct_rule_update,
|
||||
|
||||
.init = mlx5_ct_fs_smfs_init,
|
||||
.destroy = mlx5_ct_fs_smfs_destroy,
|
||||
|
|
|
|||
|
|
@ -884,7 +884,6 @@ mlx5_tc_ct_entry_update_rule(struct mlx5_tc_ct_priv *ct_priv,
|
|||
struct mlx5_ct_zone_rule *zone_rule = &entry->zone_rules[nat];
|
||||
struct mlx5_flow_attr *attr = zone_rule->attr, *old_attr;
|
||||
struct mlx5e_mod_hdr_handle *mh;
|
||||
struct mlx5_ct_fs_rule *rule;
|
||||
struct mlx5_flow_spec *spec;
|
||||
int err;
|
||||
|
||||
|
|
@ -902,22 +901,19 @@ mlx5_tc_ct_entry_update_rule(struct mlx5_tc_ct_priv *ct_priv,
|
|||
err = mlx5_tc_ct_entry_create_mod_hdr(ct_priv, attr, flow_rule, &mh, zone_restore_id,
|
||||
nat, mlx5_tc_ct_entry_in_ct_nat_table(entry));
|
||||
if (err) {
|
||||
ct_dbg("Failed to create ct entry mod hdr");
|
||||
ct_dbg("Failed to create ct entry mod hdr, err: %d", err);
|
||||
goto err_mod_hdr;
|
||||
}
|
||||
|
||||
mlx5_tc_ct_set_tuple_match(ct_priv, spec, flow_rule);
|
||||
mlx5e_tc_match_to_reg_match(spec, ZONE_TO_REG, entry->tuple.zone, MLX5_CT_ZONE_MASK);
|
||||
|
||||
rule = ct_priv->fs_ops->ct_rule_add(ct_priv->fs, spec, attr, flow_rule);
|
||||
if (IS_ERR(rule)) {
|
||||
err = PTR_ERR(rule);
|
||||
ct_dbg("Failed to add replacement ct entry rule, nat: %d", nat);
|
||||
err = ct_priv->fs_ops->ct_rule_update(ct_priv->fs, zone_rule->rule, spec, attr);
|
||||
if (err) {
|
||||
ct_dbg("Failed to update ct entry rule, nat: %d, err: %d", nat, err);
|
||||
goto err_rule;
|
||||
}
|
||||
|
||||
ct_priv->fs_ops->ct_rule_del(ct_priv->fs, zone_rule->rule);
|
||||
zone_rule->rule = rule;
|
||||
mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, old_attr, zone_rule->mh);
|
||||
zone_rule->mh = mh;
|
||||
mlx5_put_label_mapping(ct_priv, old_attr->ct_attr.ct_labels_id);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user