[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!
This commit is contained in:
Adrian Chadd 2017-05-20 00:43:52 +00:00
parent 9a1452026e
commit 85c4e67075
8 changed files with 14 additions and 12 deletions

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */

View File

@ -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 *);

View File

@ -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)

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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;
}