Skip to content

Commit 9d9fe04

Browse files
idoschdavem330
authored andcommitted
mlxsw: spectrum: Adjust FDB notifications for VLAN devices
FDB notifications contain the FID and port (or LAG ID) on which the MAC was learned. In the case of the 802.1Q bridge one can easily derive the matching VID - as FID equals VID - and generate the appropriate notification for the software bridge. With VLAN devices this is no longer the case, as these are associated with a vFID. Solve that by converting the FID to a vFID and lookup the matching VLAN device. From that derive the VID and whether learning (and learning sync) should occur. Signed-off-by: Ido Schimmel <[email protected]> Signed-off-by: Jiri Pirko <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 168a885 commit 9d9fe04

File tree

2 files changed

+61
-4
lines changed

2 files changed

+61
-4
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,16 @@ static inline u16 mlxsw_sp_vfid_to_fid(u16 vfid)
7373
return MLXSW_SP_VFID_BASE + vfid;
7474
}
7575

76+
static inline u16 mlxsw_sp_fid_to_vfid(u16 fid)
77+
{
78+
return fid - MLXSW_SP_VFID_BASE;
79+
}
80+
81+
static inline bool mlxsw_sp_fid_is_vfid(u16 fid)
82+
{
83+
return fid >= MLXSW_SP_VFID_BASE;
84+
}
85+
7686
struct mlxsw_sp {
7787
struct {
7888
struct list_head list;
@@ -177,6 +187,21 @@ mlxsw_sp_port_vport_find(const struct mlxsw_sp_port *mlxsw_sp_port, u16 vid)
177187
return NULL;
178188
}
179189

190+
static inline struct mlxsw_sp_port *
191+
mlxsw_sp_port_vport_find_by_vfid(const struct mlxsw_sp_port *mlxsw_sp_port,
192+
u16 vfid)
193+
{
194+
struct mlxsw_sp_port *mlxsw_sp_vport;
195+
196+
list_for_each_entry(mlxsw_sp_vport, &mlxsw_sp_port->vports_list,
197+
vport.list) {
198+
if (mlxsw_sp_vport_vfid_get(mlxsw_sp_vport) == vfid)
199+
return mlxsw_sp_vport;
200+
}
201+
202+
return NULL;
203+
}
204+
180205
enum mlxsw_sp_flood_table {
181206
MLXSW_SP_FLOOD_TABLE_UC,
182207
MLXSW_SP_FLOOD_TABLE_BM,

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

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -994,6 +994,24 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
994994
return;
995995
}
996996

997+
if (mlxsw_sp_fid_is_vfid(fid)) {
998+
u16 vfid = mlxsw_sp_fid_to_vfid(fid);
999+
struct mlxsw_sp_port *mlxsw_sp_vport;
1000+
1001+
mlxsw_sp_vport = mlxsw_sp_port_vport_find_by_vfid(mlxsw_sp_port,
1002+
vfid);
1003+
if (!mlxsw_sp_vport) {
1004+
netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n");
1005+
return;
1006+
}
1007+
1008+
vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
1009+
/* Override the physical port with the vPort. */
1010+
mlxsw_sp_port = mlxsw_sp_vport;
1011+
} else {
1012+
vid = fid;
1013+
}
1014+
9971015
err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp_port, mac, fid,
9981016
adding && mlxsw_sp_port->learning, true);
9991017
if (err) {
@@ -1002,8 +1020,6 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
10021020
return;
10031021
}
10041022

1005-
vid = fid;
1006-
10071023
mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning,
10081024
mlxsw_sp_port->learning_sync,
10091025
adding, mac, vid, mlxsw_sp_port->dev);
@@ -1026,6 +1042,24 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
10261042
return;
10271043
}
10281044

1045+
if (mlxsw_sp_fid_is_vfid(fid)) {
1046+
u16 vfid = mlxsw_sp_fid_to_vfid(fid);
1047+
struct mlxsw_sp_port *mlxsw_sp_vport;
1048+
1049+
mlxsw_sp_vport = mlxsw_sp_port_vport_find_by_vfid(mlxsw_sp_port,
1050+
vfid);
1051+
if (!mlxsw_sp_vport) {
1052+
netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n");
1053+
return;
1054+
}
1055+
1056+
vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
1057+
/* Override the physical port with the vPort. */
1058+
mlxsw_sp_port = mlxsw_sp_vport;
1059+
} else {
1060+
vid = fid;
1061+
}
1062+
10291063
err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid,
10301064
adding && mlxsw_sp_port->learning,
10311065
true);
@@ -1035,8 +1069,6 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
10351069
return;
10361070
}
10371071

1038-
vid = fid;
1039-
10401072
mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning,
10411073
mlxsw_sp_port->learning_sync,
10421074
adding, mac, vid,

0 commit comments

Comments
 (0)