diff options
author | Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com> | 2023-12-19 15:53:29 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2023-12-27 14:08:10 +0100 |
commit | 25a00d0cd691562f43a0a4b008214405e76d067f (patch) | |
tree | 984046ecd40178d619ece452341462e69c85574f /drivers/net/macsec.c | |
parent | net: macsec: documentation for macsec_context and macsec_ops (diff) | |
download | linux-25a00d0cd691562f43a0a4b008214405e76d067f.tar.xz linux-25a00d0cd691562f43a0a4b008214405e76d067f.zip |
net: macsec: revert the MAC address if mdo_upd_secy fails
Revert the MAC address if mdo_upd_secy fails. Offloaded MACsec device
might be left in an inconsistent state.
Signed-off-by: Radu Pirea (NXP OSS) <radu-nicolae.pirea@oss.nxp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/macsec.c')
-rw-r--r-- | drivers/net/macsec.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 972bd816292a..ff0c43936bef 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c @@ -3589,21 +3589,19 @@ static int macsec_set_mac_address(struct net_device *dev, void *p) struct macsec_dev *macsec = macsec_priv(dev); struct net_device *real_dev = macsec->real_dev; struct sockaddr *addr = p; + u8 old_addr[ETH_ALEN]; int err; if (!is_valid_ether_addr(addr->sa_data)) return -EADDRNOTAVAIL; - if (!(dev->flags & IFF_UP)) - goto out; - - err = dev_uc_add(real_dev, addr->sa_data); - if (err < 0) - return err; - - dev_uc_del(real_dev, dev->dev_addr); + if (dev->flags & IFF_UP) { + err = dev_uc_add(real_dev, addr->sa_data); + if (err < 0) + return err; + } -out: + ether_addr_copy(old_addr, dev->dev_addr); eth_hw_addr_set(dev, addr->sa_data); /* If h/w offloading is available, propagate to the device */ @@ -3612,13 +3610,29 @@ out: struct macsec_context ctx; ops = macsec_get_ops(macsec, &ctx); - if (ops) { - ctx.secy = &macsec->secy; - macsec_offload(ops->mdo_upd_secy, &ctx); + if (!ops) { + err = -EOPNOTSUPP; + goto restore_old_addr; } + + ctx.secy = &macsec->secy; + err = macsec_offload(ops->mdo_upd_secy, &ctx); + if (err) + goto restore_old_addr; } + if (dev->flags & IFF_UP) + dev_uc_del(real_dev, old_addr); + return 0; + +restore_old_addr: + if (dev->flags & IFF_UP) + dev_uc_del(real_dev, addr->sa_data); + + eth_hw_addr_set(dev, old_addr); + + return err; } static int macsec_change_mtu(struct net_device *dev, int new_mtu) |