Skip to content

Commit ebdd7b4

Browse files
committed
Merge branch 'mlxsw-Add-support-for-mirror-action-with-flower'
Jiri Pirko says: ==================== mlxsw: Add support for mirror action with flower 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. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 65b342f + d0d13c1 commit ebdd7b4

File tree

8 files changed

+410
-85
lines changed

8 files changed

+410
-85
lines changed

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.c

Lines changed: 233 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -310,17 +310,41 @@ struct mlxsw_afa_block {
310310
struct mlxsw_afa_set *first_set;
311311
struct mlxsw_afa_set *cur_set;
312312
unsigned int cur_act_index; /* In current set. */
313-
struct list_head fwd_entry_ref_list;
313+
struct list_head resource_list; /* List of resources held by actions
314+
* in this block.
315+
*/
314316
};
315317

318+
struct mlxsw_afa_resource {
319+
struct list_head list;
320+
void (*destructor)(struct mlxsw_afa_block *block,
321+
struct mlxsw_afa_resource *resource);
322+
};
323+
324+
static void mlxsw_afa_resource_add(struct mlxsw_afa_block *block,
325+
struct mlxsw_afa_resource *resource)
326+
{
327+
list_add(&resource->list, &block->resource_list);
328+
}
329+
330+
static void mlxsw_afa_resources_destroy(struct mlxsw_afa_block *block)
331+
{
332+
struct mlxsw_afa_resource *resource, *tmp;
333+
334+
list_for_each_entry_safe(resource, tmp, &block->resource_list, list) {
335+
list_del(&resource->list);
336+
resource->destructor(block, resource);
337+
}
338+
}
339+
316340
struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa)
317341
{
318342
struct mlxsw_afa_block *block;
319343

320344
block = kzalloc(sizeof(*block), GFP_KERNEL);
321345
if (!block)
322346
return NULL;
323-
INIT_LIST_HEAD(&block->fwd_entry_ref_list);
347+
INIT_LIST_HEAD(&block->resource_list);
324348
block->afa = mlxsw_afa;
325349

326350
/* 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)
336360
}
337361
EXPORT_SYMBOL(mlxsw_afa_block_create);
338362

339-
static void mlxsw_afa_fwd_entry_refs_destroy(struct mlxsw_afa_block *block);
340-
341363
void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block)
342364
{
343365
struct mlxsw_afa_set *set = block->first_set;
@@ -348,7 +370,7 @@ void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block)
348370
mlxsw_afa_set_put(block->afa, set);
349371
set = next_set;
350372
} while (set);
351-
mlxsw_afa_fwd_entry_refs_destroy(block);
373+
mlxsw_afa_resources_destroy(block);
352374
kfree(block);
353375
}
354376
EXPORT_SYMBOL(mlxsw_afa_block_destroy);
@@ -489,10 +511,29 @@ static void mlxsw_afa_fwd_entry_put(struct mlxsw_afa *mlxsw_afa,
489511
}
490512

491513
struct mlxsw_afa_fwd_entry_ref {
492-
struct list_head list;
514+
struct mlxsw_afa_resource resource;
493515
struct mlxsw_afa_fwd_entry *fwd_entry;
494516
};
495517

518+
static void
519+
mlxsw_afa_fwd_entry_ref_destroy(struct mlxsw_afa_block *block,
520+
struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref)
521+
{
522+
mlxsw_afa_fwd_entry_put(block->afa, fwd_entry_ref->fwd_entry);
523+
kfree(fwd_entry_ref);
524+
}
525+
526+
static void
527+
mlxsw_afa_fwd_entry_ref_destructor(struct mlxsw_afa_block *block,
528+
struct mlxsw_afa_resource *resource)
529+
{
530+
struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref;
531+
532+
fwd_entry_ref = container_of(resource, struct mlxsw_afa_fwd_entry_ref,
533+
resource);
534+
mlxsw_afa_fwd_entry_ref_destroy(block, fwd_entry_ref);
535+
}
536+
496537
static struct mlxsw_afa_fwd_entry_ref *
497538
mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port)
498539
{
@@ -509,31 +550,60 @@ mlxsw_afa_fwd_entry_ref_create(struct mlxsw_afa_block *block, u8 local_port)
509550
goto err_fwd_entry_get;
510551
}
511552
fwd_entry_ref->fwd_entry = fwd_entry;
512-
list_add(&fwd_entry_ref->list, &block->fwd_entry_ref_list);
553+
fwd_entry_ref->resource.destructor = mlxsw_afa_fwd_entry_ref_destructor;
554+
mlxsw_afa_resource_add(block, &fwd_entry_ref->resource);
513555
return fwd_entry_ref;
514556

515557
err_fwd_entry_get:
516558
kfree(fwd_entry_ref);
517559
return ERR_PTR(err);
518560
}
519561

562+
struct mlxsw_afa_counter {
563+
struct mlxsw_afa_resource resource;
564+
u32 counter_index;
565+
};
566+
520567
static void
521-
mlxsw_afa_fwd_entry_ref_destroy(struct mlxsw_afa_block *block,
522-
struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref)
568+
mlxsw_afa_counter_destroy(struct mlxsw_afa_block *block,
569+
struct mlxsw_afa_counter *counter)
523570
{
524-
list_del(&fwd_entry_ref->list);
525-
mlxsw_afa_fwd_entry_put(block->afa, fwd_entry_ref->fwd_entry);
526-
kfree(fwd_entry_ref);
571+
block->afa->ops->counter_index_put(block->afa->ops_priv,
572+
counter->counter_index);
573+
kfree(counter);
574+
}
575+
576+
static void
577+
mlxsw_afa_counter_destructor(struct mlxsw_afa_block *block,
578+
struct mlxsw_afa_resource *resource)
579+
{
580+
struct mlxsw_afa_counter *counter;
581+
582+
counter = container_of(resource, struct mlxsw_afa_counter, resource);
583+
mlxsw_afa_counter_destroy(block, counter);
527584
}
528585

529-
static void mlxsw_afa_fwd_entry_refs_destroy(struct mlxsw_afa_block *block)
586+
static struct mlxsw_afa_counter *
587+
mlxsw_afa_counter_create(struct mlxsw_afa_block *block)
530588
{
531-
struct mlxsw_afa_fwd_entry_ref *fwd_entry_ref;
532-
struct mlxsw_afa_fwd_entry_ref *tmp;
589+
struct mlxsw_afa_counter *counter;
590+
int err;
591+
592+
counter = kzalloc(sizeof(*counter), GFP_KERNEL);
593+
if (!counter)
594+
return ERR_PTR(-ENOMEM);
595+
596+
err = block->afa->ops->counter_index_get(block->afa->ops_priv,
597+
&counter->counter_index);
598+
if (err)
599+
goto err_counter_index_get;
600+
counter->resource.destructor = mlxsw_afa_counter_destructor;
601+
mlxsw_afa_resource_add(block, &counter->resource);
602+
return counter;
533603

534-
list_for_each_entry_safe(fwd_entry_ref, tmp,
535-
&block->fwd_entry_ref_list, list)
536-
mlxsw_afa_fwd_entry_ref_destroy(block, fwd_entry_ref);
604+
err_counter_index_get:
605+
kfree(counter);
606+
return ERR_PTR(err);
537607
}
538608

539609
#define MLXSW_AFA_ONE_ACTION_LEN 32
@@ -690,6 +760,16 @@ MLXSW_ITEM32(afa, trapdisc, forward_action, 0x00, 0, 4);
690760
*/
691761
MLXSW_ITEM32(afa, trapdisc, trap_id, 0x04, 0, 9);
692762

763+
/* afa_trapdisc_mirror_agent
764+
* Mirror agent.
765+
*/
766+
MLXSW_ITEM32(afa, trapdisc, mirror_agent, 0x08, 29, 3);
767+
768+
/* afa_trapdisc_mirror_enable
769+
* Mirror enable.
770+
*/
771+
MLXSW_ITEM32(afa, trapdisc, mirror_enable, 0x08, 24, 1);
772+
693773
static inline void
694774
mlxsw_afa_trapdisc_pack(char *payload,
695775
enum mlxsw_afa_trapdisc_trap_action trap_action,
@@ -701,6 +781,14 @@ mlxsw_afa_trapdisc_pack(char *payload,
701781
mlxsw_afa_trapdisc_trap_id_set(payload, trap_id);
702782
}
703783

784+
static inline void
785+
mlxsw_afa_trapdisc_mirror_pack(char *payload, bool mirror_enable,
786+
u8 mirror_agent)
787+
{
788+
mlxsw_afa_trapdisc_mirror_enable_set(payload, mirror_enable);
789+
mlxsw_afa_trapdisc_mirror_agent_set(payload, mirror_agent);
790+
}
791+
704792
int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block)
705793
{
706794
char *act = mlxsw_afa_block_append_action(block,
@@ -746,6 +834,104 @@ int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
746834
}
747835
EXPORT_SYMBOL(mlxsw_afa_block_append_trap_and_forward);
748836

837+
struct mlxsw_afa_mirror {
838+
struct mlxsw_afa_resource resource;
839+
int span_id;
840+
u8 local_in_port;
841+
u8 local_out_port;
842+
bool ingress;
843+
};
844+
845+
static void
846+
mlxsw_afa_mirror_destroy(struct mlxsw_afa_block *block,
847+
struct mlxsw_afa_mirror *mirror)
848+
{
849+
block->afa->ops->mirror_del(block->afa->ops_priv,
850+
mirror->local_in_port,
851+
mirror->local_out_port,
852+
mirror->ingress);
853+
kfree(mirror);
854+
}
855+
856+
static void
857+
mlxsw_afa_mirror_destructor(struct mlxsw_afa_block *block,
858+
struct mlxsw_afa_resource *resource)
859+
{
860+
struct mlxsw_afa_mirror *mirror;
861+
862+
mirror = container_of(resource, struct mlxsw_afa_mirror, resource);
863+
mlxsw_afa_mirror_destroy(block, mirror);
864+
}
865+
866+
static struct mlxsw_afa_mirror *
867+
mlxsw_afa_mirror_create(struct mlxsw_afa_block *block,
868+
u8 local_in_port, u8 local_out_port,
869+
bool ingress)
870+
{
871+
struct mlxsw_afa_mirror *mirror;
872+
int err;
873+
874+
mirror = kzalloc(sizeof(*mirror), GFP_KERNEL);
875+
if (!mirror)
876+
return ERR_PTR(-ENOMEM);
877+
878+
err = block->afa->ops->mirror_add(block->afa->ops_priv,
879+
local_in_port, local_out_port,
880+
ingress, &mirror->span_id);
881+
if (err)
882+
goto err_mirror_add;
883+
884+
mirror->ingress = ingress;
885+
mirror->local_out_port = local_out_port;
886+
mirror->local_in_port = local_in_port;
887+
mirror->resource.destructor = mlxsw_afa_mirror_destructor;
888+
mlxsw_afa_resource_add(block, &mirror->resource);
889+
return mirror;
890+
891+
err_mirror_add:
892+
kfree(mirror);
893+
return ERR_PTR(err);
894+
}
895+
896+
static int
897+
mlxsw_afa_block_append_allocated_mirror(struct mlxsw_afa_block *block,
898+
u8 mirror_agent)
899+
{
900+
char *act = mlxsw_afa_block_append_action(block,
901+
MLXSW_AFA_TRAPDISC_CODE,
902+
MLXSW_AFA_TRAPDISC_SIZE);
903+
if (!act)
904+
return -ENOBUFS;
905+
mlxsw_afa_trapdisc_pack(act, MLXSW_AFA_TRAPDISC_TRAP_ACTION_NOP,
906+
MLXSW_AFA_TRAPDISC_FORWARD_ACTION_FORWARD, 0);
907+
mlxsw_afa_trapdisc_mirror_pack(act, true, mirror_agent);
908+
return 0;
909+
}
910+
911+
int
912+
mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
913+
u8 local_in_port, u8 local_out_port, bool ingress)
914+
{
915+
struct mlxsw_afa_mirror *mirror;
916+
int err;
917+
918+
mirror = mlxsw_afa_mirror_create(block, local_in_port, local_out_port,
919+
ingress);
920+
if (IS_ERR(mirror))
921+
return PTR_ERR(mirror);
922+
923+
err = mlxsw_afa_block_append_allocated_mirror(block, mirror->span_id);
924+
if (err)
925+
goto err_append_allocated_mirror;
926+
927+
return 0;
928+
929+
err_append_allocated_mirror:
930+
mlxsw_afa_mirror_destroy(block, mirror);
931+
return err;
932+
}
933+
EXPORT_SYMBOL(mlxsw_afa_block_append_mirror);
934+
749935
/* Forwarding Action
750936
* -----------------
751937
* Forwarding Action can be used to implement Policy Based Switching (PBS)
@@ -853,18 +1039,43 @@ mlxsw_afa_polcnt_pack(char *payload,
8531039
mlxsw_afa_polcnt_counter_index_set(payload, counter_index);
8541040
}
8551041

856-
int mlxsw_afa_block_append_counter(struct mlxsw_afa_block *block,
857-
u32 counter_index)
1042+
int mlxsw_afa_block_append_allocated_counter(struct mlxsw_afa_block *block,
1043+
u32 counter_index)
8581044
{
859-
char *act = mlxsw_afa_block_append_action(block,
860-
MLXSW_AFA_POLCNT_CODE,
1045+
char *act = mlxsw_afa_block_append_action(block, MLXSW_AFA_POLCNT_CODE,
8611046
MLXSW_AFA_POLCNT_SIZE);
8621047
if (!act)
8631048
return -ENOBUFS;
8641049
mlxsw_afa_polcnt_pack(act, MLXSW_AFA_POLCNT_COUNTER_SET_TYPE_PACKETS_BYTES,
8651050
counter_index);
8661051
return 0;
8671052
}
1053+
EXPORT_SYMBOL(mlxsw_afa_block_append_allocated_counter);
1054+
1055+
int mlxsw_afa_block_append_counter(struct mlxsw_afa_block *block,
1056+
u32 *p_counter_index)
1057+
{
1058+
struct mlxsw_afa_counter *counter;
1059+
u32 counter_index;
1060+
int err;
1061+
1062+
counter = mlxsw_afa_counter_create(block);
1063+
if (IS_ERR(counter))
1064+
return PTR_ERR(counter);
1065+
counter_index = counter->counter_index;
1066+
1067+
err = mlxsw_afa_block_append_allocated_counter(block, counter_index);
1068+
if (err)
1069+
goto err_append_allocated_counter;
1070+
1071+
if (p_counter_index)
1072+
*p_counter_index = counter_index;
1073+
return 0;
1074+
1075+
err_append_allocated_counter:
1076+
mlxsw_afa_counter_destroy(block, counter);
1077+
return err;
1078+
}
8681079
EXPORT_SYMBOL(mlxsw_afa_block_append_counter);
8691080

8701081
/* Virtual Router and Forwarding Domain Action

drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_actions.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ struct mlxsw_afa_ops {
4646
void (*kvdl_set_del)(void *priv, u32 kvdl_index, bool is_first);
4747
int (*kvdl_fwd_entry_add)(void *priv, u32 *p_kvdl_index, u8 local_port);
4848
void (*kvdl_fwd_entry_del)(void *priv, u32 kvdl_index);
49+
int (*counter_index_get)(void *priv, unsigned int *p_counter_index);
50+
void (*counter_index_put)(void *priv, unsigned int counter_index);
51+
int (*mirror_add)(void *priv, u8 locol_in_port, u8 local_out_port,
52+
bool ingress, int *p_span_id);
53+
void (*mirror_del)(void *priv, u8 locol_in_port, u8 local_out_port,
54+
bool ingress);
4955
};
5056

5157
struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set,
@@ -63,12 +69,17 @@ int mlxsw_afa_block_append_drop(struct mlxsw_afa_block *block);
6369
int mlxsw_afa_block_append_trap(struct mlxsw_afa_block *block, u16 trap_id);
6470
int mlxsw_afa_block_append_trap_and_forward(struct mlxsw_afa_block *block,
6571
u16 trap_id);
72+
int mlxsw_afa_block_append_mirror(struct mlxsw_afa_block *block,
73+
u8 local_in_port, u8 local_out_port,
74+
bool ingress);
6675
int mlxsw_afa_block_append_fwd(struct mlxsw_afa_block *block,
6776
u8 local_port, bool in_port);
6877
int mlxsw_afa_block_append_vlan_modify(struct mlxsw_afa_block *block,
6978
u16 vid, u8 pcp, u8 et);
79+
int mlxsw_afa_block_append_allocated_counter(struct mlxsw_afa_block *block,
80+
u32 counter_index);
7081
int mlxsw_afa_block_append_counter(struct mlxsw_afa_block *block,
71-
u32 counter_index);
82+
u32 *p_counter_index);
7283
int mlxsw_afa_block_append_fid_set(struct mlxsw_afa_block *block, u16 fid);
7384
int mlxsw_afa_block_append_mcrouter(struct mlxsw_afa_block *block,
7485
u16 expected_irif, u16 min_mtu,

0 commit comments

Comments
 (0)