mlxsw: Add support for mirror action with flower
Subsystems (3)
cover mlxsw: Add support for mirror action with flower
From: Jiri Pirko <[email protected]>
Arkadi says:
Add support for mirror action with flower classifier. The first 3 patches introduce a generic per-block resource infra. The last 4 patches add support for flow based span.
Arkadi Sharshevsky (4):
mlxsw: spectrum_acl: Add support for mirroring action
mlxsw: spectrum: Extend and export SPAN API
mlxsw: spectrum: Extend mlxsw_afa_ops for counter index and implement
for Spectrum
mlxsw: spectrum_acl: Add support for mirror action
Jiri Pirko (3):
mlxsw: spectrum: Extend mlxsw_afa_ops for counter index and implement
for Spectrum
mlxsw: core: Convert fwd_entry_ref list to be generic per-block
resource list
mlxsw: core: Make counter index allocated inside the action append
.../mellanox/mlxsw/core_acl_flex_actions.c | 255 +++++++++++++++++++-- .../mellanox/mlxsw/core_acl_flex_actions.h | 13 +- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 79 ++++--- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 15 +- drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 57 ++--- .../mellanox/mlxsw/spectrum_acl_flex_actions.c | 66 ++++++ .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 7 + .../net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c | 3 +- 8 files changed, 410 insertions(+), 85 deletions(-)
Signature · 1 line
2.14.3
PATCH 1/7 mlxsw: spectrum: Extend mlxsw_afa_ops for counter index and implement for Spectrum
From: Jiri Pirko <[email protected]>
Introduce extension of mlxsw_afa_ops in order to get/put counter indexes and implement the ops for Spectrum.
--- .../ethernet/mellanox/mlxsw/core_acl_flex_actions.h | 2 ++ .../mellanox/mlxsw/spectrum_acl_flex_actions.c | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h +2 -0
@@ -46,6 +46,8 @@ struct mlxsw_afa_ops {void (*kvdl_set_del)(void *priv,u32 kvdl_index,bool is_first);int (*kvdl_fwd_entry_add)(void *priv,u32 *p_kvdl_index,u8 local_port);void (*kvdl_fwd_entry_del)(void *priv,u32 kvdl_index); +int (*counter_index_get)(void *priv,unsigned int *p_counter_index); +void (*counter_index_put)(void *priv,unsigned int counter_index); }; struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set,
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c +18 -0
@@ -108,11 +108,29 @@ static void mlxsw_sp_act_kvdl_fwd_entry_del(void *priv, u32 kvdl_index)mlxsw_sp_kvdl_free (mlxsw_sp, kvdl_index); } +static int +mlxsw_sp_act_counter_index_get (void *priv,unsigned int *p_counter_index) +{ +struct mlxsw_sp *mlxsw_sp = priv; + +return mlxsw_sp_flow_counter_alloc (mlxsw_sp, p_counter_index); +} + +static void +mlxsw_sp_act_counter_index_put (void *priv,unsigned int counter_index) +{ +struct mlxsw_sp *mlxsw_sp = priv; + +mlxsw_sp_flow_counter_free (mlxsw_sp, counter_index); +} +static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = { .kvdl_set_add = mlxsw_sp_act_kvdl_set_add, .kvdl_set_del = mlxsw_sp_act_kvdl_set_del, .kvdl_fwd_entry_add = mlxsw_sp_act_kvdl_fwd_entry_add, .kvdl_fwd_entry_del = mlxsw_sp_act_kvdl_fwd_entry_del, + .counter_index_get = mlxsw_sp_act_counter_index_get, + .counter_index_put = mlxsw_sp_act_counter_index_put, };int mlxsw_sp_afa_init (struct mlxsw_sp *mlxsw_sp)
Signature · 1 line
2.14.3
PATCH 2/7 mlxsw: core: Convert fwd_entry_ref list to be generic per-block resource list
In reply to Jiri PirkoFrom: Jiri Pirko <[email protected]>
Since the resource list needs to be used also for other entries different to fwd_entry_ref, make the list generic. For that purpose, introduce a resource structure with couple of helpers that the code which need to store a per-block resource should use.
--- .../mellanox/mlxsw/core_acl_flex_actions.c | 75 ++++++++++++++-------- 1 file changed, 49 insertions(+), 26 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +49 -26
@@ -310,9 +310,33 @@ struct mlxsw_afa_block {struct mlxsw_afa_set *first_set;struct mlxsw_afa_set *cur_set;unsigned int cur_act_index;/* In current set. */ -struct list_head fwd_entry_ref_list; +struct list_head resource_list;/* List of resources held by actions +* in this block. +*/ }; +struct mlxsw_afa_resource { +struct list_head list; +void (*destructor)(struct mlxsw_afa_block *block, +struct mlxsw_afa_resource *resource); +}; + +static void mlxsw_afa_resource_add (struct mlxsw_afa_block *block, +struct mlxsw_afa_resource *resource) +{ +list_add (&resource->list, &block->resource_list); +} + +static void mlxsw_afa_resources_destroy (struct mlxsw_afa_block *block) +{ +struct mlxsw_afa_resource *resource, *tmp; + +list_for_each_entry_safe (resource, tmp, &block->resource_list, list) { +list_del (&resource->list); + resource->destructor (block, resource); + } +} +struct mlxsw_afa_block *mlxsw_afa_block_create (struct mlxsw_afa *mlxsw_afa) {struct mlxsw_afa_block *block;
@@ -320,7 +344,7 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa) block =kzalloc (sizeof (*block),GFP_KERNEL );if (!block)return NULL ; -INIT_LIST_HEAD (&block->fwd_entry_ref_list); +INIT_LIST_HEAD (&block->resource_list); block->afa = mlxsw_afa;/* At least one action set is always present, so just create it here */
@@ -336,8 +360,6 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa) }EXPORT_SYMBOL (mlxsw_afa_block_create); -static void mlxsw_afa_fwd_entry_refs_destroy (struct mlxsw_afa_block *block); -void mlxsw_afa_block_destroy (struct mlxsw_afa_block *block) {struct mlxsw_afa_set *set = block->first_set;
@@ -348,7 +370,7 @@ void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block)mlxsw_afa_set_put (block->afa, set); set = next_set; }while (set); -mlxsw_afa_fwd_entry_refs_destroy (block); +mlxsw_afa_resources_destroy (block);kfree (block); }EXPORT_SYMBOL (mlxsw_afa_block_destroy);
@@ -489,10 +511,29 @@ static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa, }struct mlxsw_afa_fwd_entry_ref { -struct list_head list; +struct mlxsw_afa_resource resource;struct mlxsw_afa_fwd_entry *fwd_entry; }; +static void +mlxsw_afa_fwd_entry_ref_destroy (struct mlxsw_afa_block *block, +struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref) +{ +mlxsw_afa_fwd_entry_put (block->afa, fwd_entry_ref->fwd_entry); +kfree (fwd_entry_ref); +} + +static void +mlxsw_afa_fwd_entry_ref_destructor (struct mlxsw_afa_block *block, +struct mlxsw_afa_resource *resource) +{ +struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref; + + fwd_entry_ref = container_of(resource, struct mlxsw_afa_fwd_entry_ref, + resource); +mlxsw_afa_fwd_entry_ref_destroy (block, fwd_entry_ref); +} +static struct mlxsw_afa_fwd_entry_ref *mlxsw_afa_fwd_entry_ref_create (struct mlxsw_afa_block *block,u8 local_port) {
@@ -509,7 +550,8 @@ mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port) goto err_fwd_entry_get; } fwd_entry_ref->fwd_entry = fwd_entry; -list_add (&fwd_entry_ref->list, &block->fwd_entry_ref_list); + fwd_entry_ref->resource.destructor = mlxsw_afa_fwd_entry_ref_destructor; +mlxsw_afa_resource_add (block, &fwd_entry_ref->resource);return fwd_entry_ref; err_fwd_entry_get:
@@ -517,25 +559,6 @@ mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port)return ERR_PTR (err); } -static void -mlxsw_afa_fwd_entry_ref_destroy (struct mlxsw_afa_block *block, -struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref) -{ -list_del (&fwd_entry_ref->list); -mlxsw_afa_fwd_entry_put (block->afa, fwd_entry_ref->fwd_entry); -kfree (fwd_entry_ref); -} - -static void mlxsw_afa_fwd_entry_refs_destroy (struct mlxsw_afa_block *block) -{ -struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref; -struct mlxsw_afa_fwd_entry_ref *tmp; - -list_for_each_entry_safe (fwd_entry_ref, tmp, - &block->fwd_entry_ref_list, list) -mlxsw_afa_fwd_entry_ref_destroy (block, fwd_entry_ref); -} -#define MLXSW_AFA_ONE_ACTION_LEN 32#define MLXSW_AFA_PAYLOAD_OFFSET 4
Signature · 1 line
2.14.3
PATCH 3/7 mlxsw: core: Make counter index allocated inside the action append
In reply to Jiri PirkoFrom: Jiri Pirko <[email protected]>
So far, the caller of mlxsw_afa_block_append_counter needed to allocate counter index by hand. Benefit from the previously introduced resource infra and counter_index_get/put callbacks, and allocate the counter index in place where it is needed, inside the action append function.
--- .../mellanox/mlxsw/core_acl_flex_actions.c | 80 ++++++++++++++++++++-- .../mellanox/mlxsw/core_acl_flex_actions.h | 4 +- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 1 - drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 29 +------- .../net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c | 3 +- 5 files changed, 82 insertions(+), 35 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +76 -4
@@ -559,6 +559,53 @@ mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port)return ERR_PTR (err); } +struct mlxsw_afa_counter { +struct mlxsw_afa_resource resource; +u32 counter_index; +}; + +static void +mlxsw_afa_counter_destroy (struct mlxsw_afa_block *block, +struct mlxsw_afa_counter *counter) +{ + block->afa->ops->counter_index_put (block->afa->ops_priv, + counter->counter_index); +kfree (counter); +} + +static void +mlxsw_afa_counter_destructor (struct mlxsw_afa_block *block, +struct mlxsw_afa_resource *resource) +{ +struct mlxsw_afa_counter *counter; + + counter = container_of(resource, struct mlxsw_afa_counter, resource); +mlxsw_afa_counter_destroy (block, counter); +} + +static struct mlxsw_afa_counter * +mlxsw_afa_counter_create (struct mlxsw_afa_block *block) +{ +struct mlxsw_afa_counter *counter; +int err; + + counter =kzalloc (sizeof (*counter),GFP_KERNEL ); +if (!counter) +return ERR_PTR (-ENOMEM ); + + err = block->afa->ops->counter_index_get (block->afa->ops_priv, + &counter->counter_index); +if (err) + goto err_counter_index_get; + counter->resource.destructor = mlxsw_afa_counter_destructor; +mlxsw_afa_resource_add (block, &counter->resource); +return counter; + +err_counter_index_get: +kfree (counter); +return ERR_PTR (err); +} +#define MLXSW_AFA_ONE_ACTION_LEN 32#define MLXSW_AFA_PAYLOAD_OFFSET 4
@@ -876,11 +923,10 @@ mlxsw_afa_polcnt_pack(char *payload,mlxsw_afa_polcnt_counter_index_set (payload, counter_index); } -int mlxsw_afa_block_append_counter (struct mlxsw_afa_block *block, -u32 counter_index) +int mlxsw_afa_block_append_allocated_counter (struct mlxsw_afa_block *block, +u32 counter_index) { -char *act =mlxsw_afa_block_append_action (block, -MLXSW_AFA_POLCNT_CODE , +char *act =mlxsw_afa_block_append_action (block,MLXSW_AFA_POLCNT_CODE ,MLXSW_AFA_POLCNT_SIZE );if (!act)return -ENOBUFS ;
@@ -888,6 +934,32 @@ int mlxsw_afa_block_append_counter(struct mlxsw_afa_block *block, counter_index);return 0 ; } +EXPORT_SYMBOL (mlxsw_afa_block_append_allocated_counter); + +int mlxsw_afa_block_append_counter (struct mlxsw_afa_block *block, +u32 *p_counter_index) +{ +struct mlxsw_afa_counter *counter; +u32 counter_index; +int err; + + counter =mlxsw_afa_counter_create (block); +if (IS_ERR (counter)) +return PTR_ERR (counter); + counter_index = counter->counter_index; + + err =mlxsw_afa_block_append_allocated_counter (block, counter_index); +if (err) + goto err_append_allocated_counter; + +if (p_counter_index) + *p_counter_index = counter_index; +return 0 ; + +err_append_allocated_counter: +mlxsw_afa_counter_destroy (block, counter); +return err; +}EXPORT_SYMBOL (mlxsw_afa_block_append_counter);/* Virtual Router and Forwarding Domain Action
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h +3 -1
@@ -69,8 +69,10 @@ int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block, u8 local_port, bool in_port);int mlxsw_afa_block_append_vlan_modify (struct mlxsw_afa_block *block,u16 vid,u8 pcp,u8 et); +int mlxsw_afa_block_append_allocated_counter (struct mlxsw_afa_block *block, +u32 counter_index);int mlxsw_afa_block_append_counter (struct mlxsw_afa_block *block, -u32 counter_index); +u32 *p_counter_index);int mlxsw_afa_block_append_fid_set (struct mlxsw_afa_block *block,u16 fid); int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block, u16 expected_irif, u16 min_mtu,
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +0 -1
@@ -457,7 +457,6 @@ struct mlxsw_sp_acl_rule_info {struct mlxsw_afk_element_values values;struct mlxsw_afa_block *act_block;unsigned int counter_index; -bool counter_valid; };enum mlxsw_sp_acl_profile {
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +1 -28
@@ -462,27 +462,6 @@ u16 mlxsw_sp_acl_ruleset_group_id(struct mlxsw_sp_acl_ruleset *ruleset)return ops->ruleset_group_id (ruleset->priv); } -static int -mlxsw_sp_acl_rulei_counter_alloc (struct mlxsw_sp *mlxsw_sp, -struct mlxsw_sp_acl_rule_info *rulei) -{ -int err; - - err =mlxsw_sp_flow_counter_alloc (mlxsw_sp, &rulei->counter_index); -if (err) -return err; - rulei->counter_valid = true; -return 0 ; -} - -static void -mlxsw_sp_acl_rulei_counter_free (struct mlxsw_sp *mlxsw_sp, -struct mlxsw_sp_acl_rule_info *rulei) -{ - rulei->counter_valid = false; -mlxsw_sp_flow_counter_free (mlxsw_sp, rulei->counter_index); -} -struct mlxsw_sp_acl_rule_info *mlxsw_sp_acl_rulei_create (struct mlxsw_sp_acl *acl) {
@@ -619,7 +598,7 @@ int mlxsw_sp_acl_rulei_act_count(struct mlxsw_sp *mlxsw_sp, struct mlxsw_sp_acl_rule_info *rulei) {return mlxsw_afa_block_append_counter (rulei->act_block, - rulei->counter_index); + &rulei->counter_index); } int mlxsw_sp_acl_rulei_act_fid_set(struct mlxsw_sp *mlxsw_sp,
@@ -653,13 +632,8 @@ mlxsw_sp_acl_rule_create(struct mlxsw_sp *mlxsw_sp, goto err_rulei_create; } - err =mlxsw_sp_acl_rulei_counter_alloc (mlxsw_sp, rule->rulei); -if (err) - goto err_counter_alloc;return rule; -err_counter_alloc: -mlxsw_sp_acl_rulei_destroy (rule->rulei); err_rulei_create:kfree (rule); err_alloc:
@@ -672,7 +646,6 @@ void mlxsw_sp_acl_rule_destroy(struct mlxsw_sp *mlxsw_sp, {struct mlxsw_sp_acl_ruleset *ruleset = rule->ruleset; -mlxsw_sp_acl_rulei_counter_free (mlxsw_sp, rule->rulei);mlxsw_sp_acl_rulei_destroy (rule->rulei);kfree (rule);mlxsw_sp_acl_ruleset_ref_dec (mlxsw_sp, ruleset);
drivers/net/ethernet/mellanox/mlxsw/spectrum_mr_tcam.c +2 -1
@@ -243,7 +243,8 @@ mlxsw_sp_mr_tcam_afa_block_create(struct mlxsw_sp *mlxsw_sp,if (!afa_block)return ERR_PTR (-ENOMEM ); - err =mlxsw_afa_block_append_counter (afa_block, counter_index); + err =mlxsw_afa_block_append_allocated_counter (afa_block, + counter_index);if (err) goto err;
Signature · 1 line
2.14.3
PATCH 4/7 mlxsw: spectrum_acl: Add support for mirroring action
In reply to Jiri PirkoFrom: Arkadi Sharshevsky <[email protected]>
The patch extends the trap action for mirroring.
--- .../mellanox/mlxsw/core_acl_flex_actions.c | 33 ++++++++++++++++++++++ .../mellanox/mlxsw/core_acl_flex_actions.h | 2 ++ 2 files changed, 35 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +33 -0
@@ -760,6 +760,16 @@ MLXSW_ITEM32(afa, trapdisc, forward_action, 0x00, 0, 4);*/ MLXSW_ITEM32 (afa, trapdisc, trap_id,0x04 ,0 ,9 ); +/* afa_trapdisc_mirror_agent +* Mirror agent. +*/ +MLXSW_ITEM32 (afa, trapdisc, mirror_agent,0x08 ,29 ,3 ); + +/* afa_trapdisc_mirror_enable +* Mirror enable. +*/ +MLXSW_ITEM32 (afa, trapdisc, mirror_enable,0x08 ,24 ,1 ); + static inline void mlxsw_afa_trapdisc_pack(char *payload, enum mlxsw_afa_trapdisc_trap_action trap_action,
@@ -771,6 +781,14 @@ mlxsw_afa_trapdisc_pack(char *payload,mlxsw_afa_trapdisc_trap_id_set (payload, trap_id); } +static inline void +mlxsw_afa_trapdisc_mirror_pack (char *payload,bool mirror_enable, +u8 mirror_agent) +{ +mlxsw_afa_trapdisc_mirror_enable_set (payload, mirror_enable); +mlxsw_afa_trapdisc_mirror_agent_set (payload, mirror_agent); +} +int mlxsw_afa_block_append_drop (struct mlxsw_afa_block *block) { char *act = mlxsw_afa_block_append_action(block,
@@ -816,6 +834,21 @@ int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block, }EXPORT_SYMBOL (mlxsw_afa_block_append_trap_and_forward); +int mlxsw_afa_block_append_mirror (struct mlxsw_afa_block *block, +u8 mirror_agent) +{ +char *act =mlxsw_afa_block_append_action (block, +MLXSW_AFA_TRAPDISC_CODE , +MLXSW_AFA_TRAPDISC_SIZE ); +if (!act) +return -ENOBUFS ; +mlxsw_afa_trapdisc_pack (act,MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP , +MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD ,0 ); +mlxsw_afa_trapdisc_mirror_pack (act, true, mirror_agent); +return 0 ; +} +EXPORT_SYMBOL (mlxsw_afa_block_append_mirror); +/* Forwarding Action * ----------------- * Forwarding Action can be used to implement Policy Based Switching (PBS)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h +2 -0
@@ -65,6 +65,8 @@ int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block);int mlxsw_afa_block_append_trap (struct mlxsw_afa_block *block,u16 trap_id);int mlxsw_afa_block_append_trap_and_forward (struct mlxsw_afa_block *block,u16 trap_id); +int mlxsw_afa_block_append_mirror (struct mlxsw_afa_block *block, +u8 mirror_agent);int mlxsw_afa_block_append_fwd (struct mlxsw_afa_block *block,u8 local_port,bool in_port); int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block,
Signature · 1 line
2.14.3
PATCH 5/7 mlxsw: spectrum: Extend and export SPAN API
In reply to Jiri PirkoFrom: Arkadi Sharshevsky <[email protected]>
Extend SPAN API for ACL case. In case of ACL triggering the MPAR register shouldn't be configured. This patch also export those helpers for ACL usage.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 79 +++++++++++++++----------- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 10 ++++ 2 files changed, 57 insertions(+), 32 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +47 -32
@@ -568,7 +568,7 @@ static void mlxsw_sp_span_entry_destroy(struct mlxsw_sp *mlxsw_sp, span_entry->used = false; } -static struct mlxsw_sp_span_entry * +struct mlxsw_sp_span_entry *mlxsw_sp_span_entry_find (struct mlxsw_sp *mlxsw_sp,u8 local_port) {int i;
@@ -669,13 +669,28 @@ mlxsw_sp_span_entry_bound_port_find(struct mlxsw_sp_port *port,static int mlxsw_sp_span_inspected_port_bind (struct mlxsw_sp_port *port,struct mlxsw_sp_span_entry *span_entry, -enum mlxsw_sp_span_type type) +enum mlxsw_sp_span_type type, +bool bind) { -struct mlxsw_sp_span_inspected_port *inspected_port;struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp;char mpar_pl[MLXSW_REG_MPAR_LEN ]; -char sbib_pl[MLXSW_REG_SBIB_LEN ];int pa_id = span_entry->id; + +/* bind the port to the SPAN entry */ +mlxsw_reg_mpar_pack (mpar_pl, port->local_port, + (enum mlxsw_reg_mpar_i_e ) type, bind, pa_id); +return mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (mpar), mpar_pl); +} + +static int +mlxsw_sp_span_inspected_port_add (struct mlxsw_sp_port *port, +struct mlxsw_sp_span_entry *span_entry, +enum mlxsw_sp_span_type type, +bool bind) +{ +struct mlxsw_sp_span_inspected_port *inspected_port; +struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; +char sbib_pl[MLXSW_REG_SBIB_LEN ];int err;/* if it is an egress SPAN, bind a shared buffer to it */
@@ -691,12 +706,12 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port, } } -/* bind the port to the SPAN entry */ -mlxsw_reg_mpar_pack (mpar_pl, port->local_port, - (enum mlxsw_reg_mpar_i_e ) type, true, pa_id); - err =mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (mpar), mpar_pl); -if (err) - goto err_mpar_reg_write; +if (bind) { + err =mlxsw_sp_span_inspected_port_bind (port, span_entry, type, + true); +if (err) + goto err_port_bind; + } inspected_port =kzalloc (sizeof (*inspected_port),GFP_KERNEL );if (!inspected_port) {
@@ -709,8 +724,11 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port,return 0 ; -err_mpar_reg_write: err_inspected_port_alloc: +if (bind) +mlxsw_sp_span_inspected_port_bind (port, span_entry, type, + false); +err_port_bind:if (type ==MLXSW_SP_SPAN_EGRESS ) {mlxsw_reg_sbib_pack (sbib_pl, port->local_port,0 );mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (sbib), sbib_pl);
@@ -719,25 +737,22 @@ mlxsw_sp_span_inspected_port_bind(struct mlxsw_sp_port *port, }static void -mlxsw_sp_span_inspected_port_unbind (struct mlxsw_sp_port *port, -struct mlxsw_sp_span_entry *span_entry, -enum mlxsw_sp_span_type type) +mlxsw_sp_span_inspected_port_del (struct mlxsw_sp_port *port, +struct mlxsw_sp_span_entry *span_entry, +enum mlxsw_sp_span_type type, +bool bind) {struct mlxsw_sp_span_inspected_port *inspected_port;struct mlxsw_sp *mlxsw_sp = port->mlxsw_sp; -char mpar_pl[MLXSW_REG_MPAR_LEN ];char sbib_pl[MLXSW_REG_SBIB_LEN ]; -int pa_id = span_entry->id; inspected_port =mlxsw_sp_span_entry_bound_port_find (port, span_entry);if (!inspected_port)return ; -/* remove the inspected port */ -mlxsw_reg_mpar_pack (mpar_pl, port->local_port, - (enum mlxsw_reg_mpar_i_e ) type, false, pa_id); -mlxsw_reg_write (mlxsw_sp->core,MLXSW_REG (mpar), mpar_pl); - +if (bind) +mlxsw_sp_span_inspected_port_bind (port, span_entry, type, + false);/* remove the SBIB buffer if it was egress SPAN */ if (type ==MLXSW_SP_SPAN_EGRESS ) {mlxsw_reg_sbib_pack (sbib_pl, port->local_port,0 );
@@ -750,9 +765,9 @@ mlxsw_sp_span_inspected_port_unbind(struct mlxsw_sp_port *port,kfree (inspected_port); } -static int mlxsw_sp_span_mirror_add (struct mlxsw_sp_port *from, -struct mlxsw_sp_port *to, -enum mlxsw_sp_span_type type) +int mlxsw_sp_span_mirror_add (struct mlxsw_sp_port *from, +struct mlxsw_sp_port *to, +enum mlxsw_sp_span_type type,bool bind) {struct mlxsw_sp *mlxsw_sp = from->mlxsw_sp;struct mlxsw_sp_span_entry *span_entry;
@@ -765,7 +780,7 @@ static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,netdev_dbg (from->dev,"Adding inspected port to SPAN entry %d\n" , span_entry->id); - err =mlxsw_sp_span_inspected_port_bind (from, span_entry, type); + err =mlxsw_sp_span_inspected_port_add (from, span_entry, type, bind);if (err) goto err_port_bind;
@@ -776,9 +791,8 @@ static int mlxsw_sp_span_mirror_add(struct mlxsw_sp_port *from,return err; } -static void mlxsw_sp_span_mirror_remove (struct mlxsw_sp_port *from, -u8 destination_port, -enum mlxsw_sp_span_type type) +void mlxsw_sp_span_mirror_del (struct mlxsw_sp_port *from,u8 destination_port, +enum mlxsw_sp_span_type type,bool bind) {struct mlxsw_sp_span_entry *span_entry;
@@ -791,7 +805,7 @@ static void mlxsw_sp_span_mirror_remove(struct mlxsw_sp_port *from,netdev_dbg (from->dev,"removing inspected port from SPAN entry %d\n" , span_entry->id); -mlxsw_sp_span_inspected_port_unbind (from, span_entry, type); +mlxsw_sp_span_inspected_port_del (from, span_entry, type, bind); } static int mlxsw_sp_port_sample_set(struct mlxsw_sp_port *mlxsw_sp_port,
@@ -1582,7 +1596,8 @@ mlxsw_sp_port_add_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, mirror->to_local_port = to_port->local_port; mirror->ingress = ingress; span_type = ingress ?MLXSW_SP_SPAN_INGRESS :MLXSW_SP_SPAN_EGRESS ; -return mlxsw_sp_span_mirror_add (mlxsw_sp_port, to_port, span_type); +return mlxsw_sp_span_mirror_add (mlxsw_sp_port, to_port, span_type, + true); } static void
@@ -1593,8 +1608,8 @@ mlxsw_sp_port_del_cls_matchall_mirror(struct mlxsw_sp_port *mlxsw_sp_port, span_type = mirror->ingress ?MLXSW_SP_SPAN_INGRESS :MLXSW_SP_SPAN_EGRESS ; -mlxsw_sp_span_mirror_remove (mlxsw_sp_port, mirror->to_local_port, - span_type); +mlxsw_sp_span_mirror_del (mlxsw_sp_port, mirror->to_local_port, + span_type, true); } static int
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +10 -0
@@ -396,6 +396,16 @@ struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find(struct net_device *dev);struct mlxsw_sp_port *mlxsw_sp_port_lower_dev_hold (struct net_device *dev);void mlxsw_sp_port_dev_put (struct mlxsw_sp_port *mlxsw_sp_port);struct mlxsw_sp_port *mlxsw_sp_port_dev_lower_find_rcu (struct net_device *dev); +int mlxsw_sp_span_mirror_add (struct mlxsw_sp_port *from, +struct mlxsw_sp_port *to, +enum mlxsw_sp_span_type type, +bool bind); +void mlxsw_sp_span_mirror_del (struct mlxsw_sp_port *from, +u8 destination_port, +enum mlxsw_sp_span_type type, +bool bind); +struct mlxsw_sp_span_entry * +mlxsw_sp_span_entry_find (struct mlxsw_sp *mlxsw_sp,u8 local_port);/* spectrum_dcb.c */ #ifdef CONFIG_MLXSW_SPECTRUM_DCB
Signature · 1 line
2.14.3
PATCH 6/7 mlxsw: spectrum: Extend mlxsw_afa_ops for counter index and implement for Spectrum
In reply to Jiri PirkoFrom: Arkadi Sharshevsky <[email protected]>
Introduce extension of mlxsw_afa_ops in order to add/del mirroring and implement the ops for Spectrum.
--- .../mellanox/mlxsw/core_acl_flex_actions.h | 4 ++ .../mellanox/mlxsw/spectrum_acl_flex_actions.c | 48 ++++++++++++++++++++++ 2 files changed, 52 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h +4 -0
@@ -48,6 +48,10 @@ struct mlxsw_afa_ops {void (*kvdl_fwd_entry_del)(void *priv,u32 kvdl_index);int (*counter_index_get)(void *priv,unsigned int *p_counter_index);void (*counter_index_put)(void *priv,unsigned int counter_index); +int (*mirror_add)(void *priv,u8 locol_in_port,u8 local_out_port, +bool ingress,int *p_span_id); +void (*mirror_del)(void *priv,u8 locol_in_port,u8 local_out_port, +bool ingress); }; struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set,
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_actions.c +48 -0
60 lines not on this page · raw message
Signature · 1 line
2.14.3
PATCH 7/7 mlxsw: spectrum_acl: Add support for mirror action
In reply to Jiri PirkoFrom: Arkadi Sharshevsky <[email protected]>
Add support for mirror action. Only one mirror action can be set per rule.
--- .../mellanox/mlxsw/core_acl_flex_actions.c | 87 +++++++++++++++++++++- .../mellanox/mlxsw/core_acl_flex_actions.h | 3 +- drivers/net/ethernet/mellanox/mlxsw/spectrum.h | 4 + drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c | 28 +++++++ .../net/ethernet/mellanox/mlxsw/spectrum_flower.c | 7 ++ 5 files changed, 126 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c +85 -2
@@ -834,8 +834,68 @@ int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block, }EXPORT_SYMBOL (mlxsw_afa_block_append_trap_and_forward); -int mlxsw_afa_block_append_mirror (struct mlxsw_afa_block *block, -u8 mirror_agent) +struct mlxsw_afa_mirror { +struct mlxsw_afa_resource resource; +int span_id; +u8 local_in_port; +u8 local_out_port; +bool ingress; +}; + +static void +mlxsw_afa_mirror_destroy (struct mlxsw_afa_block *block, +struct mlxsw_afa_mirror *mirror) +{ + block->afa->ops->mirror_del (block->afa->ops_priv, + mirror->local_in_port, + mirror->local_out_port, + mirror->ingress); +kfree (mirror); +} + +static void +mlxsw_afa_mirror_destructor (struct mlxsw_afa_block *block, +struct mlxsw_afa_resource *resource) +{ +struct mlxsw_afa_mirror *mirror; + + mirror = container_of(resource, struct mlxsw_afa_mirror, resource); +mlxsw_afa_mirror_destroy (block, mirror); +} + +static struct mlxsw_afa_mirror * +mlxsw_afa_mirror_create (struct mlxsw_afa_block *block, +u8 local_in_port,u8 local_out_port, +bool ingress) +{ +struct mlxsw_afa_mirror *mirror; +int err; + + mirror =kzalloc (sizeof (*mirror),GFP_KERNEL ); +if (!mirror) +return ERR_PTR (-ENOMEM ); + + err = block->afa->ops->mirror_add (block->afa->ops_priv, + local_in_port, local_out_port, + ingress, &mirror->span_id); +if (err) + goto err_mirror_add; + + mirror->ingress = ingress; + mirror->local_out_port = local_out_port; + mirror->local_in_port = local_in_port; + mirror->resource.destructor = mlxsw_afa_mirror_destructor; +mlxsw_afa_resource_add (block, &mirror->resource); +return mirror; + +err_mirror_add: +kfree (mirror); +return ERR_PTR (err); +} + +static int +mlxsw_afa_block_append_allocated_mirror (struct mlxsw_afa_block *block, +u8 mirror_agent) { char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_TRAPDISC_CODE,
@@ -847,6 +907,29 @@ int mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,mlxsw_afa_trapdisc_mirror_pack (act, true, mirror_agent);return 0 ; } + +int +mlxsw_afa_block_append_mirror (struct mlxsw_afa_block *block, +u8 local_in_port,u8 local_out_port,bool ingress) +{ +struct mlxsw_afa_mirror *mirror; +int err; + + mirror =mlxsw_afa_mirror_create (block, local_in_port, local_out_port, + ingress); +if (IS_ERR (mirror)) +return PTR_ERR (mirror); + + err =mlxsw_afa_block_append_allocated_mirror (block, mirror->span_id); +if (err) + goto err_append_allocated_mirror; + +return 0 ; + +err_append_allocated_mirror: +mlxsw_afa_mirror_destroy (block, mirror); +return err; +}EXPORT_SYMBOL (mlxsw_afa_block_append_mirror);/* Forwarding Action
drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h +2 -1
@@ -70,7 +70,8 @@ int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);int mlxsw_afa_block_append_trap_and_forward (struct mlxsw_afa_block *block,u16 trap_id);int mlxsw_afa_block_append_mirror (struct mlxsw_afa_block *block, -u8 mirror_agent); +u8 local_in_port,u8 local_out_port, +bool ingress);int mlxsw_afa_block_append_fwd (struct mlxsw_afa_block *block,u8 local_port,bool in_port); int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block,
drivers/net/ethernet/mellanox/mlxsw/spectrum.h +4 -0
@@ -554,6 +554,10 @@ int mlxsw_sp_acl_rulei_act_jump(struct mlxsw_sp_acl_rule_info *rulei, u16 group_id);int mlxsw_sp_acl_rulei_act_drop (struct mlxsw_sp_acl_rule_info *rulei);int mlxsw_sp_acl_rulei_act_trap (struct mlxsw_sp_acl_rule_info *rulei); +int mlxsw_sp_acl_rulei_act_mirror (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_acl_rule_info *rulei, +struct mlxsw_sp_acl_block *block, +struct net_device *out_dev);int mlxsw_sp_acl_rulei_act_fwd (struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_acl_rule_info *rulei,struct net_device *out_dev);
drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c +28 -0
@@ -566,6 +566,34 @@ int mlxsw_sp_acl_rulei_act_fwd(struct mlxsw_sp *mlxsw_sp, local_port, in_port); } +int mlxsw_sp_acl_rulei_act_mirror (struct mlxsw_sp *mlxsw_sp, +struct mlxsw_sp_acl_rule_info *rulei, +struct mlxsw_sp_acl_block *block, +struct net_device *out_dev) +{ +struct mlxsw_sp_acl_block_binding *binding; +struct mlxsw_sp_port *out_port; +struct mlxsw_sp_port *in_port; + +if (!list_is_singular (&block->binding_list)) +return -EOPNOTSUPP ; + + binding =list_first_entry (&block->binding_list, + struct mlxsw_sp_acl_block_binding, list); + in_port = binding->mlxsw_sp_port; +if (!mlxsw_sp_port_dev_check (out_dev)) +return -EINVAL ; + + out_port =netdev_priv (out_dev); +if (out_port->mlxsw_sp != mlxsw_sp) +return -EINVAL ; + +return mlxsw_afa_block_append_mirror (rulei->act_block, + in_port->local_port, + out_port->local_port, + binding->ingress); +} +int mlxsw_sp_acl_rulei_act_vlan (struct mlxsw_sp *mlxsw_sp,struct mlxsw_sp_acl_rule_info *rulei,u32 action,u16 vid,u16 proto,u8 prio)
drivers/net/ethernet/mellanox/mlxsw/spectrum_flower.c +7 -0
@@ -108,6 +108,13 @@ static int mlxsw_sp_flower_parse_actions(struct mlxsw_sp *mlxsw_sp, out_dev);if (err)return err; + }else if (is_tcf_mirred_egress_mirror (a)) { +struct net_device *out_dev =tcf_mirred_dev (a); + + err =mlxsw_sp_acl_rulei_act_mirror (mlxsw_sp, rulei, + block, out_dev); +if (err) +return err; }else if (is_tcf_vlan (a)) {u16 proto =be16_to_cpu (tcf_vlan_push_proto (a));u32 action =tcf_vlan_action (a);
Signature · 1 line
2.14.3
David Miller
maintainerFrom: Jiri Pirko <[email protected]>
Date: Fri, 19 Jan 2018 09:24:45 +0100
Quoted 7 lines
From: Jiri Pirko <[email protected]>
Arkadi says:
Add support for mirror action with flower classifier. The first 3 patches introduce a generic per-block resource infra. The last 4 patches add support for flow based span.
Series applied, thanks.