svn commit: r282820 - head/sys/net80211

Adrian Chadd adrian at FreeBSD.org
Tue May 12 16:55:53 UTC 2015


Author: adrian
Date: Tue May 12 16:55:50 2015
New Revision: 282820
URL: https://svnweb.freebsd.org/changeset/base/282820

Log:
  Do not check sequence number for QoS Null frames; set it for generated QoS Null
  frames to 0
  
  From IEEE Std. 802.11-2012, 8.3.2.1 "Data frame format", p. 415 (513):
  "The Sequence Control field for QoS (+)Null frames is ignored by the receiver
  upon reception."
  
  At this moment, any <mode>_input() function interprets them as regular QoS data
  frames with TID = 0. As a result, stations, that use another TX sequence for
  QoS Null frames (e.g. wpi(4), where (QoS) Null frames are generated by the
  firmware), may experience significant packet loss with any other NIC in hostap
  mode.
  
  Tested:
  
  * wpi(4) (author)
  * iwn(4) - Intel 5100, STA mode (me)
  
  PR:		kern/200128
  Submitted by:	Andriy Voskoboinyk <s3erios at gmail.com>

Modified:
  head/sys/net80211/ieee80211.h
  head/sys/net80211/ieee80211_adhoc.c
  head/sys/net80211/ieee80211_hostap.c
  head/sys/net80211/ieee80211_input.h
  head/sys/net80211/ieee80211_output.c
  head/sys/net80211/ieee80211_sta.c
  head/sys/net80211/ieee80211_wds.c

Modified: head/sys/net80211/ieee80211.h
==============================================================================
--- head/sys/net80211/ieee80211.h	Tue May 12 16:36:54 2015	(r282819)
+++ head/sys/net80211/ieee80211.h	Tue May 12 16:55:50 2015	(r282820)
@@ -169,6 +169,11 @@ struct ieee80211_qosframe_addr4 {
 #define	IEEE80211_FC1_PROTECTED			0x40
 #define	IEEE80211_FC1_ORDER			0x80
 
+#define IEEE80211_HAS_SEQ(type, subtype) \
+	((type) != IEEE80211_FC0_TYPE_CTL && \
+	!((type) == IEEE80211_FC0_TYPE_DATA && \
+	 ((subtype) & IEEE80211_FC0_SUBTYPE_QOS_NULL) == \
+		      IEEE80211_FC0_SUBTYPE_QOS_NULL))
 #define	IEEE80211_SEQ_FRAG_MASK			0x000f
 #define	IEEE80211_SEQ_FRAG_SHIFT		0
 #define	IEEE80211_SEQ_SEQ_MASK			0xfff0

Modified: head/sys/net80211/ieee80211_adhoc.c
==============================================================================
--- head/sys/net80211/ieee80211_adhoc.c	Tue May 12 16:36:54 2015	(r282819)
+++ head/sys/net80211/ieee80211_adhoc.c	Tue May 12 16:55:50 2015	(r282820)
@@ -291,7 +291,6 @@ doprint(struct ieee80211vap *vap, int su
 static int
 adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 {
-#define	HAS_SEQ(type)	((type & 0x4) == 0)
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
 	struct ifnet *ifp = vap->iv_ifp;
@@ -414,7 +413,8 @@ adhoc_input(struct ieee80211_node *ni, s
 		}
 		IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
 		ni->ni_noise = nf;
-		if (HAS_SEQ(type) && IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
+		if (IEEE80211_HAS_SEQ(type, subtype) &&
+		    IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr)) {
 			uint8_t tid = ieee80211_gettid(wh);
 			if (IEEE80211_QOS_HAS_SEQ(wh) &&
 			    TID_TO_WME_AC(tid) >= WME_AC_VI)

Modified: head/sys/net80211/ieee80211_hostap.c
==============================================================================
--- head/sys/net80211/ieee80211_hostap.c	Tue May 12 16:36:54 2015	(r282819)
+++ head/sys/net80211/ieee80211_hostap.c	Tue May 12 16:55:50 2015	(r282820)
@@ -478,7 +478,6 @@ doprint(struct ieee80211vap *vap, int su
 static int
 hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 {
-#define	HAS_SEQ(type)	((type & 0x4) == 0)
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
 	struct ifnet *ifp = vap->iv_ifp;
@@ -571,7 +570,7 @@ hostap_input(struct ieee80211_node *ni, 
 
 		IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
 		ni->ni_noise = nf;
-		if (HAS_SEQ(type)) {
+		if (IEEE80211_HAS_SEQ(type, subtype)) {
 			uint8_t tid = ieee80211_gettid(wh);
 			if (IEEE80211_QOS_HAS_SEQ(wh) &&
 			    TID_TO_WME_AC(tid) >= WME_AC_VI)

Modified: head/sys/net80211/ieee80211_input.h
==============================================================================
--- head/sys/net80211/ieee80211_input.h	Tue May 12 16:36:54 2015	(r282819)
+++ head/sys/net80211/ieee80211_input.h	Tue May 12 16:55:50 2015	(r282820)
@@ -168,19 +168,22 @@ ieee80211_check_rxseq(struct ieee80211_n
 {
 #define	SEQ_LEQ(a,b)	((int)((a)-(b)) <= 0)
 #define	SEQ_EQ(a,b)	((int)((a)-(b)) == 0)
-#define	HAS_SEQ(type)	((type & 0x4) == 0)
 #define	SEQNO(a)	((a) >> IEEE80211_SEQ_SEQ_SHIFT)
 #define	FRAGNO(a)	((a) & IEEE80211_SEQ_FRAG_MASK)
 	uint16_t rxseq;
-	uint8_t type;
+	uint8_t type, subtype;
 	uint8_t tid;
 	struct ieee80211_rx_ampdu *rap;
 
 	rxseq = le16toh(*(uint16_t *)wh->i_seq);
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
+	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 
-	/* Types with no sequence number are always treated valid */
-	if (! HAS_SEQ(type))
+	/*
+	 * Types with no sequence number (or QoS (+)Null frames)
+	 * are always treated valid.
+	 */
+	if (! IEEE80211_HAS_SEQ(type, subtype))
 		return 1;
 
 	tid = ieee80211_gettid(wh);
@@ -235,7 +238,6 @@ ieee80211_check_rxseq(struct ieee80211_n
 	return 1;
 #undef	SEQ_LEQ
 #undef	SEQ_EQ
-#undef	HAS_SEQ
 #undef	SEQNO
 #undef	FRAGNO
 }

Modified: head/sys/net80211/ieee80211_output.c
==============================================================================
--- head/sys/net80211/ieee80211_output.c	Tue May 12 16:36:54 2015	(r282819)
+++ head/sys/net80211/ieee80211_output.c	Tue May 12 16:55:50 2015	(r282820)
@@ -730,7 +730,12 @@ ieee80211_send_setup(
 	if (tid != IEEE80211_NONQOS_TID && IEEE80211_AMPDU_RUNNING(tap))
 		m->m_flags |= M_AMPDU_MPDU;
 	else {
-		seqno = ni->ni_txseqs[tid]++;
+		if (IEEE80211_HAS_SEQ(type & IEEE80211_FC0_TYPE_MASK,
+				      type & IEEE80211_FC0_SUBTYPE_MASK))
+			seqno = ni->ni_txseqs[tid]++;
+		else
+			seqno = 0;
+
 		*(uint16_t *)&wh->i_seq[0] =
 		    htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
 		M_SEQNO_SET(m, seqno);

Modified: head/sys/net80211/ieee80211_sta.c
==============================================================================
--- head/sys/net80211/ieee80211_sta.c	Tue May 12 16:36:54 2015	(r282819)
+++ head/sys/net80211/ieee80211_sta.c	Tue May 12 16:55:50 2015	(r282820)
@@ -527,7 +527,6 @@ doprint(struct ieee80211vap *vap, int su
 static int
 sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 {
-#define	HAS_SEQ(type)	((type & 0x4) == 0)
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
 	struct ifnet *ifp = vap->iv_ifp;
@@ -623,7 +622,8 @@ sta_input(struct ieee80211_node *ni, str
 
 		IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
 		ni->ni_noise = nf;
-		if (HAS_SEQ(type) && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		if ( IEEE80211_HAS_SEQ(type, subtype) &&
+		    !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
 			uint8_t tid = ieee80211_gettid(wh);
 			if (IEEE80211_QOS_HAS_SEQ(wh) &&
 			    TID_TO_WME_AC(tid) >= WME_AC_VI)

Modified: head/sys/net80211/ieee80211_wds.c
==============================================================================
--- head/sys/net80211/ieee80211_wds.c	Tue May 12 16:36:54 2015	(r282819)
+++ head/sys/net80211/ieee80211_wds.c	Tue May 12 16:55:50 2015	(r282820)
@@ -406,7 +406,6 @@ wds_newstate(struct ieee80211vap *vap, e
 static int
 wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 {
-#define	HAS_SEQ(type)	((type & 0x4) == 0)
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
 	struct ifnet *ifp = vap->iv_ifp;
@@ -488,7 +487,7 @@ wds_input(struct ieee80211_node *ni, str
 	}
 	IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
 	ni->ni_noise = nf;
-	if (HAS_SEQ(type)) {
+	if (IEEE80211_HAS_SEQ(type, subtype)) {
 		uint8_t tid = ieee80211_gettid(wh);
 		if (IEEE80211_QOS_HAS_SEQ(wh) &&
 		    TID_TO_WME_AC(tid) >= WME_AC_VI)


More information about the svn-src-all mailing list