svn commit: r218927 - head/sys/net80211

Bernhard Schmidt bschmidt at FreeBSD.org
Mon Feb 21 19:59:44 UTC 2011


Author: bschmidt
Date: Mon Feb 21 19:59:43 2011
New Revision: 218927
URL: http://svn.freebsd.org/changeset/base/218927

Log:
  Add a new mgmt subtype "ACTION NO ACK" defined in 802.11n-2009, while here
  clean up parts of the *_recv_mgmt() functions.
  - make sure appropriate counters are bumped and debug messages are printed
  - order the unhandled subtypes by value and add a few missing ones
  - fix some whitespace nits
  - remove duplicate code in adhoc_recv_mgmt()
  - remove a useless comment, probably left in while c&p

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

Modified: head/sys/net80211/ieee80211.h
==============================================================================
--- head/sys/net80211/ieee80211.h	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211.h	Mon Feb 21 19:59:43 2011	(r218927)
@@ -131,6 +131,7 @@ struct ieee80211_qosframe_addr4 {
 #define	IEEE80211_FC0_SUBTYPE_AUTH		0xb0
 #define	IEEE80211_FC0_SUBTYPE_DEAUTH		0xc0
 #define	IEEE80211_FC0_SUBTYPE_ACTION		0xd0
+#define	IEEE80211_FC0_SUBTYPE_ACTION_NOACK	0xe0
 /* for TYPE_CTL */
 #define	IEEE80211_FC0_SUBTYPE_BAR		0x80
 #define	IEEE80211_FC0_SUBTYPE_BA		0x90

Modified: head/sys/net80211/ieee80211_adhoc.c
==============================================================================
--- head/sys/net80211/ieee80211_adhoc.c	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211_adhoc.c	Mon Feb 21 19:59:43 2011	(r218927)
@@ -823,80 +823,35 @@ adhoc_recv_mgmt(struct ieee80211_node *n
 		    is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0);
 		break;
 
-	case IEEE80211_FC0_SUBTYPE_ACTION: {
-		const struct ieee80211_action *ia;
-
-		if (vap->iv_state != IEEE80211_S_RUN) {
+	case IEEE80211_FC0_SUBTYPE_ACTION:
+	case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
+		if (vap->iv_state == IEEE80211_S_RUN) {
+			if (ieee80211_parse_action(ni, m0) == 0)
+				(void)ic->ic_recv_action(ni, wh, frm, efrm);
+		} else {
 			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
 			    wh, NULL, "wrong state %s",
 			    ieee80211_state_name[vap->iv_state]);
 			vap->iv_stats.is_rx_mgtdiscard++;
-			return;
 		}
-		/*
-		 * action frame format:
-		 *	[1] category
-		 *	[1] action
-		 *	[tlv] parameters
-		 */
-		IEEE80211_VERIFY_LENGTH(efrm - frm,
-			sizeof(struct ieee80211_action), return);
-		ia = (const struct ieee80211_action *) frm;
-
-		vap->iv_stats.is_rx_action++;
-		IEEE80211_NODE_STAT(ni, rx_action);
-
-		/* verify frame payloads but defer processing */
-		/* XXX maybe push this to method */
-		switch (ia->ia_category) {
-		case IEEE80211_ACTION_CAT_BA:
-			switch (ia->ia_action) {
-			case IEEE80211_ACTION_BA_ADDBA_REQUEST:
-				IEEE80211_VERIFY_LENGTH(efrm - frm,
-				    sizeof(struct ieee80211_action_ba_addbarequest),
-				    return);
-				break;
-			case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
-				IEEE80211_VERIFY_LENGTH(efrm - frm,
-				    sizeof(struct ieee80211_action_ba_addbaresponse),
-				    return);
-				break;
-			case IEEE80211_ACTION_BA_DELBA:
-				IEEE80211_VERIFY_LENGTH(efrm - frm,
-				    sizeof(struct ieee80211_action_ba_delba),
-				    return);
-				break;
-			}
-			break;
-		case IEEE80211_ACTION_CAT_HT:
-			switch (ia->ia_action) {
-			case IEEE80211_ACTION_HT_TXCHWIDTH:
-				IEEE80211_VERIFY_LENGTH(efrm - frm,
-				    sizeof(struct ieee80211_action_ht_txchwidth),
-				    return);
-				break;
-			}
-			break;
-		}
-		ic->ic_recv_action(ni, wh, frm, efrm);
 		break;
-	}
 
-	case IEEE80211_FC0_SUBTYPE_AUTH:
 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
-	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
+	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
-	case IEEE80211_FC0_SUBTYPE_DEAUTH:
+	case IEEE80211_FC0_SUBTYPE_ATIM:
 	case IEEE80211_FC0_SUBTYPE_DISASSOC:
+	case IEEE80211_FC0_SUBTYPE_AUTH:
+	case IEEE80211_FC0_SUBTYPE_DEAUTH:
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
-		     wh, NULL, "%s", "not handled");
+		    wh, NULL, "%s", "not handled");
 		vap->iv_stats.is_rx_mgtdiscard++;
-		return;
+		break;
 
 	default:
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
-		     wh, "mgt", "subtype 0x%x not handled", subtype);
+		    wh, "mgt", "subtype 0x%x not handled", subtype);
 		vap->iv_stats.is_rx_badsubtype++;
 		break;
 	}
@@ -910,6 +865,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211com *ic = ni->ni_ic;
+	struct ieee80211_frame *wh;
 
 	/*
 	 * Process management frames when scanning; useful for doing
@@ -917,8 +873,33 @@ ahdemo_recv_mgmt(struct ieee80211_node *
 	 */
 	if (ic->ic_flags & IEEE80211_F_SCAN)
 		adhoc_recv_mgmt(ni, m0, subtype, rssi, nf);
-	else
-		vap->iv_stats.is_rx_mgtdiscard++;
+	else {
+		wh = mtod(m0, struct ieee80211_frame *);
+		switch (subtype) {
+		case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
+		case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
+		case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
+		case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
+		case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+		case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
+		case IEEE80211_FC0_SUBTYPE_BEACON:
+		case IEEE80211_FC0_SUBTYPE_ATIM:
+		case IEEE80211_FC0_SUBTYPE_DISASSOC:
+		case IEEE80211_FC0_SUBTYPE_AUTH:
+		case IEEE80211_FC0_SUBTYPE_DEAUTH:
+		case IEEE80211_FC0_SUBTYPE_ACTION:
+		case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+			     wh, NULL, "%s", "not handled");
+			vap->iv_stats.is_rx_mgtdiscard++;
+			break;
+		default:
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
+			     wh, "mgt", "subtype 0x%x not handled", subtype);
+			vap->iv_stats.is_rx_badsubtype++;
+			break;
+		}
+	}
 }
 
 static void

Modified: head/sys/net80211/ieee80211_hostap.c
==============================================================================
--- head/sys/net80211/ieee80211_hostap.c	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211_hostap.c	Mon Feb 21 19:59:43 2011	(r218927)
@@ -2194,18 +2194,29 @@ hostap_recv_mgmt(struct ieee80211_node *
 	}
 
 	case IEEE80211_FC0_SUBTYPE_ACTION:
+	case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
 		if (vap->iv_state == IEEE80211_S_RUN) {
 			if (ieee80211_parse_action(ni, m0) == 0)
-				ic->ic_recv_action(ni, wh, frm, efrm);
-		} else
+				(void)ic->ic_recv_action(ni, wh, frm, efrm);
+		} else {
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+			    wh, NULL, "wrong state %s",
+			    ieee80211_state_name[vap->iv_state]);
 			vap->iv_stats.is_rx_mgtdiscard++;
+		}
 		break;
 
 	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
 	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
+	case IEEE80211_FC0_SUBTYPE_ATIM:
+		IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+		    wh, NULL, "%s", "not handled");
+		vap->iv_stats.is_rx_mgtdiscard++;
+		break;
+
 	default:
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
-		     wh, "mgt", "subtype 0x%x not handled", subtype);
+		    wh, "mgt", "subtype 0x%x not handled", subtype);
 		vap->iv_stats.is_rx_badsubtype++;
 		break;
 	}

Modified: head/sys/net80211/ieee80211_input.c
==============================================================================
--- head/sys/net80211/ieee80211_input.c	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211_input.c	Mon Feb 21 19:59:43 2011	(r218927)
@@ -677,7 +677,6 @@ ieee80211_parse_action(struct ieee80211_
 	IEEE80211_NODE_STAT(ni, rx_action);
 
 	/* verify frame payloads but defer processing */
-	/* XXX maybe push this to method */
 	switch (ia->ia_category) {
 	case IEEE80211_ACTION_CAT_BA:
 		switch (ia->ia_action) {

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211_mesh.c	Mon Feb 21 19:59:43 2011	(r218927)
@@ -1489,11 +1489,9 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 		ieee80211_send_proberesp(vap, wh->i_addr2, 0);
 		break;
 	}
+
 	case IEEE80211_FC0_SUBTYPE_ACTION:
-		if (vap->iv_state != IEEE80211_S_RUN) {
-			vap->iv_stats.is_rx_mgtdiscard++;
-			break;
-		}
+	case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
 		/*
 		 * We received an action for an unknown neighbor.
 		 * XXX: wait for it to beacon or create ieee80211_node?
@@ -1506,6 +1504,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 		}
 		/*
 		 * Discard if not for us.
+		 * XXX: if from us too?
 		 */
 		if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1) &&
 		    !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
@@ -1514,21 +1513,30 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 			vap->iv_stats.is_rx_mgtdiscard++;
 			break;
 		}
-		/* XXX parse_action is a bit useless now */
-		if (ieee80211_parse_action(ni, m0) == 0)
-			ic->ic_recv_action(ni, wh, frm, efrm);
+		if (vap->iv_state == IEEE80211_S_RUN) {
+			if (ieee80211_parse_action(ni, m0) == 0)
+				(void)ic->ic_recv_action(ni, wh, frm, efrm);
+		} else {
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+			    wh, NULL, "wrong state %s",
+			    ieee80211_state_name[vap->iv_state]);
+			vap->iv_stats.is_rx_mgtdiscard++;
+		}
 		break;
-	case IEEE80211_FC0_SUBTYPE_AUTH:
+
 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
-	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
+	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
-	case IEEE80211_FC0_SUBTYPE_DEAUTH:
+	case IEEE80211_FC0_SUBTYPE_ATIM:
 	case IEEE80211_FC0_SUBTYPE_DISASSOC:
+	case IEEE80211_FC0_SUBTYPE_AUTH:
+	case IEEE80211_FC0_SUBTYPE_DEAUTH:
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
 		    wh, NULL, "%s", "not handled");
 		vap->iv_stats.is_rx_mgtdiscard++;
-		return;
+		break;
+
 	default:
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
 		    wh, "mgt", "subtype 0x%x not handled", subtype);

Modified: head/sys/net80211/ieee80211_proto.c
==============================================================================
--- head/sys/net80211/ieee80211_proto.c	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211_proto.c	Mon Feb 21 19:59:43 2011	(r218927)
@@ -64,7 +64,7 @@ const char *ieee80211_mgt_subtype_name[]
 	"assoc_req",	"assoc_resp",	"reassoc_req",	"reassoc_resp",
 	"probe_req",	"probe_resp",	"reserved#6",	"reserved#7",
 	"beacon",	"atim",		"disassoc",	"auth",
-	"deauth",	"action",	"reserved#14",	"reserved#15"
+	"deauth",	"action",	"action_noack",	"reserved#15"
 };
 const char *ieee80211_ctl_subtype_name[] = {
 	"reserved#0",	"reserved#1",	"reserved#2",	"reserved#3",

Modified: head/sys/net80211/ieee80211_sta.c
==============================================================================
--- head/sys/net80211/ieee80211_sta.c	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211_sta.c	Mon Feb 21 19:59:43 2011	(r218927)
@@ -1718,21 +1718,30 @@ sta_recv_mgmt(struct ieee80211_node *ni,
 	}
 
 	case IEEE80211_FC0_SUBTYPE_ACTION:
+	case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
 		if (vap->iv_state == IEEE80211_S_RUN) {
 			if (ieee80211_parse_action(ni, m0) == 0)
-				ic->ic_recv_action(ni, wh, frm, efrm);
-		} else
+				(void)ic->ic_recv_action(ni, wh, frm, efrm);
+		} else {
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+			    wh, NULL, "wrong state %s",
+			    ieee80211_state_name[vap->iv_state]);
 			vap->iv_stats.is_rx_mgtdiscard++;
+		}
 		break;
 
-	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
+	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+	case IEEE80211_FC0_SUBTYPE_ATIM:
+		IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+		    wh, NULL, "%s", "not handled");
 		vap->iv_stats.is_rx_mgtdiscard++;
-		return;
+		break;
+
 	default:
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
-		     wh, "mgt", "subtype 0x%x not handled", subtype);
+		    wh, "mgt", "subtype 0x%x not handled", subtype);
 		vap->iv_stats.is_rx_badsubtype++;
 		break;
 	}

Modified: head/sys/net80211/ieee80211_wds.c
==============================================================================
--- head/sys/net80211/ieee80211_wds.c	Mon Feb 21 19:46:02 2011	(r218926)
+++ head/sys/net80211/ieee80211_wds.c	Mon Feb 21 19:59:43 2011	(r218927)
@@ -756,31 +756,46 @@ wds_recv_mgmt(struct ieee80211_node *ni,
 	frm = (u_int8_t *)&wh[1];
 	efrm = mtod(m0, u_int8_t *) + m0->m_len;
 	switch (subtype) {
-	case IEEE80211_FC0_SUBTYPE_DEAUTH:
-	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
-	case IEEE80211_FC0_SUBTYPE_BEACON:
-	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
-	case IEEE80211_FC0_SUBTYPE_AUTH:
+	case IEEE80211_FC0_SUBTYPE_ACTION:
+	case IEEE80211_FC0_SUBTYPE_ACTION_NOACK:
+		if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_MESH,
+			    wh, NULL, "%s", "not directed to us");
+			vap->iv_stats.is_rx_mgtdiscard++;
+			break;
+		} else
+			ni->ni_inact = ni->ni_inact_reload;
+
+		if (vap->iv_state == IEEE80211_S_RUN) {
+			if (ieee80211_parse_action(ni, m0) == 0)
+				(void)ic->ic_recv_action(ni, wh, frm, efrm);
+		} else {
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+			    wh, NULL, "wrong state %s",
+			    ieee80211_state_name[vap->iv_state]);
+			vap->iv_stats.is_rx_mgtdiscard++;
+		}
+		break;
+
 	case IEEE80211_FC0_SUBTYPE_ASSOC_REQ:
-	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_ASSOC_RESP:
+	case IEEE80211_FC0_SUBTYPE_REASSOC_REQ:
 	case IEEE80211_FC0_SUBTYPE_REASSOC_RESP:
+	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+	case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
+	case IEEE80211_FC0_SUBTYPE_BEACON:
+	case IEEE80211_FC0_SUBTYPE_ATIM:
 	case IEEE80211_FC0_SUBTYPE_DISASSOC:
+	case IEEE80211_FC0_SUBTYPE_AUTH:
+	case IEEE80211_FC0_SUBTYPE_DEAUTH:
+		IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+		    wh, NULL, "%s", "not handled");
 		vap->iv_stats.is_rx_mgtdiscard++;
 		break;
-	case IEEE80211_FC0_SUBTYPE_ACTION:
-		if (vap->iv_state != IEEE80211_S_RUN ||
-		    IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-			vap->iv_stats.is_rx_mgtdiscard++;
-			break;
-		}
-		ni->ni_inact = ni->ni_inact_reload;
-		if (ieee80211_parse_action(ni, m0) == 0)
-			ic->ic_recv_action(ni, wh, frm, efrm);
-		break;
+
 	default:
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
-		     wh, "mgt", "subtype 0x%x not handled", subtype);
+		    wh, "mgt", "subtype 0x%x not handled", subtype);
 		vap->iv_stats.is_rx_badsubtype++;
 		break;
 	}


More information about the svn-src-all mailing list