net/mlx5: Create TC-miss priority and table
authorVlad Buslov <vladbu@nvidia.com>
Thu, 4 Mar 2021 11:09:53 +0000 (13:09 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Thu, 10 Jun 2021 01:36:08 +0000 (18:36 -0700)
In order to adhere to kernel software datapath model bridge offloads must
come after TC and NF FDBs. Following patches in this series add new FDB
priority for bridge after FDB_FT_OFFLOAD. However, since netfilter offload
is implemented with unmanaged tables, its miss path is not automatically
connected to next priority and requires the code to manually connect with
slow table. To keep bridge offloads encapsulated and not mix it with
eswitch offloads, create a new FDB_TC_MISS priority between FDB_FT_OFFLOAD
and FDB_SLOW_PATH:

          +
          |
+---------v----------+
|                    |
|   FDB_TC_OFFLOAD   |
|                    |
+---------+----------+
          |
          |
          |
+---------v----------+
|                    |
|   FDB_FT_OFFLOAD   |
|                    |
+---------+----------+
          |
          |
          |
+---------v----------+
|                    |
|    FDB_TC_MISS     |
|                    |
+---------+----------+
          |
          |
          |
+---------v----------+
|                    |
|   FDB_SLOW_PATH    |
|                    |
+---------+----------+
          |
          v

Initialize the new priority with single default empty managed table and use
the table as TC/NF miss patch instead of slow table. This approach allows
bridge offloads to be created as new FDB namespace priority between
FDB_TC_MISS and FDB_SLOW_PATH without exposing its internal tables to any
other modules since miss path of managed TC-miss table is automatically
wired to next priority.

Signed-off-by: Vlad Buslov <vladbu@nvidia.com>
Reviewed-by: Jianbo Liu <jianbol@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
include/linux/mlx5/fs.h

index 64ccb2bc0b58c866b2ed4f6354eb96e573e8b331..55404eabff396db5d6ff1460115f973bce487223 100644 (file)
@@ -196,6 +196,7 @@ struct mlx5_eswitch_fdb {
 
                struct offloads_fdb {
                        struct mlx5_flow_namespace *ns;
+                       struct mlx5_flow_table *tc_miss_table;
                        struct mlx5_flow_table *slow_fdb;
                        struct mlx5_flow_group *send_to_vport_grp;
                        struct mlx5_flow_group *send_to_vport_meta_grp;
index d18a28a6e9a63a7b5f9c3cd15e6da7fda3db7dbb..7579f3402776cabe8191814f5c672a77abdb7128 100644 (file)
@@ -1634,7 +1634,21 @@ static int esw_create_offloads_fdb_tables(struct mlx5_eswitch *esw)
        }
        esw->fdb_table.offloads.slow_fdb = fdb;
 
-       err = esw_chains_create(esw, fdb);
+       /* Create empty TC-miss managed table. This allows plugging in following
+        * priorities without directly exposing their level 0 table to
+        * eswitch_offloads and passing it as miss_fdb to following call to
+        * esw_chains_create().
+        */
+       memset(&ft_attr, 0, sizeof(ft_attr));
+       ft_attr.prio = FDB_TC_MISS;
+       esw->fdb_table.offloads.tc_miss_table = mlx5_create_flow_table(root_ns, &ft_attr);
+       if (IS_ERR(esw->fdb_table.offloads.tc_miss_table)) {
+               err = PTR_ERR(esw->fdb_table.offloads.tc_miss_table);
+               esw_warn(dev, "Failed to create TC miss FDB Table err %d\n", err);
+               goto tc_miss_table_err;
+       }
+
+       err = esw_chains_create(esw, esw->fdb_table.offloads.tc_miss_table);
        if (err) {
                esw_warn(dev, "Failed to open fdb chains err(%d)\n", err);
                goto fdb_chains_err;
@@ -1779,6 +1793,8 @@ send_vport_meta_err:
 send_vport_err:
        esw_chains_destroy(esw, esw_chains(esw));
 fdb_chains_err:
+       mlx5_destroy_flow_table(esw->fdb_table.offloads.tc_miss_table);
+tc_miss_table_err:
        mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb);
 slow_fdb_err:
        /* Holds true only as long as DMFS is the default */
@@ -1806,6 +1822,7 @@ static void esw_destroy_offloads_fdb_tables(struct mlx5_eswitch *esw)
 
        esw_chains_destroy(esw, esw_chains(esw));
 
+       mlx5_destroy_flow_table(esw->fdb_table.offloads.tc_miss_table);
        mlx5_destroy_flow_table(esw->fdb_table.offloads.slow_fdb);
        /* Holds true only as long as DMFS is the default */
        mlx5_flow_namespace_set_mode(esw->fdb_table.offloads.ns,
index c0936b4e53a90b31c3a5f75a11fa88ff68687989..fc70c4ed8469d533fcd2506f0ef4c984b43e82a7 100644 (file)
@@ -2780,6 +2780,12 @@ static int init_fdb_root_ns(struct mlx5_flow_steering *steering)
        if (err)
                goto out_err;
 
+       maj_prio = fs_create_prio(&steering->fdb_root_ns->ns, FDB_TC_MISS, 1);
+       if (IS_ERR(maj_prio)) {
+               err = PTR_ERR(maj_prio);
+               goto out_err;
+       }
+
        maj_prio = fs_create_prio(&steering->fdb_root_ns->ns, FDB_SLOW_PATH, 1);
        if (IS_ERR(maj_prio)) {
                err = PTR_ERR(maj_prio);
index f69f68fba9469021ededc708cfcba942f5f68fac..271f2f4d6b60d6e7170feee7cbdca094b9cd379f 100644 (file)
@@ -87,6 +87,7 @@ enum {
        FDB_BYPASS_PATH,
        FDB_TC_OFFLOAD,
        FDB_FT_OFFLOAD,
+       FDB_TC_MISS,
        FDB_SLOW_PATH,
        FDB_PER_VPORT,
 };