Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 May 2012 16:02:31 +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: r234881 - head/sys/net80211
Message-ID:  <201205011602.q41G2Vrk033351@svn.freebsd.org>

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

Log:
  PREP update
  
  * Added assertion in mesh_rt_update;
  * Fixed some prep propagation that where multicast, ALL PREPS ARE UNICAST;
  * Fixed PREP acceptance criteria;
  * Fixed some PREP debug messages;
  * HWMP intermediate reply (PREP) should only be sent if we have newer
  forwarding infomration (FI) about target;
  * Fixed PREP propagation condition and PREP w/ AE handling;
  * Ignore PREPs that have unknown originator.
  * Removed old code inside PREP that was for proactive path building
  to root mesh;
  
  Other errors include:
  * use seq number of target and not orig mesh STA;
  * Metric is what we have stored in our FI;
  * Error in amendment, Hop count is not 0 but equals FI hopcount for target;
  
  Approved by: adrian

Modified:
  head/sys/net80211/ieee80211_hwmp.c
  head/sys/net80211/ieee80211_mesh.c

Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c	Tue May  1 16:00:31 2012	(r234880)
+++ head/sys/net80211/ieee80211_hwmp.c	Tue May  1 16:02:31 2012	(r234881)
@@ -887,7 +887,8 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		return;
 
 	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-	    "received PREQ, source %6D", preq->preq_origaddr, ":");
+	    "received PREQ, orig %6D, targ(0) %6D", preq->preq_origaddr, ":",
+	    PREQ_TADDR(0), ":");
 
 	/*
 	 * Acceptance criteria: if the PREQ is not for us or not broadcast
@@ -1010,9 +1011,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 	 * root STA if requested.
 	 */
 	if (IEEE80211_ADDR_EQ(PREQ_TADDR(0), broadcastaddr) &&
-	    (PREQ_TFLAGS(0) &
-	    ((IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF) ==
-	    (IEEE80211_MESHPREQ_TFLAGS_TO|IEEE80211_MESHPREQ_TFLAGS_RF)))) {
+	    (PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO)) {
 		uint8_t rootmac[IEEE80211_ADDR_LEN];
 
 		IEEE80211_ADDR_COPY(rootmac, preq->preq_origaddr);
@@ -1096,26 +1095,26 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 			 * Check if we can send an intermediate Path Reply,
 			 * i.e., Target Only bit is not set.
 			 */
-	    		if (!(PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO)) {
+			if (!(PREQ_TFLAGS(0) & IEEE80211_MESHPREQ_TFLAGS_TO) &&
+			    HWMP_SEQ_GEQ(hrtarg->hr_seq, PREQ_TSEQ(0))) {
 				struct ieee80211_meshprep_ie prep;
 
 				IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 				    "intermediate reply for PREQ from %6D",
 				    preq->preq_origaddr, ":");
 				prep.prep_flags = 0;
-				prep.prep_hopcount = rt->rt_nhops + 1;
+				prep.prep_hopcount = rttarg->rt_nhops;
 				prep.prep_ttl = ms->ms_ttl;
 				IEEE80211_ADDR_COPY(&prep.prep_targetaddr,
 				    PREQ_TADDR(0));
-				prep.prep_targetseq = hrorig->hr_seq;
+				prep.prep_targetseq = hrtarg->hr_seq;
 				prep.prep_lifetime = preq->preq_lifetime;
-				prep.prep_metric = rt->rt_metric +
-				    ms->ms_pmetric->mpm_metric(ni);
+				prep.prep_metric =rttarg->rt_metric;
 				IEEE80211_ADDR_COPY(&prep.prep_origaddr,
 				    preq->preq_origaddr);
 				prep.prep_origseq = hrorig->hr_seq;
 				hwmp_send_prep(ni, vap->iv_myaddr,
-				    broadcastaddr, &prep);
+				    rtorig->rt_nexthop, &prep);
 			}
 		/*
 		 * We have no information about this path,
@@ -1191,6 +1190,9 @@ static void
 hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
     const struct ieee80211_frame *wh, const struct ieee80211_meshprep_ie *prep)
 {
+#define	IS_PROXY(rt)	(rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)
+#define	PROXIED_BY_US(rt)		\
+    (IEEE80211_ADDR_EQ(vap->iv_myaddr, rt->rt_mesh_gate))
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
 	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
 	struct ieee80211_mesh_route *rt = NULL;
@@ -1203,63 +1205,31 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 	uint32_t metric = 0;
 	const uint8_t *addr;
 
-	/*
-	 * Acceptance criteria: If the corresponding PREP was not generated
-	 * by us or generated by an external mac that is proxied by us
-	 * and forwarding is disabled, discard this PREP.
-	 */
 	if (ni == vap->iv_bss ||
 	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
 		return;
-	if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) &&
-	    !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
-		return;
+
+	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+	    "received PREP, orig %6D, targ %6D", prep->prep_origaddr, ":",
+	    prep->prep_targetaddr, ":");
+
+	/*
+	 * Acceptance criteria: (If the corresponding PREP was not generated
+	 * by us OR not generated by an external mac that is not proxied by us)
+	 * AND forwarding is disabled, discard this PREP.
+	 */
 	rtorig = ieee80211_mesh_rt_find(vap, prep->prep_origaddr);
-	if (rtorig != NULL &&
-	    !(rtorig->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY)) {
+	if ((!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) ||
+	    (rtorig != NULL && IS_PROXY(rtorig) && !PROXIED_BY_US(rtorig))) &&
+	    !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)){
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-		    "received PREP(%u) for an orig(%6D) not proxied by us",
-		    prep->prep_origseq, prep->prep_origaddr, ":");
+		    "discard PREP, orig(%6D) not proxied or generated by us",
+		    prep->prep_origaddr, ":");
 		return;
 	}
 
 	/* PREP ACCEPTED */
 
-	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-	    "received PREP from %6D", prep->prep_targetaddr, ":");
-
-#if 0
-	rt = ieee80211_mesh_rt_find(vap, prep->prep_targetaddr);
-	if (rt == NULL) {
-		/*
-		 * If we have no entry this could be a reply to a root PREQ.
-		 * XXX: not true anymore cause we dont create entry for target
-		 *  when propagating PREQs like the old code did.
-		 */
-		if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) {
-			rt = ieee80211_mesh_rt_add(vap, prep->prep_targetaddr);
-			if (rt == NULL) {
-				IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP,
-				    ni, "unable to add PREP path to %6D",
-				    prep->prep_targetaddr, ":");
-				vap->iv_stats.is_mesh_rtaddfailed++;
-				return;
-			}
-			IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2);
-			rt->rt_nhops = prep->prep_hopcount;
-			ieee80211_mesh_rt_update(rt, prep->prep_lifetime);
-			rt->rt_metric = prep->prep_metric;
-			rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID;
-			IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-			    "add root path to %6D nhops %d metric %lu (PREP)",
-			    prep->prep_targetaddr, ":",
-			    rt->rt_nhops, rt->rt_metric);
-			return;
-		}
-		return;
-	}
-#endif
-
 	/*
 	 * If accepted shall create or update the active forwarding information
 	 * it maintains for the target mesh STA of the PREP (according to the
@@ -1278,6 +1248,8 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 			vap->iv_stats.is_mesh_rtaddfailed++;
 			return;
 		}
+		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+		    "adding target %6D", prep->prep_targetaddr, ":");
 	}
 	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
 	/* update path metric */
@@ -1315,11 +1287,25 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 	rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; /* mark valid */
 
 	/*
-	 * If it's NOT for us, propagate the PREP.
+	 * If it's NOT for us, propagate the PREP
 	 */
 	if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) &&
-	    prep->prep_ttl > 1 && prep->prep_hopcount < hs->hs_maxhops) {
+	    prep->prep_ttl > 1 &&
+	    prep->prep_hopcount < hs->hs_maxhops) {
 		struct ieee80211_meshprep_ie pprep; /* propagated PREP */
+		/*
+		 * NB: We should already have setup the path to orig
+		 * mesh STA when we propagated PREQ to target mesh STA,
+		 * no PREP is generated without a corresponding PREQ.
+		 * XXX: for now just ignore.
+		 */
+		if (rtorig == NULL) {
+			IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+			    "received PREP for an unknown orig(%6D)",
+			    prep->prep_origaddr, ":");
+			return;
+		}
+
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "propagate PREP from %6D",
 		    prep->prep_targetaddr, ":");
@@ -1328,13 +1314,17 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		pprep.prep_hopcount += 1;
 		pprep.prep_ttl -= 1;
 		pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni);
-		hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep);
+		hwmp_send_prep(ni, vap->iv_myaddr, rtorig->rt_nexthop, &pprep);
 
-		/* may store target external address if recevied PREP w/ AE */
 		/* precursor list for the Target Mesh STA Address is updated */
 	}
-	/* check if we received a PREP for a proxy address */
-	else if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) {
+
+	/*
+	 * Check if we received a PREP w/ AE and store target external address.
+	 * We may store target external address if recevied PREP w/ AE
+	 * and we are not final destination
+	 */
+	if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) {
 		rtext = ieee80211_mesh_rt_find(vap,
 			prep->prep_target_ext_addr);
 		if (rtext == NULL) {
@@ -1366,8 +1356,11 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		rtext->rt_metric = metric;
 		rtext->rt_lifetime = prep->prep_lifetime;
 		rtext->rt_nhops = prep->prep_hopcount + 1;
-		rtext->rt_ext_seq = prep->prep_origseq; /* proxy seq */
-		/* proxy entries have no HWMP priv data, nullify them to be sure? */
+		rtext->rt_ext_seq = prep->prep_origseq; /* new proxy seq */
+		/*
+		 * XXX: proxy entries have no HWMP priv data,
+		 * nullify them to be sure?
+		 */
 	}
 	/*
 	 * Check for frames queued awaiting path discovery.
@@ -1388,6 +1381,8 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		    "flush queued frame %p len %d", m, m->m_pkthdr.len);
 		ifp->if_transmit(ifp, m);
 	}
+#undef	IS_PROXY
+#undef	PROXIED_BY_US
 }
 
 static int

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c	Tue May  1 16:00:31 2012	(r234880)
+++ head/sys/net80211/ieee80211_mesh.c	Tue May  1 16:02:31 2012	(r234881)
@@ -239,6 +239,8 @@ ieee80211_mesh_rt_update(struct ieee8021
 	int timesince, now;
 	uint32_t lifetime = 0;
 
+	KASSERT(rt != NULL, ("route is NULL"));
+
 	now = ticks;
 	RT_ENTRY_LOCK(rt);
 



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