summaryrefslogtreecommitdiff
path: root/sys/dev/usb/if_otus.c
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2020-11-30 16:09:34 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2020-11-30 16:09:34 +0000
commit0de2fe85d5c810b0bfb4e612311c319c78595330 (patch)
treef0e95bd67ad9fae2d3827f685598ff34b3a2a25c /sys/dev/usb/if_otus.c
parent2d6807e7139cc792ba63be5aa13d596df01ec3dc (diff)
Fix deferred key tasks along the same lines as urtwn(4) and run(4).
athn(4) tested by stsp@, who points out that otus(4) and rsu(4) don't yet invoke the code path to do their own key setting. ok stsp@
Diffstat (limited to 'sys/dev/usb/if_otus.c')
-rw-r--r--sys/dev/usb/if_otus.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/sys/dev/usb/if_otus.c b/sys/dev/usb/if_otus.c
index 0517a00e51a..9aa771ecad9 100644
--- a/sys/dev/usb/if_otus.c
+++ b/sys/dev/usb/if_otus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_otus.c,v 1.67 2020/07/31 10:49:32 mglocker Exp $ */
+/* $OpenBSD: if_otus.c,v 1.68 2020/11/30 16:09:33 krw Exp $ */
/*-
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
@@ -2054,9 +2054,10 @@ otus_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
/* Do it in a process context. */
cmd.key = *k;
- cmd.associd = (ni != NULL) ? ni->ni_associd : 0;
+ cmd.ni = *ni;
otus_do_async(sc, otus_set_key_cb, &cmd, sizeof cmd);
- return 0;
+ sc->sc_key_tasks++
+ return EBUSY;
}
void
@@ -2068,6 +2069,8 @@ otus_set_key_cb(struct otus_softc *sc, void *arg)
uint16_t cipher;
int error;
+ sc->sc_keys_tasks--;
+
memset(&key, 0, sizeof key);
if (k->k_flags & IEEE80211_KEY_GROUP) {
key.uid = htole16(k->k_id);
@@ -2093,18 +2096,32 @@ otus_set_key_cb(struct otus_softc *sc, void *arg)
cipher = AR_CIPHER_AES;
break;
default:
+ IEEE80211_SEND_MGMT(ic, cmd->ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
+ IEEE80211_REASON_AUTH_LEAVE);
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
return;
}
key.cipher = htole16(cipher);
memcpy(key.key, k->k_key, MIN(k->k_len, 16));
error = otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL);
- if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP)
+ if (error != 0 || k->k_cipher != IEEE80211_CIPHER_TKIP) {
+ IEEE80211_SEND_MGMT(ic, cmd->ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
+ IEEE80211_REASON_AUTH_LEAVE);
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
return;
+ }
/* TKIP: set Tx/Rx MIC Key. */
key.kix = htole16(1);
memcpy(key.key, k->k_key + 16, 16);
(void)otus_cmd(sc, AR_CMD_EKEY, &key, sizeof key, NULL);
+
+ if (sc->sc_key_tasks == 0) {
+ DPRINTF(("marking port %s valid\n",
+ ether_sprintf(cmd->ni->ni_macaddr)));
+ cmd->ni->ni_port_valid = 1;
+ ieee80211_set_link_state(ic, LINK_STATE_UP);
+ }
}
void