mirror of
https://git.kernel.org/pub/scm/network/wireless/iwd.git
synced 2024-11-23 07:29:28 +01:00
ap: remove ap_error_deauth_sta
Instead of manually sending a deauth/disassociate to a station during an error or removal, the kernel can do it automatically with DEL_STATION by including the MGMT_SUBTYPE attribute. This removes the need for ap_error_deauth_sta and introduces ap_deauthenticate_sta. Now AP can be explicit when it chooses to deauth or disassociate.
This commit is contained in:
parent
48b7ed1e47
commit
93a113f551
109
src/ap.c
109
src/ap.c
@ -167,9 +167,6 @@ static void ap_new_rsna(struct sta_state *sta)
|
||||
*/
|
||||
}
|
||||
|
||||
static void ap_error_deauth_sta(struct sta_state *sta,
|
||||
enum mmpdu_reason_code reason);
|
||||
|
||||
static void ap_drop_rsna(struct sta_state *sta)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
@ -332,6 +329,52 @@ static uint32_t ap_send_mgmt_frame(struct ap_state *ap,
|
||||
return id;
|
||||
}
|
||||
|
||||
static struct l_genl_msg *ap_build_del_station(struct sta_state *sta,
|
||||
enum mmpdu_reason_code reason, uint8_t subtype)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
uint32_t ifindex = device_get_ifindex(sta->ap->device);
|
||||
|
||||
sta->associated = false;
|
||||
sta->rsna = false;
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_DEL_STATION, 64);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &ifindex);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, 6, sta->addr);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_MGMT_SUBTYPE, 1, &subtype);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_REASON_CODE, 2, &reason);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static void ap_deauthenticate_sta(struct sta_state *sta,
|
||||
enum mmpdu_reason_code reason)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
|
||||
msg = ap_build_del_station(sta, reason,
|
||||
MPDU_MANAGEMENT_SUBTYPE_DEAUTHENTICATION);
|
||||
|
||||
if (!l_genl_family_send(nl80211, msg, ap_del_sta_cb, NULL, NULL)) {
|
||||
l_genl_msg_unref(msg);
|
||||
l_error("Issuing DEL_STATION failed");
|
||||
}
|
||||
}
|
||||
|
||||
static void ap_disassociate_sta(struct sta_state *sta,
|
||||
enum mmpdu_reason_code reason)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
|
||||
msg = ap_build_del_station(sta, reason,
|
||||
MPDU_MANAGEMENT_SUBTYPE_DISASSOCIATION);
|
||||
|
||||
if (!l_genl_family_send(nl80211, msg, ap_del_sta_cb, NULL, NULL)) {
|
||||
l_genl_msg_unref(msg);
|
||||
l_error("Issuing DEL_STATION failed");
|
||||
}
|
||||
}
|
||||
|
||||
static void ap_handshake_event(struct handshake_state *hs,
|
||||
enum handshake_event event, void *event_data, void *user_data)
|
||||
{
|
||||
@ -342,62 +385,13 @@ static void ap_handshake_event(struct handshake_state *hs,
|
||||
ap_new_rsna(sta);
|
||||
break;
|
||||
case HANDSHAKE_EVENT_FAILED:
|
||||
ap_error_deauth_sta(sta, l_get_u16(event_data));
|
||||
ap_deauthenticate_sta(sta, l_get_u16(event_data));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ap_disassociate_sta(struct ap_state *ap, struct sta_state *sta)
|
||||
{
|
||||
struct l_genl_msg *msg;
|
||||
uint32_t ifindex = device_get_ifindex(ap->device);
|
||||
|
||||
sta->associated = false;
|
||||
sta->rsna = false;
|
||||
|
||||
msg = l_genl_msg_new_sized(NL80211_CMD_DEL_STATION, 64);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_IFINDEX, 4, &ifindex);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_MAC, 6, sta->addr);
|
||||
l_genl_msg_append_attr(msg, NL80211_ATTR_STA_AID, 2, &sta->aid);
|
||||
|
||||
if (!l_genl_family_send(nl80211, msg, ap_del_sta_cb, NULL, NULL)) {
|
||||
l_genl_msg_unref(msg);
|
||||
l_error("Issuing DEL_STATION failed");
|
||||
}
|
||||
}
|
||||
|
||||
static void ap_error_deauth_sta(struct sta_state *sta,
|
||||
enum mmpdu_reason_code reason)
|
||||
{
|
||||
struct ap_state *ap = sta->ap;
|
||||
const uint8_t *bssid = device_get_address(ap->device);
|
||||
uint8_t mpdu_buf[128];
|
||||
struct mmpdu_header *mpdu = (void *) mpdu_buf;
|
||||
struct mmpdu_deauthentication *deauth;
|
||||
|
||||
memset(mpdu, 0, sizeof(*mpdu));
|
||||
mpdu->fc.protocol_version = 0;
|
||||
mpdu->fc.type = MPDU_TYPE_MANAGEMENT;
|
||||
mpdu->fc.subtype = MPDU_MANAGEMENT_SUBTYPE_DEAUTHENTICATION;
|
||||
memcpy(mpdu->address_1, sta->addr, 6); /* DA */
|
||||
memcpy(mpdu->address_2, bssid, 6); /* SA */
|
||||
memcpy(mpdu->address_3, bssid, 6); /* BSSID */
|
||||
|
||||
deauth = (void *) mmpdu_body(mpdu);
|
||||
deauth->reason_code = L_CPU_TO_LE16(reason);
|
||||
|
||||
ap_send_mgmt_frame(ap, mpdu, deauth->ies - mpdu_buf, false, NULL, NULL);
|
||||
|
||||
if (sta->associated)
|
||||
ap_disassociate_sta(ap, sta);
|
||||
|
||||
l_queue_remove(ap->sta_states, sta);
|
||||
|
||||
ap_sta_free(sta);
|
||||
}
|
||||
|
||||
static void ap_associate_sta_cb(struct l_genl_msg *msg, void *user_data)
|
||||
{
|
||||
struct sta_state *sta = user_data;
|
||||
@ -458,7 +452,7 @@ static void ap_associate_sta_cb(struct l_genl_msg *msg, void *user_data)
|
||||
return;
|
||||
|
||||
error:
|
||||
ap_disassociate_sta(sta->ap, sta);
|
||||
ap_disassociate_sta(sta, MMPDU_REASON_CODE_UNSPECIFIED);
|
||||
}
|
||||
|
||||
static void ap_associate_sta(struct ap_state *ap, struct sta_state *sta)
|
||||
@ -541,7 +535,7 @@ static void ap_success_assoc_resp_cb(struct l_genl_msg *msg, void *user_data)
|
||||
|
||||
/* If we were in State 3 or 4 go to back to State 2 */
|
||||
if (sta->associated)
|
||||
ap_disassociate_sta(ap, sta);
|
||||
ap_disassociate_sta(sta, MMPDU_REASON_CODE_UNSPECIFIED);
|
||||
|
||||
return;
|
||||
}
|
||||
@ -1003,7 +997,7 @@ static void ap_disassoc_cb(struct netdev *netdev,
|
||||
if (!sta || !sta->associated)
|
||||
return;
|
||||
|
||||
ap_disassociate_sta(ap, sta);
|
||||
ap_disassociate_sta(sta, L_LE16_TO_CPU(disassoc->reason_code));
|
||||
}
|
||||
|
||||
static void ap_auth_reply_cb(struct l_genl_msg *msg, void *user_data)
|
||||
@ -1137,8 +1131,7 @@ static void ap_deauth_cb(struct netdev *netdev, const struct mmpdu_header *hdr,
|
||||
if (!sta)
|
||||
return;
|
||||
|
||||
if (sta->associated)
|
||||
ap_disassociate_sta(ap, sta);
|
||||
ap_deauthenticate_sta(sta, L_LE16_TO_CPU(deauth->reason_code));
|
||||
|
||||
ap_sta_free(sta);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user