static int mlxsw_sp2_mr_tcam_route_create(struct mlxsw_sp *mlxsw_sp, void *priv, void *route_priv, struct mlxsw_sp_mr_route_key *key, struct mlxsw_afa_block *afa_block, enum mlxsw_sp_mr_route_prio prio) { struct mlxsw_sp2_mr_route *mr_route = route_priv; struct mlxsw_sp2_mr_tcam *mr_tcam = priv; struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_rule *rule; int err; mr_route->mr_tcam = mr_tcam; ruleset = mlxsw_sp2_mr_tcam_proto_ruleset(mr_tcam, key->proto); if (WARN_ON(!ruleset)) return -EINVAL; rule = mlxsw_sp_acl_rule_create(mlxsw_sp, ruleset, (unsigned long) route_priv, afa_block, NULL); if (IS_ERR(rule)) return PTR_ERR(rule); mlxsw_sp2_mr_tcam_rule_parse(rule, key, prio); err = mlxsw_sp_acl_rule_add(mlxsw_sp, rule); if (err) goto err_rule_add; return 0; err_rule_add: mlxsw_sp_acl_rule_destroy(mlxsw_sp, rule); return err; }
int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_block *block, struct tc_cls_flower_offload *f) { struct mlxsw_sp_acl_rule_info *rulei; struct mlxsw_sp_acl_ruleset *ruleset; struct mlxsw_sp_acl_rule *rule; int err; ruleset = mlxsw_sp_acl_ruleset_get(mlxsw_sp, block, f->common.chain_index, MLXSW_SP_ACL_PROFILE_FLOWER, NULL); if (IS_ERR(ruleset)) return PTR_ERR(ruleset); rule = mlxsw_sp_acl_rule_create(mlxsw_sp, ruleset, f->cookie, f->common.extack); if (IS_ERR(rule)) { err = PTR_ERR(rule); goto err_rule_create; } rulei = mlxsw_sp_acl_rule_rulei(rule); err = mlxsw_sp_flower_parse(mlxsw_sp, block, rulei, f); if (err) goto err_flower_parse; err = mlxsw_sp_acl_rulei_commit(rulei); if (err) goto err_rulei_commit; err = mlxsw_sp_acl_rule_add(mlxsw_sp, rule); if (err) goto err_rule_add; mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); return 0; err_rule_add: err_rulei_commit: err_flower_parse: mlxsw_sp_acl_rule_destroy(mlxsw_sp, rule); err_rule_create: mlxsw_sp_acl_ruleset_put(mlxsw_sp, ruleset); return err; }