Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Jul 2009 22:06:12 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r195260 - projects/mesh11s/sys/net80211
Message-ID:  <200907012206.n61M6CaI025178@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Wed Jul  1 22:06:12 2009
New Revision: 195260
URL: http://svn.freebsd.org/changeset/base/195260

Log:
  * add more stats
  * check for 802.11 seq no.
  * fix forwarding direction check (by sam)
  * move RSSI/noise setup below
  * fix a case of peer localid == 0
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/mesh11s/sys/net80211/ieee80211_ioctl.h
  projects/mesh11s/sys/net80211/ieee80211_mesh.c

Modified: projects/mesh11s/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ioctl.h	Wed Jul  1 20:43:46 2009	(r195259)
+++ projects/mesh11s/sys/net80211/ieee80211_ioctl.h	Wed Jul  1 22:06:12 2009	(r195260)
@@ -224,6 +224,8 @@ struct ieee80211_stats {
 	uint32_t	is_ampdu_rexmt;		/* A-MPDU frames rexmt ok */
 	uint32_t	is_ampdu_rexmt_fail;	/* A-MPDU frames rexmt fail */
 
+	uint32_t	is_mesh_wrongmesh;	/* dropped 'cuz not mesh sta*/
+	uint32_t	is_mesh_nolink;		/* dropped 'cuz link not estab*/
 	uint32_t	is_mesh_fwd_ttl;	/* mesh not fwd'd 'cuz ttl 0 */
 	uint32_t	is_mesh_fwd_nobuf;	/* mesh not fwd'd 'cuz no mbuf*/
 	uint32_t	is_mesh_fwd_tooshort;	/* mesh not fwd'd 'cuz no hdr */
@@ -232,7 +234,7 @@ struct ieee80211_stats {
 
 	uint32_t	is_hwmp_wrongseq;	/* wrong hwmp seq no. */
 
-	uint32_t	is_spare[10];
+	uint32_t	is_spare[8];
 };
 
 /*

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c	Wed Jul  1 20:43:46 2009	(r195259)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c	Wed Jul  1 22:06:12 2009	(r195260)
@@ -421,8 +421,10 @@ mesh_forward(struct ieee80211vap *vap, s
 }
 
 static int
-mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int noise)
+mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
 {
+#define	SEQ_LEQ(a,b)	((int)((a)-(b)) <= 0)
+#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;
@@ -432,6 +434,7 @@ mesh_input(struct ieee80211_node *ni, st
 	uint8_t dir, type, subtype, qos;
 	uint32_t seq;
 	uint8_t *addr;
+	ieee80211_seq rxseq;
 
 	KASSERT(ni != NULL, ("null node"));
 	ni->ni_inact = ni->ni_inact_reload;
@@ -465,8 +468,36 @@ mesh_input(struct ieee80211_node *ni, st
 	type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
 	subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
 	if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
+		IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
+		ni->ni_noise = nf;
+		if (HAS_SEQ(type)) {
+			uint8_t tid = ieee80211_gettid(wh);
+
+			if (IEEE80211_QOS_HAS_SEQ(wh) &&
+			    TID_TO_WME_AC(tid) >= WME_AC_VI)
+				ic->ic_wme.wme_hipri_traffic++;
+			rxseq = le16toh(*(uint16_t *)wh->i_seq);
+			if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 &&
+			    (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
+			    SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
+				/* duplicate, discard */
+				IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
+				    wh->i_addr1, "duplicate",
+				    "seqno <%u,%u> fragno <%u,%u> tid %u",
+				    rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
+				    ni->ni_rxseqs[tid] >>
+				    IEEE80211_SEQ_SEQ_SHIFT,
+				    rxseq & IEEE80211_SEQ_FRAG_MASK,
+				    ni->ni_rxseqs[tid] &
+				    IEEE80211_SEQ_FRAG_MASK,
+				    tid);
+				vap->iv_stats.is_rx_dup++;
+				IEEE80211_NODE_STAT(ni, rx_dup);
+				goto out;
+			}
+			ni->ni_rxseqs[tid] = rxseq;
+		}
 	}
-
 #ifdef IEEE80211_DEBUG
 	/*
 	 * It's easier, but too expensive, to simulate different mesh
@@ -486,15 +517,12 @@ mesh_input(struct ieee80211_node *ni, st
 	case IEEE80211_FC0_TYPE_DATA:
 		if (ni == vap->iv_bss)
 			goto out;
-#if 0
-		IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, ni,
-		    "received data frame, dir 0x%x", dir);
-#endif
 		if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
 			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
 			    ni->ni_macaddr, NULL,
 			    "peer link not yet established (%d)",
 			    ni->ni_mlstate);
+			vap->iv_stats.is_mesh_nolink++;
 			goto out;
 		}	
 		if (dir != IEEE80211_FC1_DIR_FROMDS &&
@@ -547,24 +575,19 @@ mesh_input(struct ieee80211_node *ni, st
 			vap->iv_stats.is_rx_dup++;
 			goto out;
 		}
+
 		/*
-		 * Forward and deliver multicast packets
-		 * XXX tap fwd'd packets not for us?
-		 */
-		if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
-			mesh_forward(vap, m, mc);
-			goto deliver;
-		}
-		/*
-		 * Forward packets if their final destination is not us.
+		 * Potentially forward packet.  See table s36 (p140)
+		 * for the rules.  XXX tap fwd'd packets not for us?
 		 */
-		if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr3) &&
-		    IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1)) {
+		if (dir == IEEE80211_FC1_DIR_FROMDS ||
+		    !IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr)) {
 			mesh_forward(vap, m, mc);
-			/* NB: don't deliver */
-			goto out;
+			if (dir == IEEE80211_FC1_DIR_DSTODS)
+				goto out;
+			/* NB: fall thru to deliver mcast frames locally */
 		}
-deliver:
+
 		/*
 		 * Save QoS bits for use below--before we strip the header.
 		 */
@@ -650,7 +673,7 @@ deliver:
 			vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
 			goto out;
 		}
-		vap->iv_recv_mgmt(ni, m, subtype, rssi, noise);
+		vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
 		goto out;
 	case IEEE80211_FC0_TYPE_CTL:
 		vap->iv_stats.is_rx_ctl++;
@@ -692,7 +715,7 @@ is11bclient(const uint8_t *rates, const 
 
 static void
 mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
-    int rssi, int noise)
+    int rssi, int nf)
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
@@ -739,7 +762,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 				ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
 			}
 			ieee80211_add_scan(vap, &scan, wh,
-			    subtype, rssi, noise);
+			    subtype, rssi, nf);
 			return;
 		}
 
@@ -754,6 +777,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 		    scan.meshid == NULL || scan.meshconf == NULL) {
 			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
 			    wh, "beacon", "%s", "not a mesh sta");
+			vap->iv_stats.is_mesh_wrongmesh++;
 			return;
 		}
 		/*
@@ -764,6 +788,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 		        (struct ieee80211_meshconf_ie *)scan.meshconf)) {
 			IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
 			    wh, "beacon", "%s", "not for our mesh");
+			vap->iv_stats.is_mesh_wrongmesh++;
 			return;
 		}
 		/*
@@ -809,8 +834,6 @@ mesh_recv_mgmt(struct ieee80211_node *ni
 			ni->ni_mlrcnt = 0;
 			mesh_peer_timeout_setup(ni);
 		}
-		IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
-		ni->ni_noise = noise;
 		break;
 	}
 	case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
@@ -939,6 +962,7 @@ mesh_recv_action(struct ieee80211_node *
 	if (ni == vap->iv_bss) {
 		IEEE80211_DISCARD(vap, IEEE80211_MSG_MESH,
 		    wh, NULL, "%s", "unknown node");
+		vap->iv_stats.is_tx_nonode++;
 		return;
 	}
 
@@ -1184,8 +1208,8 @@ mesh_recv_action(struct ieee80211_node *
 				    IEEE80211_NODE_MESH_CONFIRMRCV);
 				break;
 			case IEEE80211_NODE_MESH_HOLDING:
-				sargs.arg[0] = ni->ni_mllid;
-				sargs.arg[1] = ni->ni_mlpid;
+				sargs.arg[0] = ni->ni_mlpid;
+				sargs.arg[1] = meshpeer->peer_llinkid;
 				sargs.arg[2] =
 				    IEEE80211_REASON_MESH_MAX_RETRIES;
 				ieee80211_send_action(ni,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200907012206.n61M6CaI025178>