Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 May 2012 16:11:48 +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: r234889 - head/sys/net80211
Message-ID:  <201205011611.q41GBmeN033973@svn.freebsd.org>

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

Log:
  * Modified PERR acceptance criteria according to amendment;
  * Modified how PERR is handled and propagated according to amendment;
  
  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:10:32 2012	(r234888)
+++ head/sys/net80211/ieee80211_hwmp.c	Tue May  1 16:11:47 2012	(r234889)
@@ -1450,7 +1450,7 @@ hwmp_peerdown(struct ieee80211_node *ni)
 		PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN;
 	PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC;
 	IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest);
-	PERR_DSEQ(0) = hr->hr_seq;
+	PERR_DSEQ(0) = ++hr->hr_seq;
 	PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH;
 	/* NB: flush everything passing through peer */
 	ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr);
@@ -1461,60 +1461,117 @@ hwmp_peerdown(struct ieee80211_node *ni)
 #undef	PERR_DSEQ
 #undef	PERR_DRCODE
 
-#define	PERR_DFLAGS(n)	perr->perr_dests[n].dest_flags
-#define	PERR_DADDR(n)	perr->perr_dests[n].dest_addr
-#define	PERR_DSEQ(n)	perr->perr_dests[n].dest_seq
-#define	PERR_DRCODE(n)	perr->perr_dests[n].dest_rcode
+#define	PERR_DFLAGS(n)		perr->perr_dests[n].dest_flags
+#define	PERR_DADDR(n)		perr->perr_dests[n].dest_addr
+#define	PERR_DSEQ(n)		perr->perr_dests[n].dest_seq
+#define	PERR_DEXTADDR(n)	perr->perr_dests[n].dest_ext_addr
+#define	PERR_DRCODE(n)		perr->perr_dests[n].dest_rcode
 static void
 hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
     const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr)
 {
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
 	struct ieee80211_mesh_route *rt = NULL;
+	struct ieee80211_mesh_route *rt_ext = NULL;
 	struct ieee80211_hwmp_route *hr;
-	struct ieee80211_meshperr_ie pperr;
-	int i, forward = 0;
+	struct ieee80211_meshperr_ie *pperr = NULL;
+	int i, j = 0, forward = 0;
 
-	/*
-	 * Acceptance criteria: check if we received a PERR from a
-	 * neighbor and forwarding is enabled.
-	 */
 	if (ni == vap->iv_bss ||
-	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED ||
-	    !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
+	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
 		return;
+
+	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+	    "received PERR from %6D", wh->i_addr2, ":");
+
+	/*
+	 * if forwarding is true, prepare pperr
+	 */
+	if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) {
+		forward = 1;
+		pperr = malloc(sizeof(*perr) + 31*sizeof(*perr->perr_dests),
+		    M_80211_MESH_PERR, M_NOWAIT); /* XXX: magic number, 32 err dests */
+	}
+
 	/*
-	 * Find all routing entries that match and delete them.
+	 * Acceptance criteria: check if we have forwarding information
+	 * stored about destination, and that nexthop == TA of this PERR.
+	 * NB: we also build a new PERR to propagate in case we should forward.
 	 */
 	for (i = 0; i < perr->perr_ndests; i++) {
 		rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i));
-		if (rt == NULL)
+		if (rt == NULL || rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)
 			continue;
+		if (!IEEE80211_ADDR_EQ(rt->rt_nexthop, wh->i_addr2))
+			continue;
+
+		/* found and accepted a PERR ndest element, process it... */
+		if (forward)
+			memcpy(&pperr->perr_dests[j], &perr->perr_dests[i],
+			    sizeof(*perr->perr_dests));
 		hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
-		if (!(PERR_DFLAGS(0) & IEEE80211_MESHPERR_DFLAGS_USN) &&
-		    HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) {
-			ieee80211_mesh_rt_del(vap, rt->rt_dest);
-			ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest);
-			rt = NULL;
-			forward = 1;
+		switch(PERR_DFLAGS(i)) {
+		case (IEEE80211_REASON_MESH_PERR_NO_FI):
+			if (PERR_DSEQ(i) == 0) {
+				hr->hr_seq++;
+				if (forward) {
+					pperr->perr_dests[j].dest_seq =
+					    hr->hr_seq;
+				}
+			} else {
+				hr->hr_seq = PERR_DSEQ(i);
+			}
+			rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID;
+			j++;
+			break;
+		case (IEEE80211_REASON_MESH_PERR_DEST_UNREACH):
+			if(HWMP_SEQ_GT(PERR_DSEQ(i), hr->hr_seq)) {
+				hr->hr_seq = PERR_DSEQ(i);
+				rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID;
+				j++;
+			}
+			break;
+		case (IEEE80211_REASON_MESH_PERR_NO_PROXY):
+			rt_ext = ieee80211_mesh_rt_find(vap, PERR_DEXTADDR(i));
+			if (rt_ext != NULL) {
+				rt_ext->rt_flags &=
+				    ~IEEE80211_MESHRT_FLAGS_VALID;
+				j++;
+			}
+			break;
+		default:
+			IEEE80211_DISCARD(vap, IEEE80211_MSG_HWMP, wh, NULL,
+			    "PERR, unknown reason code %u\n", PERR_DFLAGS(i));
+			goto done; /* XXX: stats?? */
 		}
+		ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest);
+		KASSERT(j < 32, ("PERR, error ndest >= 32 (%u)", j));
+	}
+	if (j == 0) {
+		IEEE80211_DISCARD(vap, IEEE80211_MSG_HWMP, wh, NULL, "%s",
+		    "PERR not accepted");
+		goto done; /* XXX: stats?? */
 	}
+
 	/*
 	 * Propagate the PERR if we previously found it on our routing table.
-	 * XXX handle ndest > 1
 	 */
 	if (forward && perr->perr_ttl > 1) {
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "propagate PERR from %6D", wh->i_addr2, ":");
-		memcpy(&pperr, perr, sizeof(*perr));
-		pperr.perr_ttl--;
+		pperr->perr_ndests = j;
+		pperr->perr_ttl--;
 		hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr,
-		    &pperr);
+		    pperr);
 	}
+done:
+	if (pperr != NULL)
+		free(pperr, M_80211_MESH_PERR);
 }
 #undef	PERR_DFLAGS
 #undef	PEER_DADDR
 #undef	PERR_DSEQ
+#undef	PERR_DEXTADDR
 #undef	PERR_DRCODE
 
 static int



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