*/
int (*status)(void *priv, char *buf, size_t buflen);
+ /**
+ * roaming - Set roaming policy for driver-based BSS selection
+ * @priv: Private driver interface data
+ * @allowed: Whether roaming within ESS is allowed
+ * @bssid: Forced BSSID if roaming is disabled or %NULL if not set
+ * Returns: Length of written status information or -1 on failure
+ *
+ * This optional callback can be used to update roaming policy from the
+ * associate() command (bssid being set there indicates that the driver
+ * should not roam before getting this roaming() call to allow roaming.
+ * If the driver does not indicate WPA_DRIVER_FLAGS_BSS_SELECTION
+ * capability, roaming policy is handled within wpa_supplicant and there
+ * is no need to implement or react to this callback.
+ */
+ int (*roaming)(void *priv, int allowed, const u8 *bssid);
+
#ifdef CONFIG_MACSEC
int (*macsec_init)(void *priv, struct macsec_init_params *params);
static int wpa_supplicant_ctrl_iface_set_network(
struct wpa_supplicant *wpa_s, char *cmd)
{
- int id;
+ int id, ret, prev_bssid_set;
struct wpa_ssid *ssid;
char *name, *value;
+ u8 prev_bssid[ETH_ALEN];
/* cmd: "<network id> <variable name> <value>" */
name = os_strchr(cmd, ' ');
return -1;
}
- return wpa_supplicant_ctrl_iface_update_network(wpa_s, ssid, name,
- value);
+ prev_bssid_set = ssid->bssid_set;
+ os_memcpy(prev_bssid, ssid->bssid, ETH_ALEN);
+ ret = wpa_supplicant_ctrl_iface_update_network(wpa_s, ssid, name,
+ value);
+ if (ret == 0 &&
+ (ssid->bssid_set != prev_bssid_set ||
+ os_memcmp(ssid->bssid, prev_bssid, ETH_ALEN) != 0))
+ wpas_notify_network_bssid_set_changed(wpa_s, ssid);
+ return ret;
}
data, data_len, buf);
}
+static inline int wpa_drv_roaming(struct wpa_supplicant *wpa_s, int allowed,
+ const u8 *bssid)
+{
+ if (!wpa_s->driver->roaming)
+ return -1;
+ return wpa_s->driver->roaming(wpa_s->drv_priv, allowed, bssid);
+}
+
#ifdef CONFIG_MACSEC
"status='%s' parameter='%s'",
status, parameter);
}
+
+
+void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid)
+{
+ if (wpa_s->current_ssid != ssid)
+ return;
+
+ wpa_dbg(wpa_s, MSG_DEBUG,
+ "Network bssid config changed for the current network - within-ESS roaming %s",
+ ssid->bssid_set ? "disabled" : "enabled");
+
+ wpa_drv_roaming(wpa_s, !ssid->bssid_set,
+ ssid->bssid_set ? ssid->bssid : NULL);
+}
const u8 *ie, size_t ie_len, u32 ssi_signal);
void wpas_notify_eap_status(struct wpa_supplicant *wpa_s, const char *status,
const char *parameter);
+void wpas_notify_network_bssid_set_changed(struct wpa_supplicant *wpa_s,
+ struct wpa_ssid *ssid);
#endif /* NOTIFY_H */