diff --git a/src/common/wpa_ctrl.h b/src/common/wpa_ctrl.h index 3de468235..3e0a7ec23 100644 --- a/src/common/wpa_ctrl.h +++ b/src/common/wpa_ctrl.h @@ -77,6 +77,19 @@ extern "C" { /** Regulatory domain channel */ #define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE " +/** IP subnet status change notification + * + * When using an offloaded roaming mechanism where driver/firmware takes care + * of roaming and IP subnet validation checks post-roaming, this event can + * indicate whether IP subnet has changed. + * + * The event has a status=<0/1/2> parameter where + * 0 = unknown + * 1 = IP subnet unchanged (can continue to use the old IP address) + * 2 = IP subnet changed (need to get a new IP address) + */ +#define WPA_EVENT_SUBNET_STATUS_UPDATE "CTRL-EVENT-SUBNET-STATUS-UPDATE " + /** RSN IBSS 4-way handshakes completed with specified peer */ #define IBSS_RSN_COMPLETED "IBSS-RSN-COMPLETED " diff --git a/src/drivers/driver.h b/src/drivers/driver.h index 09c4fa182..1ed232097 100644 --- a/src/drivers/driver.h +++ b/src/drivers/driver.h @@ -4106,6 +4106,12 @@ union wpa_event_data { * ptk_kek_len - The length of ptk_kek */ size_t ptk_kek_len; + + /** + * subnet_status - The subnet status: + * 0 = unknown, 1 = unchanged, 2 = changed + */ + u8 subnet_status; } assoc_info; /** diff --git a/src/drivers/driver_nl80211_event.c b/src/drivers/driver_nl80211_event.c index 721b1b91e..e8cdeeb1b 100644 --- a/src/drivers/driver_nl80211_event.c +++ b/src/drivers/driver_nl80211_event.c @@ -268,7 +268,8 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv, struct nlattr *authorized, struct nlattr *key_replay_ctr, struct nlattr *ptk_kck, - struct nlattr *ptk_kek) + struct nlattr *ptk_kek, + struct nlattr *subnet_status) { union wpa_event_data event; const u8 *ssid; @@ -367,6 +368,17 @@ static void mlme_event_connect(struct wpa_driver_nl80211_data *drv, event.assoc_info.ptk_kek_len = nla_len(ptk_kek); } + if (subnet_status) { + /* + * At least for now, this is only available from + * QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS and that + * attribute has the same values 0, 1, 2 as are used in the + * variable here, so no mapping between different values are + * needed. + */ + event.assoc_info.subnet_status = nla_get_u8(subnet_status); + } + wpa_supplicant_event(drv->ctx, EVENT_ASSOC, &event); } @@ -1600,7 +1612,8 @@ static void qca_nl80211_key_mgmt_auth(struct wpa_driver_nl80211_data *drv, tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_AUTHORIZED], tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_KEY_REPLAY_CTR], tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KCK], - tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK]); + tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_PTK_KEK], + tb[QCA_WLAN_VENDOR_ATTR_ROAM_AUTH_SUBNET_STATUS]); } @@ -2084,7 +2097,7 @@ static void do_process_drv_event(struct i802_bss *bss, int cmd, tb[NL80211_ATTR_MAC], tb[NL80211_ATTR_REQ_IE], tb[NL80211_ATTR_RESP_IE], - NULL, NULL, NULL, NULL); + NULL, NULL, NULL, NULL, NULL); break; case NL80211_CMD_CH_SWITCH_NOTIFY: mlme_event_ch_switch(drv, diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 9bd791b04..547aa9839 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3256,6 +3256,11 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpa_supplicant_event_assoc(wpa_s, data); if (data && data->assoc_info.authorized) wpa_supplicant_event_assoc_auth(wpa_s, data); + if (data) { + wpa_msg(wpa_s, MSG_INFO, + WPA_EVENT_SUBNET_STATUS_UPDATE "status=%u", + data->assoc_info.subnet_status); + } break; case EVENT_DISASSOC: wpas_event_disassoc(wpa_s,