wpa_group_sm_step(wpa_auth, group);
group->GInit = FALSE;
wpa_group_sm_step(wpa_auth, group);
+ if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE)
+ return -1;
return 0;
}
{
struct wpa_state_machine *sm;
+ if (wpa_auth->group->wpa_group_state == WPA_GROUP_FATAL_FAILURE)
+ return NULL;
+
sm = os_zalloc(sizeof(struct wpa_state_machine));
if (sm == NULL)
return NULL;
}
+static int wpa_group_disconnect_cb(struct wpa_state_machine *sm, void *ctx)
+{
+ if (sm->group == ctx) {
+ wpa_printf(MSG_DEBUG, "WPA: Mark STA " MACSTR
+ " for discconnection due to fatal failure",
+ MAC2STR(sm->addr));
+ sm->Disconnect = TRUE;
+ }
+
+ return 0;
+}
+
+
+static void wpa_group_fatal_failure(struct wpa_authenticator *wpa_auth,
+ struct wpa_group *group)
+{
+ wpa_printf(MSG_DEBUG, "WPA: group state machine entering state FATAL_FAILURE");
+ group->changed = TRUE;
+ group->wpa_group_state = WPA_GROUP_FATAL_FAILURE;
+ wpa_auth_for_each_sta(wpa_auth, wpa_group_disconnect_cb, group);
+}
+
+
static int wpa_group_setkeysdone(struct wpa_authenticator *wpa_auth,
struct wpa_group *group)
{
group->changed = TRUE;
group->wpa_group_state = WPA_GROUP_SETKEYSDONE;
- if (wpa_group_config_group_keys(wpa_auth, group) < 0)
+ if (wpa_group_config_group_keys(wpa_auth, group) < 0) {
+ wpa_group_fatal_failure(wpa_auth, group);
return -1;
+ }
return 0;
}
{
if (group->GInit) {
wpa_group_gtk_init(wpa_auth, group);
+ } else if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE) {
+ /* Do not allow group operations */
} else if (group->wpa_group_state == WPA_GROUP_GTK_INIT &&
group->GTKAuthenticator) {
wpa_group_setkeysdone(wpa_auth, group);
if (sm->group == group)
return 0;
+ if (group->wpa_group_state == WPA_GROUP_FATAL_FAILURE)
+ return -1;
+
wpa_printf(MSG_DEBUG, "WPA: Moving STA " MACSTR " to use group state "
"machine for VLAN ID %d", MAC2STR(sm->addr), vlan_id);