From: stsp Date: Wed, 8 May 2024 14:02:59 +0000 (+0000) Subject: disable the regular ieee80211_encap() Tx path in monitor mode X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=a12575e0295a54e1b2c6849eb09458062d1d5df7;p=openbsd disable the regular ieee80211_encap() Tx path in monitor mode Frames injected from user space carry the DLT_IEEE802_11_RADIO mbuf tag, and are handled as a special case. Do not fall back to regular encapsulation while we are in monitor mode and the frame injected by userspace is found to be invalid. This fixes an issue when iwx(4) runs in monitor mode with addresses configured on the interface and leaving 11n/11ac mode directly for monitor mode. In this case, traffic generated by userspace or the kernel (such as ICMPv6) would trigger Tx attempts, which in turn would trigger an attempt to set up a block ACK agreement and then cause a firmware panic. This points at a related issue where interface configuration state is not properly cleaned up while switching into monitor mode. The 11n/11ac interface config should ideally be cleared completely, preventing block ack from being initiated. But preventing the stack from trying to send frames down the regular Tx path in monitor mode is a good idea in general because drivers may not handle this very well for various reasons, block ack being just one. tested by jmc@ and myself on iwx ax200 --- diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index a6161bf8e42..554083bb31e 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ieee80211_output.c,v 1.138 2024/04/14 03:26:25 jsg Exp $ */ +/* $OpenBSD: ieee80211_output.c,v 1.139 2024/05/08 14:02:59 stsp Exp $ */ /* $NetBSD: ieee80211_output.c,v 1.13 2004/05/31 11:02:55 dyoung Exp $ */ /*- @@ -569,6 +569,9 @@ ieee80211_encap(struct ifnet *ifp, struct mbuf *m, struct ieee80211_node **pni) } fallback: + if (ic->ic_opmode == IEEE80211_M_MONITOR) + goto bad; + if (m->m_len < sizeof(struct ether_header)) { m = m_pullup(m, sizeof(struct ether_header)); if (m == NULL) {