From 85c4e67075a5e814710497d55fa6b283155f069f Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Sat, 20 May 2017 00:43:52 +0000 Subject: [PATCH] [net80211] prepare for A-MSDU/A-MPDU offload crypto / sequence number checking. When doing AMSDU offload, the driver (for now!) presents 802.11 frames with the same sequence number and crypto sequence number / IV values up to the stack. But, this will trip afoul over the sequence number detection. So drivers now have a way to signify that a frame is part of an offloaded AMSDU group, so we can just ensure that we pass those frames up to the stack. The logic will be a bit messy - the TL;DR will be that if it's part of the previously seen sequence number then it belongs in the same burst. But if we get a repeat of the same sequence number (eg we sent an ACK but the receiver didn't hear it) then we shouldn't be passing those frames up. So, we can't just say "all subframes go up", we need to track whether we've seen the end of a burst of frames for the given sequence number or not, so we know whether to actually pass them up or not. The first part of doing all of this is to ensure the ieee80211_rx_stats struct is available in the RX sequence number check path and the RX ampdu reorder path. So, start by passing the pointer into these functions to avoid doing another lookup. The actual support will come in a subsequent commit once I know the functionality actually works! --- sys/net80211/ieee80211_adhoc.c | 4 ++-- sys/net80211/ieee80211_hostap.c | 4 ++-- sys/net80211/ieee80211_ht.c | 3 ++- sys/net80211/ieee80211_ht.h | 3 ++- sys/net80211/ieee80211_input.h | 2 +- sys/net80211/ieee80211_mesh.c | 2 +- sys/net80211/ieee80211_sta.c | 4 ++-- sys/net80211/ieee80211_wds.c | 4 ++-- 8 files changed, 14 insertions(+), 12 deletions(-) diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c index 6d26f85b56b..ebb2a246e11 100644 --- a/sys/net80211/ieee80211_adhoc.c +++ b/sys/net80211/ieee80211_adhoc.c @@ -448,7 +448,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, bssid)) + if (! ieee80211_check_rxseq(ni, wh, bssid, rxs)) goto out; } } @@ -479,7 +479,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, * and we should do nothing more with it. */ if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; } diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 40680b1c101..f5361ddc098 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -577,7 +577,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, bssid)) + if (! ieee80211_check_rxseq(ni, wh, bssid, rxs)) goto out; } } @@ -665,7 +665,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, * and we should do nothing more with it. */ if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; } diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 543bd4e608a..0db03f67412 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -849,7 +849,8 @@ ampdu_rx_flush_upto(struct ieee80211_node *ni, * the frame should be processed normally by the caller. */ int -ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m) +ieee80211_ampdu_reorder(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_rx_stats *rxs) { #define PROCESS 0 /* caller should process frame */ #define CONSUMED 1 /* frame consumed, caller does nothing */ diff --git a/sys/net80211/ieee80211_ht.h b/sys/net80211/ieee80211_ht.h index 5b818a28b71..b85e1c9a99e 100644 --- a/sys/net80211/ieee80211_ht.h +++ b/sys/net80211/ieee80211_ht.h @@ -185,7 +185,8 @@ int ieee80211_setup_htrates(struct ieee80211_node *, void ieee80211_setup_basic_htrates(struct ieee80211_node *, const uint8_t *htinfo); struct mbuf *ieee80211_decap_amsdu(struct ieee80211_node *, struct mbuf *); -int ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *); +int ieee80211_ampdu_reorder(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_rx_stats *); void ieee80211_recv_bar(struct ieee80211_node *, struct mbuf *); void ieee80211_ht_node_init(struct ieee80211_node *); void ieee80211_ht_node_cleanup(struct ieee80211_node *); diff --git a/sys/net80211/ieee80211_input.h b/sys/net80211/ieee80211_input.h index 0ae8dd08df4..cff07c68e9c 100644 --- a/sys/net80211/ieee80211_input.h +++ b/sys/net80211/ieee80211_input.h @@ -158,7 +158,7 @@ ishtinfooui(const uint8_t *frm) */ static __inline int ieee80211_check_rxseq(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *bssid) + uint8_t *bssid, const struct ieee80211_rx_stats *rxs) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define SEQ_EQ(a,b) ((int)((a)-(b)) == 0) diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index c8e69b74238..1b6ff3c089c 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -1580,7 +1580,7 @@ mesh_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1)) + if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1, rxs)) goto out; } } diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index cebfa1e303b..27bb290b0f0 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -648,7 +648,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, bssid)) + if (! ieee80211_check_rxseq(ni, wh, bssid, rxs)) goto out; } } @@ -673,7 +673,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, if ((m->m_flags & M_AMPDU) && (dir == IEEE80211_FC1_DIR_FROMDS || dir == IEEE80211_FC1_DIR_DSTODS) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; } diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c index 038f41292ed..e445bfed8b9 100644 --- a/sys/net80211/ieee80211_wds.c +++ b/sys/net80211/ieee80211_wds.c @@ -504,7 +504,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, if (IEEE80211_QOS_HAS_SEQ(wh) && TID_TO_WME_AC(tid) >= WME_AC_VI) ic->ic_wme.wme_hipri_traffic++; - if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1)) + if (! ieee80211_check_rxseq(ni, wh, wh->i_addr1, rxs)) goto out; } switch (type) { @@ -540,7 +540,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, * and we should do nothing more with it. */ if ((m->m_flags & M_AMPDU) && - ieee80211_ampdu_reorder(ni, m) != 0) { + ieee80211_ampdu_reorder(ni, m, rxs) != 0) { m = NULL; goto out; }