Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147555802
D44463.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
12 KB
Referenced Files
None
Subscribers
None
D44463.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D44463: LinuxKPI: LKPI_80211_HW_CRYPTO: add basic multi-keys support
Attached
Detach File
Event Timeline
Log In to Comment