net/sfc: implement flow insert/remove in MAE backend

Exercise action set allocation / release and action rule
insertion / removal in order to let flow API callers
actually get created flows functioning.

Signed-off-by: Ivan Malov <ivan.malov@oktetlabs.ru>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Reviewed-by: Andy Moreton <amoreton@xilinx.com>
This commit is contained in:
Ivan Malov 2020-10-20 10:13:04 +01:00 committed by Ferruh Yigit
parent b4fac34715
commit 041f22ec34
4 changed files with 125 additions and 2 deletions

View File

@ -50,8 +50,8 @@ static const struct sfc_flow_ops_by_spec sfc_flow_ops_mae = {
.parse = sfc_flow_parse_rte_to_mae,
.verify = sfc_mae_flow_verify,
.cleanup = sfc_mae_flow_cleanup,
.insert = NULL,
.remove = NULL,
.insert = sfc_mae_flow_insert,
.remove = sfc_mae_flow_remove,
};
static const struct sfc_flow_ops_by_spec *
@ -1202,6 +1202,7 @@ sfc_flow_parse_attr(struct sfc_adapter *sa,
spec_mae->priority = attr->priority;
spec_mae->match_spec = NULL;
spec_mae->action_set = NULL;
spec_mae->rule_id.id = EFX_MAE_RSRC_ID_INVALID;
}
return 0;

View File

@ -67,6 +67,8 @@ struct sfc_flow_spec_mae {
efx_mae_match_spec_t *match_spec;
/* Action set registry entry */
struct sfc_mae_action_set *action_set;
/* Firmware-allocated rule ID */
efx_mae_rule_id_t rule_id;
};
/* Flow specification */

View File

@ -113,6 +113,8 @@ sfc_mae_action_set_add(struct sfc_adapter *sa,
action_set->refcnt = 1;
action_set->spec = spec;
action_set->fw_rsrc.aset_id.id = EFX_MAE_RSRC_ID_INVALID;
TAILQ_INSERT_TAIL(&mae->action_sets, action_set, entries);
*action_setp = action_set;
@ -134,11 +136,62 @@ sfc_mae_action_set_del(struct sfc_adapter *sa,
if (action_set->refcnt != 0)
return;
SFC_ASSERT(action_set->fw_rsrc.aset_id.id == EFX_MAE_RSRC_ID_INVALID);
SFC_ASSERT(action_set->fw_rsrc.refcnt == 0);
efx_mae_action_set_spec_fini(sa->nic, action_set->spec);
TAILQ_REMOVE(&mae->action_sets, action_set, entries);
rte_free(action_set);
}
static int
sfc_mae_action_set_enable(struct sfc_adapter *sa,
struct sfc_mae_action_set *action_set)
{
struct sfc_mae_fw_rsrc *fw_rsrc = &action_set->fw_rsrc;
int rc;
SFC_ASSERT(sfc_adapter_is_locked(sa));
if (fw_rsrc->refcnt == 0) {
SFC_ASSERT(fw_rsrc->aset_id.id == EFX_MAE_RSRC_ID_INVALID);
SFC_ASSERT(action_set->spec != NULL);
rc = efx_mae_action_set_alloc(sa->nic, action_set->spec,
&fw_rsrc->aset_id);
if (rc != 0)
return rc;
}
++(fw_rsrc->refcnt);
return 0;
}
static int
sfc_mae_action_set_disable(struct sfc_adapter *sa,
struct sfc_mae_action_set *action_set)
{
struct sfc_mae_fw_rsrc *fw_rsrc = &action_set->fw_rsrc;
int rc;
SFC_ASSERT(sfc_adapter_is_locked(sa));
SFC_ASSERT(fw_rsrc->aset_id.id != EFX_MAE_RSRC_ID_INVALID);
SFC_ASSERT(fw_rsrc->refcnt != 0);
if (fw_rsrc->refcnt == 1) {
rc = efx_mae_action_set_free(sa->nic, &fw_rsrc->aset_id);
if (rc != 0)
return rc;
fw_rsrc->aset_id.id = EFX_MAE_RSRC_ID_INVALID;
}
--(fw_rsrc->refcnt);
return 0;
}
void
sfc_mae_flow_cleanup(struct sfc_adapter *sa,
struct rte_flow *flow)
@ -156,6 +209,8 @@ sfc_mae_flow_cleanup(struct sfc_adapter *sa,
spec_mae = &spec->mae;
SFC_ASSERT(spec_mae->rule_id.id == EFX_MAE_RSRC_ID_INVALID);
if (spec_mae->action_set != NULL)
sfc_mae_action_set_del(sa, spec_mae->action_set);
@ -563,3 +618,56 @@ sfc_mae_flow_verify(struct sfc_adapter *sa,
return sfc_mae_action_rule_class_verify(sa, spec_mae);
}
int
sfc_mae_flow_insert(struct sfc_adapter *sa,
struct rte_flow *flow)
{
struct sfc_flow_spec *spec = &flow->spec;
struct sfc_flow_spec_mae *spec_mae = &spec->mae;
struct sfc_mae_action_set *action_set = spec_mae->action_set;
struct sfc_mae_fw_rsrc *fw_rsrc = &action_set->fw_rsrc;
int rc;
SFC_ASSERT(spec_mae->rule_id.id == EFX_MAE_RSRC_ID_INVALID);
SFC_ASSERT(action_set != NULL);
rc = sfc_mae_action_set_enable(sa, action_set);
if (rc != 0)
goto fail_action_set_enable;
rc = efx_mae_action_rule_insert(sa->nic, spec_mae->match_spec,
NULL, &fw_rsrc->aset_id,
&spec_mae->rule_id);
if (rc != 0)
goto fail_action_rule_insert;
return 0;
fail_action_rule_insert:
(void)sfc_mae_action_set_disable(sa, action_set);
fail_action_set_enable:
return rc;
}
int
sfc_mae_flow_remove(struct sfc_adapter *sa,
struct rte_flow *flow)
{
struct sfc_flow_spec *spec = &flow->spec;
struct sfc_flow_spec_mae *spec_mae = &spec->mae;
struct sfc_mae_action_set *action_set = spec_mae->action_set;
int rc;
SFC_ASSERT(spec_mae->rule_id.id != EFX_MAE_RSRC_ID_INVALID);
SFC_ASSERT(action_set != NULL);
rc = efx_mae_action_rule_remove(sa->nic, &spec_mae->rule_id);
if (rc != 0)
return rc;
spec_mae->rule_id.id = EFX_MAE_RSRC_ID_INVALID;
return sfc_mae_action_set_disable(sa, action_set);
}

View File

@ -18,11 +18,21 @@
extern "C" {
#endif
/** FW-allocatable resource context */
struct sfc_mae_fw_rsrc {
unsigned int refcnt;
RTE_STD_C11
union {
efx_mae_aset_id_t aset_id;
};
};
/** Action set registry entry */
struct sfc_mae_action_set {
TAILQ_ENTRY(sfc_mae_action_set) entries;
unsigned int refcnt;
efx_mae_actions_t *spec;
struct sfc_mae_fw_rsrc fw_rsrc;
};
TAILQ_HEAD(sfc_mae_action_sets, sfc_mae_action_set);
@ -63,6 +73,8 @@ int sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
struct sfc_mae_action_set **action_setp,
struct rte_flow_error *error);
sfc_flow_verify_cb_t sfc_mae_flow_verify;
sfc_flow_insert_cb_t sfc_mae_flow_insert;
sfc_flow_remove_cb_t sfc_mae_flow_remove;
#ifdef __cplusplus
}