Current APIs only allow looking for a FID and creating it in case it
does not exist.

With VxLAN, in case the bridge to which the VxLAN device was enslaved
does not already have a corresponding FID, then it means that something
went wrong that we need to be aware of.

Add an API to look up a FID, but without creating it in order to catch
above-mentioned situation.

Signed-off-by: Ido Schimmel <ido...@mellanox.com>
Reviewed-by: Petr Machata <pe...@mellanox.com>
---
 .../net/ethernet/mellanox/mlxsw/spectrum.h    |  4 ++
 .../ethernet/mellanox/mlxsw/spectrum_fid.c    | 45 ++++++++++++++++---
 2 files changed, 44 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
index 7f96953f0409..f463be58c6dc 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.h
@@ -679,6 +679,8 @@ int mlxsw_sp_setup_tc_prio(struct mlxsw_sp_port 
*mlxsw_sp_port,
                           struct tc_prio_qopt_offload *p);
 
 /* spectrum_fid.c */
+struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_vni(struct mlxsw_sp *mlxsw_sp,
+                                               __be32 vni);
 int mlxsw_sp_fid_vni(const struct mlxsw_sp_fid *fid, __be32 *vni);
 int mlxsw_sp_fid_nve_flood_index_set(struct mlxsw_sp_fid *fid,
                                     u32 nve_flood_index);
@@ -705,6 +707,8 @@ u16 mlxsw_sp_fid_8021q_vid(const struct mlxsw_sp_fid *fid);
 struct mlxsw_sp_fid *mlxsw_sp_fid_8021q_get(struct mlxsw_sp *mlxsw_sp, u16 
vid);
 struct mlxsw_sp_fid *mlxsw_sp_fid_8021d_get(struct mlxsw_sp *mlxsw_sp,
                                            int br_ifindex);
+struct mlxsw_sp_fid *mlxsw_sp_fid_8021d_lookup(struct mlxsw_sp *mlxsw_sp,
+                                              int br_ifindex);
 struct mlxsw_sp_fid *mlxsw_sp_fid_rfid_get(struct mlxsw_sp *mlxsw_sp,
                                           u16 rif_index);
 struct mlxsw_sp_fid *mlxsw_sp_fid_dummy_get(struct mlxsw_sp *mlxsw_sp);
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
index 7e07cf368e90..0ba3d90d4632 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c
@@ -113,6 +113,19 @@ static const int *mlxsw_sp_packet_type_sfgc_types[] = {
        [MLXSW_SP_FLOOD_TYPE_MC]        = mlxsw_sp_sfgc_mc_packet_types,
 };
 
+struct mlxsw_sp_fid *mlxsw_sp_fid_lookup_by_vni(struct mlxsw_sp *mlxsw_sp,
+                                               __be32 vni)
+{
+       struct mlxsw_sp_fid *fid;
+
+       fid = rhashtable_lookup_fast(&mlxsw_sp->fid_core->vni_ht, &vni,
+                                    mlxsw_sp_fid_vni_ht_params);
+       if (fid)
+               fid->ref_count++;
+
+       return fid;
+}
+
 int mlxsw_sp_fid_vni(const struct mlxsw_sp_fid *fid, __be32 *vni)
 {
        if (!fid->vni_valid)
@@ -879,14 +892,12 @@ static const struct mlxsw_sp_fid_family 
*mlxsw_sp_fid_family_arr[] = {
        [MLXSW_SP_FID_TYPE_DUMMY]       = &mlxsw_sp_fid_dummy_family,
 };
 
-static struct mlxsw_sp_fid *mlxsw_sp_fid_get(struct mlxsw_sp *mlxsw_sp,
-                                            enum mlxsw_sp_fid_type type,
-                                            const void *arg)
+static struct mlxsw_sp_fid *mlxsw_sp_fid_lookup(struct mlxsw_sp *mlxsw_sp,
+                                               enum mlxsw_sp_fid_type type,
+                                               const void *arg)
 {
        struct mlxsw_sp_fid_family *fid_family;
        struct mlxsw_sp_fid *fid;
-       u16 fid_index;
-       int err;
 
        fid_family = mlxsw_sp->fid_core->fid_family_arr[type];
        list_for_each_entry(fid, &fid_family->fids_list, list) {
@@ -896,6 +907,23 @@ static struct mlxsw_sp_fid *mlxsw_sp_fid_get(struct 
mlxsw_sp *mlxsw_sp,
                return fid;
        }
 
+       return NULL;
+}
+
+static struct mlxsw_sp_fid *mlxsw_sp_fid_get(struct mlxsw_sp *mlxsw_sp,
+                                            enum mlxsw_sp_fid_type type,
+                                            const void *arg)
+{
+       struct mlxsw_sp_fid_family *fid_family;
+       struct mlxsw_sp_fid *fid;
+       u16 fid_index;
+       int err;
+
+       fid = mlxsw_sp_fid_lookup(mlxsw_sp, type, arg);
+       if (fid)
+               return fid;
+
+       fid_family = mlxsw_sp->fid_core->fid_family_arr[type];
        fid = kzalloc(fid_family->fid_size, GFP_KERNEL);
        if (!fid)
                return ERR_PTR(-ENOMEM);
@@ -955,6 +983,13 @@ struct mlxsw_sp_fid *mlxsw_sp_fid_8021d_get(struct 
mlxsw_sp *mlxsw_sp,
        return mlxsw_sp_fid_get(mlxsw_sp, MLXSW_SP_FID_TYPE_8021D, &br_ifindex);
 }
 
+struct mlxsw_sp_fid *mlxsw_sp_fid_8021d_lookup(struct mlxsw_sp *mlxsw_sp,
+                                              int br_ifindex)
+{
+       return mlxsw_sp_fid_lookup(mlxsw_sp, MLXSW_SP_FID_TYPE_8021D,
+                                  &br_ifindex);
+}
+
 struct mlxsw_sp_fid *mlxsw_sp_fid_rfid_get(struct mlxsw_sp *mlxsw_sp,
                                           u16 rif_index)
 {
-- 
2.17.2

Reply via email to