summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkrw <krw@openbsd.org>2020-11-12 13:31:19 +0000
committerkrw <krw@openbsd.org>2020-11-12 13:31:19 +0000
commit2362e6a47775512ed958a0f646ebf28f77abf9d3 (patch)
tree6a15c441c1542749090b4a1f6f0bb1aa1e85f36b
parentFDT-based I2C drivers should not use OF_* API in the match code, since (diff)
downloadwireguard-openbsd-2362e6a47775512ed958a0f646ebf28f77abf9d3.tar.xz
wireguard-openbsd-2362e6a47775512ed958a0f646ebf28f77abf9d3.zip
Don't enable port or link until all crypto keys are installed by
async task(s). Makes dhclient(8) much happier. Suggestions and ok stsp@, jmatthew@
-rw-r--r--sys/dev/usb/if_urtwn.c22
-rw-r--r--sys/net80211/ieee80211_pae_input.c38
2 files changed, 48 insertions, 12 deletions
diff --git a/sys/dev/usb/if_urtwn.c b/sys/dev/usb/if_urtwn.c
index 3ffaead61d1..4693ad37dca 100644
--- a/sys/dev/usb/if_urtwn.c
+++ b/sys/dev/usb/if_urtwn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_urtwn.c,v 1.94 2020/11/10 11:19:37 stsp Exp $ */
+/* $OpenBSD: if_urtwn.c,v 1.95 2020/11/12 13:31:19 krw Exp $ */
/*-
* Copyright (c) 2010 Damien Bergamini <damien.bergamini@free.fr>
@@ -216,6 +216,7 @@ struct urtwn_softc {
#define sc_txtap sc_txtapu.th
int sc_txtap_len;
#endif
+ int sc_key_tasks;
};
#ifdef URTWN_DEBUG
@@ -1044,7 +1045,9 @@ urtwn_set_key(struct ieee80211com *ic, struct ieee80211_node *ni,
cmd.key = *k;
cmd.ni = ni;
urtwn_do_async(sc, urtwn_set_key_cb, &cmd, sizeof(cmd));
- return (0);
+ sc->sc_key_tasks++;
+
+ return (EBUSY);
}
void
@@ -1053,7 +1056,20 @@ urtwn_set_key_cb(struct urtwn_softc *sc, void *arg)
struct ieee80211com *ic = &sc->sc_sc.sc_ic;
struct urtwn_cmd_key *cmd = arg;
- rtwn_set_key(ic, cmd->ni, &cmd->key);
+ sc->sc_key_tasks--;
+
+ if (rtwn_set_key(ic, cmd->ni, &cmd->key) == 0) {
+ 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);
+ }
+ } else {
+ IEEE80211_SEND_MGMT(ic, cmd->ni, IEEE80211_FC0_SUBTYPE_DEAUTH,
+ IEEE80211_REASON_AUTH_LEAVE);
+ ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+ }
}
void
diff --git a/sys/net80211/ieee80211_pae_input.c b/sys/net80211/ieee80211_pae_input.c
index d8982de8563..06d8767ab69 100644
--- a/sys/net80211/ieee80211_pae_input.c
+++ b/sys/net80211/ieee80211_pae_input.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211_pae_input.c,v 1.35 2020/07/13 08:26:26 stsp Exp $ */
+/* $OpenBSD: ieee80211_pae_input.c,v 1.36 2020/11/12 13:31:19 krw Exp $ */
/*-
* Copyright (c) 2007,2008 Damien Bergamini <damien.bergamini@free.fr>
@@ -366,7 +366,7 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
const u_int8_t *frm, *efrm;
const u_int8_t *rsnie1, *rsnie2, *gtk, *igtk;
u_int16_t info, reason = 0;
- int keylen;
+ int keylen, deferlink = 0;
#ifndef IEEE80211_STA_ONLY
if (ic->ic_opmode != IEEE80211_M_STA &&
@@ -565,7 +565,13 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
k->k_len = keylen;
memcpy(k->k_key, ni->ni_ptk.tk, k->k_len);
/* install the PTK */
- if ((*ic->ic_set_key)(ic, ni, k) != 0) {
+ switch ((*ic->ic_set_key)(ic, ni, k)) {
+ case 0:
+ break;
+ case EBUSY:
+ deferlink = 1;
+ break;
+ default:
reason = IEEE80211_REASON_AUTH_LEAVE;
goto deauth;
}
@@ -599,7 +605,13 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
k->k_len = keylen;
memcpy(k->k_key, &gtk[8], k->k_len);
/* install the GTK */
- if ((*ic->ic_set_key)(ic, ni, k) != 0) {
+ switch ((*ic->ic_set_key)(ic, ni, k)) {
+ case 0:
+ break;
+ case EBUSY:
+ deferlink = 1;
+ break;
+ default:
reason = IEEE80211_REASON_AUTH_LEAVE;
goto deauth;
}
@@ -630,7 +642,13 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
k->k_len = 16;
memcpy(k->k_key, &igtk[14], k->k_len);
/* install the IGTK */
- if ((*ic->ic_set_key)(ic, ni, k) != 0) {
+ switch ((*ic->ic_set_key)(ic, ni, k)) {
+ case 0:
+ break;
+ case EBUSY:
+ deferlink = 1;
+ break;
+ default:
reason = IEEE80211_REASON_AUTH_LEAVE;
goto deauth;
}
@@ -646,10 +664,12 @@ ieee80211_recv_4way_msg3(struct ieee80211com *ic,
++ni->ni_key_count == 2)
#endif
{
- DPRINTF(("marking port %s valid\n",
- ether_sprintf(ni->ni_macaddr)));
- ni->ni_port_valid = 1;
- ieee80211_set_link_state(ic, LINK_STATE_UP);
+ if (deferlink == 0) {
+ DPRINTF(("marking port %s valid\n",
+ ether_sprintf(ni->ni_macaddr)));
+ ni->ni_port_valid = 1;
+ ieee80211_set_link_state(ic, LINK_STATE_UP);
+ }
ni->ni_assoc_fail = 0;
if (ic->ic_opmode == IEEE80211_M_STA)
ic->ic_rsngroupcipher = ni->ni_rsngroupcipher;