mlxsw: spectrum_fid: Add APIs to lookup FID without creating it
authorIdo Schimmel <idosch@mellanox.com>
Wed, 17 Oct 2018 08:53:05 +0000 (08:53 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 18 Oct 2018 00:45:07 +0000 (17:45 -0700)
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 <idosch@mellanox.com>
Reviewed-by: Petr Machata <petrm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlxsw/spectrum.h
drivers/net/ethernet/mellanox/mlxsw/spectrum_fid.c

index 7f96953f04091f37f7e891b385cfd87903aeb81f..f463be58c6dce4728eeb732f2f81bb97b6672f29 100644 (file)
@@ -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);
index 7e07cf368e9079bece5031f18d8eb04ccf5111fa..0ba3d90d46327538ea3924b5ce6142a6d3e1a8a7 100644 (file)
@@ -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)
 {