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; }
static void mlxsw_sp2_mr_tcam_rule_parse(struct mlxsw_sp_acl_rule *rule, struct mlxsw_sp_mr_route_key *key, unsigned int priority) { struct mlxsw_sp_acl_rule_info *rulei; rulei = mlxsw_sp_acl_rule_rulei(rule); rulei->priority = priority; mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_VIRT_ROUTER_0_7, key->vrid, GENMASK(7, 0)); mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_VIRT_ROUTER_8_10, key->vrid >> 8, GENMASK(2, 0)); switch (key->proto) { case MLXSW_SP_L3_PROTO_IPV4: return mlxsw_sp2_mr_tcam_rule_parse4(rulei, key); case MLXSW_SP_L3_PROTO_IPV6: return mlxsw_sp2_mr_tcam_rule_parse6(rulei, key); } }