Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 May 2012 16:10:32 +0000 (UTC)
From:      Monthadar Al Jaberi <monthadar@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r234888 - head/sys/net80211
Message-ID:  <201205011610.q41GAWjX033880@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: monthadar
Date: Tue May  1 16:10:32 2012
New Revision: 234888
URL: http://svn.freebsd.org/changeset/base/234888

Log:
  Updated PREQ propagation code;
  
  * When receiving a Proactive PREQ dont return after processing it but propagate;
  * When we propagate we should not enforce ratechecking;
  * Added checking for multiple pred ID detection;
  * Storing proxy orig address when PREQ is not for us;
  
  Approved by: adrian

Modified:
  head/sys/net80211/ieee80211_hwmp.c

Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c	Tue May  1 16:09:44 2012	(r234887)
+++ head/sys/net80211/ieee80211_hwmp.c	Tue May  1 16:10:32 2012	(r234888)
@@ -886,11 +886,13 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
 	struct ieee80211_mesh_route *rt = NULL; /* pro-active code */
 	struct ieee80211_mesh_route *rtorig = NULL;
+	struct ieee80211_mesh_route *rtorig_ext = NULL;
 	struct ieee80211_mesh_route *rttarg = NULL;
 	struct ieee80211_hwmp_route *hrorig = NULL;
 	struct ieee80211_hwmp_route *hrtarg = NULL;
 	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
 	struct ieee80211_meshprep_ie prep;
+	ieee80211_hwmp_seq preqid;	/* last seen preqid for orig */
 
 	if (ni == vap->iv_bss ||
 	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
@@ -945,15 +947,22 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 	rtorig = ieee80211_mesh_rt_find(vap, preq->preq_origaddr);
 	if (rtorig == NULL) {
 		rtorig = ieee80211_mesh_rt_add(vap, preq->preq_origaddr);
+		if (rtorig == NULL) {
+			IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+			    "unable to add orig path to %6D",
+			    preq->preq_origaddr, ":");
+			vap->iv_stats.is_mesh_rtaddfailed++;
+			return;
+		}
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "adding originator %6D", preq->preq_origaddr, ":");
 	}
-	if (rtorig == NULL) {
-		/* XXX stat */
-		return;
-	}
 	hrorig = IEEE80211_MESH_ROUTE_PRIV(rtorig, struct ieee80211_hwmp_route);
 
+	/* record last seen preqid */
+	preqid = hrorig->hr_preqid;
+	hrorig->hr_preqid = HWMP_SEQ_MAX(hrorig->hr_preqid, preq->preq_id);
+
 	/* Data creation and update of forwarding information
 	 * according to Table 11C-8 for originator mesh STA.
 	 */
@@ -968,13 +977,16 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		ieee80211_mesh_rt_update(rtorig, preq->preq_lifetime);
 		/* path to orig is valid now */
 		rtorig->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID;
-	}else if(hrtarg != NULL &&
-		HWMP_SEQ_EQ(hrtarg->hr_seq, PREQ_TSEQ(0)) &&
-		(rtorig->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) {
+	}else if ((hrtarg != NULL &&
+	    HWMP_SEQ_EQ(hrtarg->hr_seq, PREQ_TSEQ(0)) &&
+	    ((rtorig->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0)) ||
+	    preqid >= preq->preq_id) {
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-		    "discard PREQ from %6D, old seq no %u <= %u",
+		    "discard PREQ from %6D, old seqno %u <= %u,"
+		    " or old preqid %u < %u",
 		    preq->preq_origaddr, ":",
-		    preq->preq_origseq, hrorig->hr_seq);
+		    preq->preq_origseq, hrorig->hr_seq,
+		    preq->preq_id, preqid);
 		return;
 	}
 
@@ -1025,6 +1037,26 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep);
 		return;
 	}
+	/* we may update our proxy information for the orig external */
+	else if (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE) {
+		rtorig_ext =
+		    ieee80211_mesh_rt_find(vap, preq->preq_orig_ext_addr);
+		if (rtorig_ext == NULL) {
+			rtorig_ext = ieee80211_mesh_rt_add(vap,
+			    preq->preq_orig_ext_addr);
+			if (rtorig_ext == NULL) {
+				IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+				    "unable to add orig ext proxy to %6D",
+				    preq->preq_orig_ext_addr, ":");
+				vap->iv_stats.is_mesh_rtaddfailed++;
+				return;
+			}
+			IEEE80211_ADDR_COPY(rtorig_ext->rt_mesh_gate,
+			    preq->preq_origaddr);
+		}
+		rtorig_ext->rt_ext_seq = preq->preq_origseq;
+		ieee80211_mesh_rt_update(rtorig_ext, preq->preq_lifetime);
+	}
 	/*
 	 * Proactive PREQ: reply with a proactive PREP to the
 	 * root STA if requested.
@@ -1067,54 +1099,29 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 			hwmp_send_prep(vap->iv_bss, vap->iv_myaddr,
 			    broadcastaddr, &prep);
 		}
-		hwmp_discover(vap, rootmac, NULL);
-		return;
 	}
 
 	/*
 	 * Forwarding and Intermediate reply for PREQs with 1 target.
 	 */
-	if (preq->preq_tcount == 1) {
+	if ((preq->preq_tcount == 1) && (preq->preq_ttl > 1) &&
+	    (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) {
 		struct ieee80211_meshpreq_ie ppreq; /* propagated PREQ */
 
 		memcpy(&ppreq, preq, sizeof(ppreq));
+
 		/*
 		 * We have a valid route to this node.
 		 */
 		if (rttarg != NULL &&
 		    (rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)) {
-			if (preq->preq_ttl > 1 &&
-			    preq->preq_hopcount < hs->hs_maxhops) {
-				IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-				    "forward PREQ from %6D",
-				    preq->preq_origaddr, ":");
-				/*
-				 * Propagate the original PREQ.
-				 * PREQ is unicast now to rttarg->rt_nexthop
-				 */
-				ppreq.preq_flags |=
-				    IEEE80211_MESHPREQ_FLAGS_AM;
-				ppreq.preq_hopcount += 1;
-				ppreq.preq_ttl -= 1;
-				ppreq.preq_metric +=
-				    ms->ms_pmetric->mpm_metric(ni);
-				/*
-				 * Set TO and unset RF bits because we are
-				 * going to send a PREP next.
-				 */
-				ppreq.preq_targets[0].target_flags |=
-				    IEEE80211_MESHPREQ_TFLAGS_TO;
-				hwmp_send_preq(ni, vap->iv_myaddr,
-				    rttarg->rt_nexthop, &ppreq,
-				    &hrtarg->hr_lastpreq,
-				    &ieee80211_hwmp_preqminint);
-			}
 			/*
 			 * Check if we can send an intermediate Path Reply,
-			 * i.e., Target Only bit is not set.
+			 * i.e., Target Only bit is not set and target is not
+			 * the MAC broadcast address.
 			 */
 			if (!(PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO) &&
-			    HWMP_SEQ_GEQ(hrtarg->hr_seq, PREQ_TSEQ(0))) {
+			    !IEEE80211_ADDR_EQ(PREQ_TADDR(0), broadcastaddr)) {
 				struct ieee80211_meshprep_ie prep;
 
 				IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
@@ -1133,42 +1140,26 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 				prep.prep_origseq = hrorig->hr_seq;
 				hwmp_send_prep(ni, vap->iv_myaddr,
 				    rtorig->rt_nexthop, &prep);
-			}
-		/*
-		 * We have no information about this path,
-		 * propagate the PREQ.
-		 */
-		} else if (preq->preq_ttl > 1 &&
-		    preq->preq_hopcount < hs->hs_maxhops) {
-			if (rttarg == NULL) {
-				rttarg =
-				    ieee80211_mesh_rt_add(vap, PREQ_TADDR(0));
-				if (rttarg == NULL) {
-					IEEE80211_NOTE(vap,
-					    IEEE80211_MSG_HWMP, ni,
-					    "unable to add PREQ path to %6D",
-					    PREQ_TADDR(0), ":");
-					vap->iv_stats.is_mesh_rtaddfailed++;
-					return;
-				}
-			}
-			rttarg->rt_metric = preq->preq_metric;
-			ieee80211_mesh_rt_update(rttarg, preq->preq_lifetime);
-			hrtarg = IEEE80211_MESH_ROUTE_PRIV(rttarg,
-			    struct ieee80211_hwmp_route);
-			hrtarg->hr_seq = PREQ_TSEQ(0);
-			hrtarg->hr_preqid = preq->preq_id;
 
-			IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-			    "forward PREQ from %6D",
-			    preq->preq_origaddr, ":");
-			ppreq.preq_hopcount += 1;
-			ppreq.preq_ttl -= 1;
-			ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni);
-			hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr,
-			    &ppreq, &hrtarg->hr_lastpreq,
-			    &ieee80211_hwmp_preqminint);
+				/*
+				 * Set TO and unset RF bits because we have
+				 * sent a PREP.
+				 */
+				ppreq.preq_targets[0].target_flags |=
+				    IEEE80211_MESHPREQ_TFLAGS_TO;
+			}
 		}
+
+		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+		    "forward PREQ from %6D",
+		    preq->preq_origaddr, ":");
+		ppreq.preq_hopcount += 1;
+		ppreq.preq_ttl -= 1;
+		ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni);
+
+		/* don't do PREQ ratecheck when we propagate */
+		hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr,
+			&ppreq, NULL, NULL);
 	}
 }
 #undef	PREQ_TFLAGS



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