aboutsummaryrefslogtreecommitdiff
path: root/sys/net80211/ieee80211_adhoc.c
diff options
context:
space:
mode:
authorAdrian Chadd <adrian@FreeBSD.org>2016-11-19 02:00:24 +0000
committerAdrian Chadd <adrian@FreeBSD.org>2016-11-19 02:00:24 +0000
commitfe75b45213a403dc13c2e8a3bef5c83fa3b8225c (patch)
tree9b6b7d0214b2ec19cbc742b5e35afe97bc895dc8 /sys/net80211/ieee80211_adhoc.c
parentc49cf11473dfae9cae91ef4267b852116d089e50 (diff)
downloadsrc-fe75b45213a403dc13c2e8a3bef5c83fa3b8225c.tar.gz
src-fe75b45213a403dc13c2e8a3bef5c83fa3b8225c.zip
[net80211] handle hardware encryption offload in the receive path
* teach the crypto modules about receive offload - although I have to do some further reviewing in places where we /can't/ have an RX key * teach the RX data path about receive offload encryption - check the flag, handle NULL key, do decap and checking as appropriate. Tested: * iwn(4), STA mode * ath(4), STA and AP mode * ath10k port, STA mode (hardware encryption) Reviewed by: avos Differential Revision: https://reviews.freebsd.org/D8533
Notes
Notes: svn path=/head/; revision=308823
Diffstat (limited to 'sys/net80211/ieee80211_adhoc.c')
-rw-r--r--sys/net80211/ieee80211_adhoc.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c
index 54cc570b5f8d..f32892651e4e 100644
--- a/sys/net80211/ieee80211_adhoc.c
+++ b/sys/net80211/ieee80211_adhoc.c
@@ -316,6 +316,16 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
int hdrspace, need_tap = 1; /* mbuf need to be tapped. */
uint8_t dir, type, subtype, qos;
uint8_t *bssid;
+ int is_hw_decrypted = 0;
+ int has_decrypted = 0;
+
+ /*
+ * Some devices do hardware decryption all the way through
+ * to pretending the frame wasn't encrypted in the first place.
+ * So, tag it appropriately so it isn't discarded inappropriately.
+ */
+ if ((rxs != NULL) && (rxs->c_pktflags & IEEE80211_RX_F_DECRYPTED))
+ is_hw_decrypted = 1;
if (m->m_flags & M_AMPDU_MPDU) {
/*
@@ -479,7 +489,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
* crypto cipher modules used to do delayed update
* of replay sequence numbers.
*/
- if (wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
+ if (is_hw_decrypted || wh->i_fc[1] & IEEE80211_FC1_PROTECTED) {
if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) {
/*
* Discard encrypted frames when privacy is off.
@@ -490,14 +500,14 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
IEEE80211_NODE_STAT(ni, rx_noprivacy);
goto out;
}
- key = ieee80211_crypto_decap(ni, m, hdrspace);
- if (key == NULL) {
+ if (ieee80211_crypto_decap(ni, m, hdrspace, &key) == 0) {
/* NB: stats+msgs handled in crypto_decap */
IEEE80211_NODE_STAT(ni, rx_wepfail);
goto out;
}
wh = mtod(m, struct ieee80211_frame *);
wh->i_fc[1] &= ~IEEE80211_FC1_PROTECTED;
+ has_decrypted = 1;
} else {
/* XXX M_WEP and IEEE80211_F_PRIVACY */
key = NULL;
@@ -528,7 +538,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
/*
* Next strip any MSDU crypto bits.
*/
- if (key != NULL && !ieee80211_crypto_demic(vap, key, m, 0)) {
+ if (!ieee80211_crypto_demic(vap, key, m, 0)) {
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
ni->ni_macaddr, "data", "%s", "demic error");
vap->iv_stats.is_rx_demicfail++;
@@ -582,7 +592,8 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m,
* any non-PAE frames received without encryption.
*/
if ((vap->iv_flags & IEEE80211_F_DROPUNENC) &&
- (key == NULL && (m->m_flags & M_WEP) == 0) &&
+ ((has_decrypted == 0) && (m->m_flags & M_WEP) == 0) &&
+ (is_hw_decrypted == 0) &&
eh->ether_type != htons(ETHERTYPE_PAE)) {
/*
* Drop unencrypted frames.