mlxsw: spectrum_matchall: Expose a function to get min and max rule priority
authorJiri Pirko <jiri@mellanox.com>
Sat, 9 May 2020 20:06:05 +0000 (23:06 +0300)
committerJakub Kicinski <kuba@kernel.org>
Sat, 9 May 2020 23:02:43 +0000 (16:02 -0700)
Introduce an infrastructure that allows to get minimum and maximum
rule priority for specified chain. This is going to be used by
a subsequent patch to enforce ordering between flower and
matchall filters.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_matchall.c

index 55369346980581693318e39ab99a97f130c54d8a..456dbaa5ee2607d9b73ed2a1fe1798d6b74b278a 100644 (file)
@@ -638,6 +638,8 @@ struct mlxsw_sp_flow_block {
        struct list_head binding_list;
        struct {
                struct list_head list;
+               unsigned int min_prio;
+               unsigned int max_prio;
        } mall;
        struct mlxsw_sp_acl_ruleset *ruleset_zero;
        struct mlxsw_sp *mlxsw_sp;
@@ -900,6 +902,8 @@ int mlxsw_sp_mall_port_bind(struct mlxsw_sp_flow_block *block,
                            struct mlxsw_sp_port *mlxsw_sp_port);
 void mlxsw_sp_mall_port_unbind(struct mlxsw_sp_flow_block *block,
                               struct mlxsw_sp_port *mlxsw_sp_port);
+int mlxsw_sp_mall_prio_get(struct mlxsw_sp_flow_block *block, u32 chain_index,
+                          unsigned int *p_min_prio, unsigned int *p_max_prio);
 
 /* spectrum_flower.c */
 int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp,
index d64ee31a611c24135905a9e8e923f80087c7fbd2..b11bab76b2e118d8126cc6eea398e5149534adc8 100644 (file)
@@ -23,6 +23,7 @@ struct mlxsw_sp_mall_mirror_entry {
 struct mlxsw_sp_mall_entry {
        struct list_head list;
        unsigned long cookie;
+       unsigned int priority;
        enum mlxsw_sp_mall_action_type type;
        bool ingress;
        union {
@@ -175,6 +176,22 @@ mlxsw_sp_mall_port_rule_del(struct mlxsw_sp_port *mlxsw_sp_port,
        }
 }
 
+static void mlxsw_sp_mall_prio_update(struct mlxsw_sp_flow_block *block)
+{
+       struct mlxsw_sp_mall_entry *mall_entry;
+
+       if (list_empty(&block->mall.list))
+               return;
+       block->mall.min_prio = UINT_MAX;
+       block->mall.max_prio = 0;
+       list_for_each_entry(mall_entry, &block->mall.list, list) {
+               if (mall_entry->priority < block->mall.min_prio)
+                       block->mall.min_prio = mall_entry->priority;
+               if (mall_entry->priority > block->mall.max_prio)
+                       block->mall.max_prio = mall_entry->priority;
+       }
+}
+
 int mlxsw_sp_mall_replace(struct mlxsw_sp_flow_block *block,
                          struct tc_cls_matchall_offload *f)
 {
@@ -203,6 +220,7 @@ int mlxsw_sp_mall_replace(struct mlxsw_sp_flow_block *block,
        if (!mall_entry)
                return -ENOMEM;
        mall_entry->cookie = f->cookie;
+       mall_entry->priority = f->common.prio;
        mall_entry->ingress = mlxsw_sp_flow_block_is_ingress_bound(block);
 
        act = &f->rule->action.entries[0];
@@ -245,6 +263,7 @@ int mlxsw_sp_mall_replace(struct mlxsw_sp_flow_block *block,
        else
                block->ingress_blocker_rule_count++;
        list_add_tail(&mall_entry->list, &block->mall.list);
+       mlxsw_sp_mall_prio_update(block);
        return 0;
 
 rollback:
@@ -277,6 +296,7 @@ void mlxsw_sp_mall_destroy(struct mlxsw_sp_flow_block *block,
        list_for_each_entry(binding, &block->binding_list, list)
                mlxsw_sp_mall_port_rule_del(binding->mlxsw_sp_port, mall_entry);
        kfree_rcu(mall_entry, rcu); /* sample RX packets may be in-flight */
+       mlxsw_sp_mall_prio_update(block);
 }
 
 int mlxsw_sp_mall_port_bind(struct mlxsw_sp_flow_block *block,
@@ -307,3 +327,17 @@ void mlxsw_sp_mall_port_unbind(struct mlxsw_sp_flow_block *block,
        list_for_each_entry(mall_entry, &block->mall.list, list)
                mlxsw_sp_mall_port_rule_del(mlxsw_sp_port, mall_entry);
 }
+
+int mlxsw_sp_mall_prio_get(struct mlxsw_sp_flow_block *block, u32 chain_index,
+                          unsigned int *p_min_prio, unsigned int *p_max_prio)
+{
+       if (chain_index || list_empty(&block->mall.list))
+               /* In case there are no matchall rules, the caller
+                * receives -ENOENT to indicate there is no need
+                * to check the priorities.
+                */
+               return -ENOENT;
+       *p_min_prio = block->mall.min_prio;
+       *p_max_prio = block->mall.max_prio;
+       return 0;
+}