mlxsw: spectrum: remove FDB entry in case we get unknown object notification
It may happen that we get notification for FDB entry for object (port, lag, vport), which does not exist. Currently we ignore that, which only causes this being re-sent in next notification. The entry will never disappear. So get rid of it by simply removing it using SFD register. Signed-off-by: Jiri Pirko <jiri@mellanox.com> Reviewed-by: Ido Schimmel <idosch@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
2fa9d45e16
commit
12f1501e75
|
@ -1030,13 +1030,14 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
char mac[ETH_ALEN];
|
char mac[ETH_ALEN];
|
||||||
u8 local_port;
|
u8 local_port;
|
||||||
u16 vid, fid;
|
u16 vid, fid;
|
||||||
|
bool do_notification = true;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mlxsw_reg_sfn_mac_unpack(sfn_pl, rec_index, mac, &fid, &local_port);
|
mlxsw_reg_sfn_mac_unpack(sfn_pl, rec_index, mac, &fid, &local_port);
|
||||||
mlxsw_sp_port = mlxsw_sp->ports[local_port];
|
mlxsw_sp_port = mlxsw_sp->ports[local_port];
|
||||||
if (!mlxsw_sp_port) {
|
if (!mlxsw_sp_port) {
|
||||||
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect local port in FDB notification\n");
|
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Incorrect local port in FDB notification\n");
|
||||||
return;
|
goto just_remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mlxsw_sp_fid_is_vfid(fid)) {
|
if (mlxsw_sp_fid_is_vfid(fid)) {
|
||||||
|
@ -1047,9 +1048,8 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
vfid);
|
vfid);
|
||||||
if (!mlxsw_sp_vport) {
|
if (!mlxsw_sp_vport) {
|
||||||
netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n");
|
netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n");
|
||||||
return;
|
goto just_remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
|
vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
|
||||||
/* Override the physical port with the vPort. */
|
/* Override the physical port with the vPort. */
|
||||||
mlxsw_sp_port = mlxsw_sp_vport;
|
mlxsw_sp_port = mlxsw_sp_vport;
|
||||||
|
@ -1057,17 +1057,28 @@ static void mlxsw_sp_fdb_notify_mac_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
vid = fid;
|
vid = fid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adding = adding && mlxsw_sp_port->learning;
|
||||||
|
|
||||||
|
do_fdb_op:
|
||||||
err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid,
|
err = mlxsw_sp_port_fdb_uc_op(mlxsw_sp, local_port, mac, fid,
|
||||||
adding && mlxsw_sp_port->learning, true);
|
adding, true);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (net_ratelimit())
|
if (net_ratelimit())
|
||||||
netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n");
|
netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!do_notification)
|
||||||
|
return;
|
||||||
mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning,
|
mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning,
|
||||||
mlxsw_sp_port->learning_sync,
|
mlxsw_sp_port->learning_sync,
|
||||||
adding, mac, vid, mlxsw_sp_port->dev);
|
adding, mac, vid, mlxsw_sp_port->dev);
|
||||||
|
return;
|
||||||
|
|
||||||
|
just_remove:
|
||||||
|
adding = false;
|
||||||
|
do_notification = false;
|
||||||
|
goto do_fdb_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
|
static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
@ -1079,13 +1090,14 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
u16 lag_vid = 0;
|
u16 lag_vid = 0;
|
||||||
u16 lag_id;
|
u16 lag_id;
|
||||||
u16 vid, fid;
|
u16 vid, fid;
|
||||||
|
bool do_notification = true;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
mlxsw_reg_sfn_mac_lag_unpack(sfn_pl, rec_index, mac, &fid, &lag_id);
|
mlxsw_reg_sfn_mac_lag_unpack(sfn_pl, rec_index, mac, &fid, &lag_id);
|
||||||
mlxsw_sp_port = mlxsw_sp_lag_rep_port(mlxsw_sp, lag_id);
|
mlxsw_sp_port = mlxsw_sp_lag_rep_port(mlxsw_sp, lag_id);
|
||||||
if (!mlxsw_sp_port) {
|
if (!mlxsw_sp_port) {
|
||||||
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Cannot find port representor for LAG\n");
|
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Cannot find port representor for LAG\n");
|
||||||
return;
|
goto just_remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mlxsw_sp_fid_is_vfid(fid)) {
|
if (mlxsw_sp_fid_is_vfid(fid)) {
|
||||||
|
@ -1096,7 +1108,7 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
vfid);
|
vfid);
|
||||||
if (!mlxsw_sp_vport) {
|
if (!mlxsw_sp_vport) {
|
||||||
netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n");
|
netdev_err(mlxsw_sp_port->dev, "Failed to find a matching vPort following FDB notification\n");
|
||||||
return;
|
goto just_remove;
|
||||||
}
|
}
|
||||||
|
|
||||||
vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
|
vid = mlxsw_sp_vport_vid_get(mlxsw_sp_vport);
|
||||||
|
@ -1107,19 +1119,29 @@ static void mlxsw_sp_fdb_notify_mac_lag_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
vid = fid;
|
vid = fid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adding = adding && mlxsw_sp_port->learning;
|
||||||
|
|
||||||
|
do_fdb_op:
|
||||||
err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid,
|
err = mlxsw_sp_port_fdb_uc_lag_op(mlxsw_sp, lag_id, mac, fid, lag_vid,
|
||||||
adding && mlxsw_sp_port->learning,
|
adding, true);
|
||||||
true);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
if (net_ratelimit())
|
if (net_ratelimit())
|
||||||
netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n");
|
netdev_err(mlxsw_sp_port->dev, "Failed to set FDB entry\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!do_notification)
|
||||||
|
return;
|
||||||
mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning,
|
mlxsw_sp_fdb_call_notifiers(mlxsw_sp_port->learning,
|
||||||
mlxsw_sp_port->learning_sync,
|
mlxsw_sp_port->learning_sync,
|
||||||
adding, mac, vid,
|
adding, mac, vid,
|
||||||
mlxsw_sp_lag_get(mlxsw_sp, lag_id)->dev);
|
mlxsw_sp_lag_get(mlxsw_sp, lag_id)->dev);
|
||||||
|
return;
|
||||||
|
|
||||||
|
just_remove:
|
||||||
|
adding = false;
|
||||||
|
do_notification = false;
|
||||||
|
goto do_fdb_op;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mlxsw_sp_fdb_notify_rec_process(struct mlxsw_sp *mlxsw_sp,
|
static void mlxsw_sp_fdb_notify_rec_process(struct mlxsw_sp *mlxsw_sp,
|
||||||
|
|
Loading…
Reference in New Issue