3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-25 17:59:25 +01:00

netdev: allow powered address change

Support for MAC address changes while powered was recently added to
mac80211. This avoids the need to power down the device which both
saves time as well as preserves any allowed frequencies which may
have been disabled if the device powered down.

The code path for changing the address was reused but now just the
'up' callback will be provided directly to l_rtnl_set_mac. Since
there aren't multiple stages of callbacks the rtnl_data structure
isn't strictly needed, but the code looks cleaner and more
consistent between the powered/non-powered code paths.

The comment/debug error print was also updated to be more general
between the two MAC change code paths.
This commit is contained in:
James Prestwood 2022-09-06 12:22:06 -07:00 committed by Denis Kenzior
parent f10bac5ff5
commit 45f95ecf35

View File

@ -3601,12 +3601,8 @@ static void netdev_mac_change_failed(struct netdev *netdev,
goto failed; goto failed;
} else { } else {
/* /* If the interface is up we can still try and connect */
* If the interface is up we can still try and connect. This l_info("Failed to change the MAC, continuing with connection");
* is a very rare case and most likely will never happen.
*/
l_info("Interface still up after failing to change the MAC, "
"continuing with connection");
if (netdev_begin_connection(netdev) < 0) if (netdev_begin_connection(netdev) < 0)
goto failed; goto failed;
@ -3641,8 +3637,8 @@ static void netdev_mac_power_up_cb(int error, uint16_t type,
netdev->mac_change_cmd_id = 0; netdev->mac_change_cmd_id = 0;
if (error) { if (error) {
l_error("Error taking interface %u up for per-network MAC " l_error("Error changing per-network MAC on interface %u: %s",
"generation: %s", netdev->index, strerror(-error)); netdev->index, strerror(-error));
netdev_mac_change_failed(netdev, req, error); netdev_mac_change_failed(netdev, req, error);
return; return;
} }
@ -3673,8 +3669,6 @@ static void netdev_mac_power_down_cb(int error, uint16_t type,
return; return;
} }
l_debug("Setting generated address on ifindex: %d to: "MAC,
netdev->index, MAC_STR(req->addr));
netdev->mac_change_cmd_id = l_rtnl_set_mac(rtnl, netdev->index, netdev->mac_change_cmd_id = l_rtnl_set_mac(rtnl, netdev->index,
req->addr, true, req->addr, true,
netdev_mac_power_up_cb, req, netdev_mac_power_up_cb, req,
@ -3713,6 +3707,8 @@ static int netdev_start_powered_mac_change(struct netdev *netdev)
{ {
struct rtnl_data *req; struct rtnl_data *req;
uint8_t new_addr[6]; uint8_t new_addr[6];
bool powered = wiphy_has_ext_feature(netdev->wiphy,
NL80211_EXT_FEATURE_POWERED_ADDR_CHANGE);
/* No address set in handshake, use per-network MAC generation */ /* No address set in handshake, use per-network MAC generation */
if (l_memeqzero(netdev->handshake->spa, ETH_ALEN)) if (l_memeqzero(netdev->handshake->spa, ETH_ALEN))
@ -3734,9 +3730,16 @@ static int netdev_start_powered_mac_change(struct netdev *netdev)
req->ref++; req->ref++;
memcpy(req->addr, new_addr, sizeof(req->addr)); memcpy(req->addr, new_addr, sizeof(req->addr));
netdev->mac_change_cmd_id = l_rtnl_set_powered(rtnl, netdev->index, if (powered)
false, netdev_mac_power_down_cb, netdev->mac_change_cmd_id = l_rtnl_set_mac(rtnl, netdev->index,
req, netdev_mac_destroy); req->addr, false,
netdev_mac_power_up_cb, req,
netdev_mac_destroy);
else
netdev->mac_change_cmd_id = l_rtnl_set_powered(rtnl,
netdev->index, false,
netdev_mac_power_down_cb, req,
netdev_mac_destroy);
if (!netdev->mac_change_cmd_id) { if (!netdev->mac_change_cmd_id) {
l_free(req); l_free(req);
@ -3744,6 +3747,10 @@ static int netdev_start_powered_mac_change(struct netdev *netdev)
return -EIO; return -EIO;
} }
l_debug("Setting generated address on ifindex: %d to: "MAC" (%s)",
netdev->index, MAC_STR(req->addr),
powered ? "powered" : "power-down");
return 0; return 0;
} }