Commit c35b57ce authored by Vladimir Oltean's avatar Vladimir Oltean Committed by Jakub Kicinski

net: switchdev: zero-initialize struct switchdev_notifier_fdb_info emitted by...

net: switchdev: zero-initialize struct switchdev_notifier_fdb_info emitted by drivers towards the bridge

The blamed commit added a new field to struct switchdev_notifier_fdb_info,
but did not make sure that all call paths set it to something valid.
For example, a switchdev driver may emit a SWITCHDEV_FDB_ADD_TO_BRIDGE
notifier, and since the 'is_local' flag is not set, it contains junk
from the stack, so the bridge might interpret those notifications as
being for local FDB entries when that was not intended.

To avoid that now and in the future, zero-initialize all
switchdev_notifier_fdb_info structures created by drivers such that all
newly added fields to not need to touch drivers again.

Fixes: 2c4eca3e ("net: bridge: switchdev: include local flag in FDB notifications")
Reported-by: default avatarIdo Schimmel <idosch@idosch.org>
Signed-off-by: default avatarVladimir Oltean <vladimir.oltean@nxp.com>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Tested-by: default avatarIdo Schimmel <idosch@nvidia.com>
Reviewed-by: default avatarLeon Romanovsky <leonro@nvidia.com>
Reviewed-by: default avatarKarsten Graul <kgraul@linux.ibm.com>
Link: https://lore.kernel.org/r/20210810115024.1629983-1-vladimir.oltean@nxp.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 45a68787
...@@ -748,7 +748,7 @@ static void ...@@ -748,7 +748,7 @@ static void
prestera_fdb_offload_notify(struct prestera_port *port, prestera_fdb_offload_notify(struct prestera_port *port,
struct switchdev_notifier_fdb_info *info) struct switchdev_notifier_fdb_info *info)
{ {
struct switchdev_notifier_fdb_info send_info; struct switchdev_notifier_fdb_info send_info = {};
send_info.addr = info->addr; send_info.addr = info->addr;
send_info.vid = info->vid; send_info.vid = info->vid;
...@@ -1123,7 +1123,7 @@ static int prestera_switchdev_blk_event(struct notifier_block *unused, ...@@ -1123,7 +1123,7 @@ static int prestera_switchdev_blk_event(struct notifier_block *unused,
static void prestera_fdb_event(struct prestera_switch *sw, static void prestera_fdb_event(struct prestera_switch *sw,
struct prestera_event *evt, void *arg) struct prestera_event *evt, void *arg)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
struct net_device *dev = NULL; struct net_device *dev = NULL;
struct prestera_port *port; struct prestera_port *port;
struct prestera_lag *lag; struct prestera_lag *lag;
......
...@@ -69,7 +69,7 @@ static void ...@@ -69,7 +69,7 @@ static void
mlx5_esw_bridge_fdb_offload_notify(struct net_device *dev, const unsigned char *addr, u16 vid, mlx5_esw_bridge_fdb_offload_notify(struct net_device *dev, const unsigned char *addr, u16 vid,
unsigned long val) unsigned long val)
{ {
struct switchdev_notifier_fdb_info send_info; struct switchdev_notifier_fdb_info send_info = {};
send_info.addr = addr; send_info.addr = addr;
send_info.vid = vid; send_info.vid = vid;
......
...@@ -9079,7 +9079,7 @@ mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif, ...@@ -9079,7 +9079,7 @@ mlxsw_sp_rif_fid_fid_get(struct mlxsw_sp_rif *rif,
static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac) static void mlxsw_sp_rif_fid_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
struct net_device *dev; struct net_device *dev;
dev = br_fdb_find_port(rif->dev, mac, 0); dev = br_fdb_find_port(rif->dev, mac, 0);
...@@ -9127,8 +9127,8 @@ mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif, ...@@ -9127,8 +9127,8 @@ mlxsw_sp_rif_vlan_fid_get(struct mlxsw_sp_rif *rif,
static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac) static void mlxsw_sp_rif_vlan_fdb_del(struct mlxsw_sp_rif *rif, const char *mac)
{ {
struct switchdev_notifier_fdb_info info = {};
u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid); u16 vid = mlxsw_sp_fid_8021q_vid(rif->fid);
struct switchdev_notifier_fdb_info info;
struct net_device *br_dev; struct net_device *br_dev;
struct net_device *dev; struct net_device *dev;
......
...@@ -2508,7 +2508,7 @@ mlxsw_sp_fdb_call_notifiers(enum switchdev_notifier_type type, ...@@ -2508,7 +2508,7 @@ mlxsw_sp_fdb_call_notifiers(enum switchdev_notifier_type type,
const char *mac, u16 vid, const char *mac, u16 vid,
struct net_device *dev, bool offloaded) struct net_device *dev, bool offloaded)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
info.addr = mac; info.addr = mac;
info.vid = vid; info.vid = vid;
......
...@@ -277,7 +277,7 @@ static void sparx5_fdb_call_notifiers(enum switchdev_notifier_type type, ...@@ -277,7 +277,7 @@ static void sparx5_fdb_call_notifiers(enum switchdev_notifier_type type,
const char *mac, u16 vid, const char *mac, u16 vid,
struct net_device *dev, bool offloaded) struct net_device *dev, bool offloaded)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
info.addr = mac; info.addr = mac;
info.vid = vid; info.vid = vid;
......
...@@ -2715,7 +2715,7 @@ static void ...@@ -2715,7 +2715,7 @@ static void
rocker_fdb_offload_notify(struct rocker_port *rocker_port, rocker_fdb_offload_notify(struct rocker_port *rocker_port,
struct switchdev_notifier_fdb_info *recv_info) struct switchdev_notifier_fdb_info *recv_info)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
info.addr = recv_info->addr; info.addr = recv_info->addr;
info.vid = recv_info->vid; info.vid = recv_info->vid;
......
...@@ -1822,7 +1822,7 @@ static void ofdpa_port_fdb_learn_work(struct work_struct *work) ...@@ -1822,7 +1822,7 @@ static void ofdpa_port_fdb_learn_work(struct work_struct *work)
container_of(work, struct ofdpa_fdb_learn_work, work); container_of(work, struct ofdpa_fdb_learn_work, work);
bool removing = (lw->flags & OFDPA_OP_FLAG_REMOVE); bool removing = (lw->flags & OFDPA_OP_FLAG_REMOVE);
bool learned = (lw->flags & OFDPA_OP_FLAG_LEARNED); bool learned = (lw->flags & OFDPA_OP_FLAG_LEARNED);
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
info.addr = lw->addr; info.addr = lw->addr;
info.vid = lw->vid; info.vid = lw->vid;
......
...@@ -358,7 +358,7 @@ static int am65_cpsw_port_obj_del(struct net_device *ndev, const void *ctx, ...@@ -358,7 +358,7 @@ static int am65_cpsw_port_obj_del(struct net_device *ndev, const void *ctx,
static void am65_cpsw_fdb_offload_notify(struct net_device *ndev, static void am65_cpsw_fdb_offload_notify(struct net_device *ndev,
struct switchdev_notifier_fdb_info *rcv) struct switchdev_notifier_fdb_info *rcv)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
info.addr = rcv->addr; info.addr = rcv->addr;
info.vid = rcv->vid; info.vid = rcv->vid;
......
...@@ -368,7 +368,7 @@ static int cpsw_port_obj_del(struct net_device *ndev, const void *ctx, ...@@ -368,7 +368,7 @@ static int cpsw_port_obj_del(struct net_device *ndev, const void *ctx,
static void cpsw_fdb_offload_notify(struct net_device *ndev, static void cpsw_fdb_offload_notify(struct net_device *ndev,
struct switchdev_notifier_fdb_info *rcv) struct switchdev_notifier_fdb_info *rcv)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
info.addr = rcv->addr; info.addr = rcv->addr;
info.vid = rcv->vid; info.vid = rcv->vid;
......
...@@ -279,7 +279,7 @@ static void qeth_l2_set_pnso_mode(struct qeth_card *card, ...@@ -279,7 +279,7 @@ static void qeth_l2_set_pnso_mode(struct qeth_card *card,
static void qeth_l2_dev2br_fdb_flush(struct qeth_card *card) static void qeth_l2_dev2br_fdb_flush(struct qeth_card *card)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
QETH_CARD_TEXT(card, 2, "fdbflush"); QETH_CARD_TEXT(card, 2, "fdbflush");
...@@ -679,7 +679,7 @@ static void qeth_l2_dev2br_fdb_notify(struct qeth_card *card, u8 code, ...@@ -679,7 +679,7 @@ static void qeth_l2_dev2br_fdb_notify(struct qeth_card *card, u8 code,
struct net_if_token *token, struct net_if_token *token,
struct mac_addr_lnid *addr_lnid) struct mac_addr_lnid *addr_lnid)
{ {
struct switchdev_notifier_fdb_info info; struct switchdev_notifier_fdb_info info = {};
u8 ntfy_mac[ETH_ALEN]; u8 ntfy_mac[ETH_ALEN];
ether_addr_copy(ntfy_mac, addr_lnid->mac); ether_addr_copy(ntfy_mac, addr_lnid->mac);
......
...@@ -2291,8 +2291,8 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb, ...@@ -2291,8 +2291,8 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb,
static void static void
dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work) dsa_fdb_offload_notify(struct dsa_switchdev_event_work *switchdev_work)
{ {
struct switchdev_notifier_fdb_info info = {};
struct dsa_switch *ds = switchdev_work->ds; struct dsa_switch *ds = switchdev_work->ds;
struct switchdev_notifier_fdb_info info;
struct dsa_port *dp; struct dsa_port *dp;
if (!dsa_is_user_port(ds, switchdev_work->port)) if (!dsa_is_user_port(ds, switchdev_work->port))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment