diff options
author | 2020-11-12 13:31:19 +0000 | |
---|---|---|
committer | 2020-11-12 13:31:19 +0000 | |
commit | 2362e6a47775512ed958a0f646ebf28f77abf9d3 (patch) | |
tree | 6a15c441c1542749090b4a1f6f0bb1aa1e85f36b | |
parent | FDT-based I2C drivers should not use OF_* API in the match code, since (diff) | |
download | wireguard-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.c | 22 | ||||
-rw-r--r-- | sys/net80211/ieee80211_pae_input.c | 38 |
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, >k[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; |