Page MenuHomeFreeBSD

D44463.diff
No OneTemporary

D44463.diff

diff --git a/sys/compat/linuxkpi/common/src/linux_80211.h b/sys/compat/linuxkpi/common/src/linux_80211.h
--- a/sys/compat/linuxkpi/common/src/linux_80211.h
+++ b/sys/compat/linuxkpi/common/src/linux_80211.h
@@ -1,7 +1,10 @@
/*-
- * Copyright (c) 2020-2023 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
* Copyright (c) 2020-2021 Bjoern A. Zeeb
*
+ * Portions of this software were developed by Cheng Cui
+ * <cc@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
+ *
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
*
@@ -61,6 +64,7 @@
#define D80211_TRACEX (D80211_TRACE_TX|D80211_TRACE_RX)
#define D80211_TRACEX_DUMP (D80211_TRACE_TX_DUMP|D80211_TRACE_RX_DUMP)
#define D80211_TRACE_STA 0x00010000
+#define D80211_TRACE_CRYPTO 0x00020000
#define D80211_TRACE_MO 0x00100000
#define D80211_TRACE_MODE 0x0f000000
#define D80211_TRACE_MODE_HT 0x01000000
@@ -144,7 +148,7 @@
struct mbufq txq;
struct mtx txq_mtx;
- struct ieee80211_key_conf *kc;
+ struct ieee80211_key_conf *kc[IEEE80211_WEP_NKID];
enum ieee80211_sta_state state;
bool txq_ready; /* Can we run the taskq? */
bool added_to_drv; /* Driver knows; i.e. we called ...(). */
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -1,6 +1,9 @@
/*-
- * Copyright (c) 2020-2023 The FreeBSD Foundation
- * Copyright (c) 2020-2022 Bjoern A. Zeeb
+ * Copyright (c) 2020-2024 The FreeBSD Foundation
+ * Copyright (c) 2020-2024 Bjoern A. Zeeb
+ *
+ * Portions of this software were developed by Cheng Cui
+ * <cc@FreeBSD.org> under sponsorship from the FreeBSD Foundation.
*
* This software was developed by Björn Zeeb under sponsorship from
* the FreeBSD Foundation.
@@ -102,9 +105,15 @@
printf("XXX-TODO %s:%d: UNIMPLEMENTED\n", __func__, __LINE__)
#define TRACEOK() if (linuxkpi_debug_80211 & D80211_TRACEOK) \
printf("XXX-TODO %s:%d: TRACEPOINT\n", __func__, __LINE__)
+
+#define LKPI_80211_TRACE_CRYPTO(fmt, ...) \
+ if (linuxkpi_debug_80211 & D80211_TRACE_CRYPTO) \
+ printf("LKPI_80211_TRACE_CRYPTO %s:%d: " fmt "\n", \
+ __func__, __LINE__, __VA_ARGS__)
#else
#define UNIMPLEMENTED do { } while (0)
#define TRACEOK() do { } while (0)
+#define LKPI_80211_TRACE_CRYPTO(...) do { } while(0)
#endif
/* #define PREP_TX_INFO_DURATION (IEEE80211_TRANS_WAIT * 1000) */
@@ -544,12 +553,20 @@
switch (wlan_cipher_suite) {
case WLAN_CIPHER_SUITE_WEP40:
+ LKPI_80211_TRACE_CRYPTO("supported WLAN Cipher Suite %#08x | %u",
+ wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff);
return (IEEE80211_CRYPTO_WEP);
case WLAN_CIPHER_SUITE_TKIP:
+ LKPI_80211_TRACE_CRYPTO("supported WLAN Cipher Suite %#08x | %u",
+ wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff);
return (IEEE80211_CRYPTO_TKIP);
case WLAN_CIPHER_SUITE_CCMP:
+ LKPI_80211_TRACE_CRYPTO("supported WLAN Cipher Suite %#08x | %u",
+ wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff);
return (IEEE80211_CRYPTO_AES_CCM);
case WLAN_CIPHER_SUITE_WEP104:
+ LKPI_80211_TRACE_CRYPTO("supported WLAN Cipher Suite %#08x | %u",
+ wlan_cipher_suite >> 8, wlan_cipher_suite & 0xff);
return (IEEE80211_CRYPTO_WEP);
case WLAN_CIPHER_SUITE_AES_CMAC:
case WLAN_CIPHER_SUITE_GCMP:
@@ -575,10 +592,13 @@
switch (cipher) {
case IEEE80211_CIPHER_TKIP:
+ LKPI_80211_TRACE_CRYPTO("supported Cipher %#x", cipher);
return (WLAN_CIPHER_SUITE_TKIP);
case IEEE80211_CIPHER_AES_CCM:
+ LKPI_80211_TRACE_CRYPTO("supported Cipher %#x", cipher);
return (WLAN_CIPHER_SUITE_CCMP);
case IEEE80211_CIPHER_WEP:
+ LKPI_80211_TRACE_CRYPTO("supported Cipher %#x", cipher);
if (keylen < 8)
return (WLAN_CIPHER_SUITE_WEP40);
else
@@ -708,20 +728,76 @@
#ifdef LKPI_80211_HW_CRYPTO
static int
-_lkpi_iv_key_set_delete(struct ieee80211vap *vap, const struct ieee80211_key *k,
- enum set_key_cmd cmd)
+_lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
struct ieee80211com *ic;
struct lkpi_hw *lhw;
struct ieee80211_hw *hw;
struct lkpi_vif *lvif;
+ struct lkpi_sta *lsta;
struct ieee80211_vif *vif;
- struct ieee80211_sta *sta;
struct ieee80211_node *ni;
- struct ieee80211_key_conf *kc;
+ struct ieee80211_key_conf *kcf;
int error;
- /* XXX TODO Check (k->wk_flags & IEEE80211_KEY_SWENCRYPT) and don't upload to driver/hw? */
+ ic = vap->iv_ic;
+ lhw = ic->ic_softc;
+ hw = LHW_TO_HW(lhw);
+ lvif = VAP_TO_LVIF(vap);
+ vif = LVIF_TO_VIF(lvif);
+
+ ni = ieee80211_ref_node(vap->iv_bss);
+ KASSERT(ni->ni_drv_data != NULL, ("%s: ni %p ni_drv_data %p\n",
+ __func__, ni, ni->ni_drv_data));
+ lsta = ni->ni_drv_data;
+
+ if (lsta->kc[k->wk_keyix] == NULL) {
+ LKPI_80211_TRACE_CRYPTO("sta %6D and no key information on "
+ "keyidx %u, returning success", ni->ni_bssid, ":",
+ k->wk_keyix);
+ return (1);
+ }
+ kcf = lsta->kc[k->wk_keyix];
+
+ error = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif, LSTA_TO_STA(lsta),
+ kcf);
+ if (error != 0) {
+ ic_printf(ic, "%s: set_key cmd %d(%s) for sta %6D failed: %d\n",
+ __func__, DISABLE_KEY, "DISABLE", ni->ni_bssid, ":", error);
+ return (0);
+ }
+
+ LKPI_80211_TRACE_CRYPTO("set_key cmd %d(%s) for sta %6D succeeded: "
+ "keyidx %u hw_key_idx %u flags %#x", DISABLE_KEY, "DISABLE",
+ ni->ni_bssid, ":", kcf->keyidx, kcf->hw_key_idx, kcf->flags);
+
+ free(lsta->kc[k->wk_keyix], M_LKPI80211);
+ lsta->kc[k->wk_keyix] = NULL;
+ kcf = NULL;
+ return (1);
+}
+
+static int
+lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
+{
+
+ /* XXX-BZ one day we should replace this iterating over VIFs, or node list? */
+ return (_lkpi_iv_key_delete(vap, k));
+}
+
+static int
+_lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
+{
+ struct ieee80211com *ic;
+ struct lkpi_hw *lhw;
+ struct ieee80211_hw *hw;
+ struct lkpi_vif *lvif;
+ struct lkpi_sta *lsta;
+ struct ieee80211_vif *vif;
+ struct ieee80211_node *ni;
+ struct ieee80211_key_conf *kcf;
+ uint32_t lcipher;
+ int error;
ic = vap->iv_ic;
lhw = ic->ic_softc;
@@ -729,65 +805,80 @@
lvif = VAP_TO_LVIF(vap);
vif = LVIF_TO_VIF(lvif);
- memset(&kc, 0, sizeof(kc));
- kc = malloc(sizeof(*kc) + k->wk_keylen, M_LKPI80211, M_WAITOK | M_ZERO);
- kc->cipher = lkpi_net80211_to_l80211_cipher_suite(
- k->wk_cipher->ic_cipher, k->wk_keylen);
- kc->keyidx = k->wk_keyix;
-#if 0
- kc->hw_key_idx = /* set by hw and needs to be passed for TX */;
-#endif
- atomic64_set(&kc->tx_pn, k->wk_keytsc);
- kc->keylen = k->wk_keylen;
- memcpy(kc->key, k->wk_key, k->wk_keylen);
+ ni = ieee80211_ref_node(vap->iv_bss);
+ kcf = NULL;
+
+ KASSERT(ni->ni_drv_data != NULL, ("%s: ni %p ni_drv_data %p\n",
+ __func__, ni, ni->ni_drv_data));
+ lsta = ni->ni_drv_data;
+
+ if (lsta->kc[k->wk_keyix] != NULL) {
+ IMPROVE("Still in firmware? Del first. Can we assert this cannot happen?");
+ LKPI_80211_TRACE_CRYPTO("sta %6D found with key information", ni->ni_bssid, ":");
- switch (kc->cipher) {
+ free(lsta->kc[k->wk_keyix], M_LKPI80211);
+ lsta->kc[k->wk_keyix] = NULL; /* safeguard */
+ }
+
+ lcipher = lkpi_net80211_to_l80211_cipher_suite(k->wk_cipher->ic_cipher,
+ k->wk_keylen);
+ kcf = malloc(sizeof(*kcf) + k->wk_keylen, M_LKPI80211, M_WAITOK | M_ZERO);
+
+ if (kcf == NULL) {
+ return (0);
+ }
+ switch (lcipher) {
case WLAN_CIPHER_SUITE_CCMP:
- kc->iv_len = k->wk_cipher->ic_header;
- kc->icv_len = k->wk_cipher->ic_trailer;
+ kcf->iv_len = k->wk_cipher->ic_header;
+ kcf->icv_len = k->wk_cipher->ic_trailer;
break;
case WLAN_CIPHER_SUITE_TKIP:
default:
+ LKPI_80211_TRACE_CRYPTO("CIPHER SUITE %#x not supported", lcipher);
IMPROVE();
return (0);
- };
-
- ni = vap->iv_bss;
- sta = ieee80211_find_sta(vif, ni->ni_bssid);
- if (sta != NULL) {
- struct lkpi_sta *lsta;
+ }
- lsta = STA_TO_LSTA(sta);
- lsta->kc = kc;
+ kcf->cipher = lcipher;
+ kcf->keyidx = k->wk_keyix;
+ if (!IEEE80211_IS_MULTICAST(k->wk_macaddr)) {
+ kcf->flags = IEEE80211_KEY_FLAG_PAIRWISE;
}
+ kcf->link_id = -1;
+#if 0
+ kcf->hw_key_idx = /* set by hw and needs to be passed for TX */;
+#endif
+ atomic64_set(&kcf->tx_pn, k->wk_keytsc);
+ kcf->keylen = k->wk_keylen;
+ memcpy(kcf->key, k->wk_key, k->wk_keylen);
- error = lkpi_80211_mo_set_key(hw, cmd, vif, sta, kc);
+ error = lkpi_80211_mo_set_key(hw, SET_KEY, vif, LSTA_TO_STA(lsta), kcf);
if (error != 0) {
- /* XXX-BZ leaking kc currently */
- ic_printf(ic, "%s: set_key failed: %d\n", __func__, error);
+ LKPI_80211_TRACE_CRYPTO("set_key cmd %d(%s) for sta %6D failed: %d",
+ SET_KEY, "SET", ni->ni_bssid, ":", error);
return (0);
- } else {
- ic_printf(ic, "%s: set_key succeeded: keyidx %u hw_key_idx %u "
- "flags %#10x\n", __func__,
- kc->keyidx, kc->hw_key_idx, kc->flags);
- return (1);
}
-}
-static int
-lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k)
-{
+ LKPI_80211_TRACE_CRYPTO("set_key cmd %d(%s) for sta %6D succeeded: "
+ "kcf %p keyidx %u hw_key_idx %u flags %#x", SET_KEY, "SET",
+ ni->ni_bssid, ":", kcf, kcf->keyidx, kcf->hw_key_idx, kcf->flags);
- /* XXX-BZ one day we should replace this iterating over VIFs, or node list? */
- return (_lkpi_iv_key_set_delete(vap, k, DISABLE_KEY));
+ lsta->kc[k->wk_keyix] = kcf;
+
+#if 0
+ /* Make sure we get the delete callback? */
+ k->wk_flags |= IEEE80211_KEY_DEVKEY;
+#endif
+ return (1);
}
+
static int
lkpi_iv_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k)
{
- return (_lkpi_iv_key_set_delete(vap, k, SET_KEY));
+ return (_lkpi_iv_key_set(vap, k));
}
-#endif
+#endif /* LKPI_80211_HW_CRYPTO */
static u_int
lkpi_ic_update_mcast_copy(void *arg, struct sockaddr_dl *sdl, u_int cnt)
@@ -3572,9 +3663,7 @@
lkpi_80211_txq_tx_one(struct lkpi_sta *lsta, struct mbuf *m)
{
struct ieee80211_node *ni;
-#ifndef LKPI_80211_HW_CRYPTO
struct ieee80211_frame *wh;
-#endif
struct ieee80211_key *k;
struct sk_buff *skb;
struct ieee80211com *ic;
@@ -3598,10 +3687,10 @@
#endif
ni = lsta->ni;
+ wh = mtod(m, struct ieee80211_frame *);
k = NULL;
#ifndef LKPI_80211_HW_CRYPTO
/* Encrypt the frame if need be; XXX-BZ info->control.hw_key. */
- wh = mtod(m, struct ieee80211_frame *);
if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
/* Retrieve key for TX && do software encryption. */
k = ieee80211_crypto_encap(ni, m);
@@ -3708,7 +3797,20 @@
sta = LSTA_TO_STA(lsta);
#ifdef LKPI_80211_HW_CRYPTO
- info->control.hw_key = lsta->kc;
+ if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+ k = ieee80211_crypto_get_txkey(ni, m);
+ LKPI_80211_TRACE_CRYPTO("use key %p wk_keyix %u for "
+ "mbuf %p", k, k->wk_keyix, m);
+
+ if (k != NULL && k->wk_keyix != IEEE80211_KEYIX_NONE) {
+ LKPI_80211_TRACE_CRYPTO("use lsta->kc[%u]:%p to "
+ "control.hw_key for mbuf %p", k->wk_keyix,
+ lsta->kc[k->wk_keyix], m);
+ info->control.hw_key = lsta->kc[k->wk_keyix];
+ } else {
+ info->control.hw_key = NULL;
+ }
+ }
#endif
IMPROVE();
@@ -5011,6 +5113,29 @@
rx_stats.c_freq = rx_status->freq;
rx_stats.c_ieee = ieee80211_mhz2ieee(rx_stats.c_freq, rx_stats.c_band);
+ /*
+ * We only need these for LKPI_80211_HW_CRYPTO in theory but in
+ * case the hardware does something we do not expect always leave
+ * these enabled. Leaving this as documentation.
+ */
+#if defined(LKPI_80211_HW_CRYPTO) || 1
+ if (rx_status->flag & RX_FLAG_DECRYPTED)
+ rx_stats.c_pktflags |= IEEE80211_RX_F_DECRYPTED;
+ if (rx_status->flag & RX_FLAG_MMIC_STRIPPED)
+ rx_stats.c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
+ if (rx_status->flag & RX_FLAG_MIC_STRIPPED) {
+ IMPROVE("WARNING: no direct mapping for RX_FLAG_MIC_STRIPPED in net80211");
+ rx_stats.c_pktflags |= IEEE80211_RX_F_MMIC_STRIP;
+ }
+ if (rx_status->flag & RX_FLAG_IV_STRIPPED)
+ rx_stats.c_pktflags |= IEEE80211_RX_F_IV_STRIP;
+ if (rx_status->flag & RX_FLAG_MMIC_ERROR)
+ rx_stats.c_pktflags |= IEEE80211_RX_F_FAIL_MIC;
+ if (rx_status->flag & RX_FLAG_FAILED_FCS_CRC)
+ rx_stats.c_pktflags |= IEEE80211_RX_F_FAIL_FCSCRC;
+ IMPROVE("map as many RX_FLAG_ -> IEEE80211_RX_F_ as possible");
+#endif
+
/* XXX (*sta_statistics)() to get to some of that? */
/* XXX-BZ dump the FreeBSD version of rx_stats as well! */

File Metadata

Mime Type
text/plain
Expires
Thu, Mar 12, 9:13 PM (5 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29595968
Default Alt Text
D44463.diff (12 KB)

Event Timeline