Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 1 May 2012 16:16:20 +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: r234894 - head/sys/net80211
Message-ID:  <201205011616.q41GGKN7034347@svn.freebsd.org>

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

Log:
  PREQ discovery update.
  
  * Added a new discovery flag IEEE80211_MESHRT_FLAGS_DISCOVER;
  * Modified ieee80211_ioctl.h to include IEEE80211_MESHRT_FLAGS_DISCOVER;
  * Added hwmp_rediscover_cb, which will be called by a timeout to do
  rediscovery if we have not reach max number of preq discovery;
  * Modified hwmp_discover to setup a callout for path rediscovery;
  * Added to ieee80211req_mesh_route to have a back pointer to ieee80211vap
  for the discovery callout context;
  * Modified mesh_rt_add_locked arguemnt from ieee80211_mesh_state to
  ieee80211vap, this because we have to initialize the above back pointer;
  
  Approved by: adrian

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

Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c	Tue May  1 16:15:34 2012	(r234893)
+++ head/sys/net80211/ieee80211_hwmp.c	Tue May  1 16:16:20 2012	(r234894)
@@ -1319,7 +1319,7 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 	rt->rt_metric = metric;
 	rt->rt_nhops = prep->prep_hopcount + 1;
 	ieee80211_mesh_rt_update(rt, prep->prep_lifetime);
-	rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; /* mark valid */
+	rt->rt_flags = IEEE80211_MESHRT_FLAGS_VALID; /* mark valid */
 
 	/*
 	 * If it's NOT for us, propagate the PREP
@@ -1805,6 +1805,64 @@ hwmp_send_rann(struct ieee80211_node *ni
 #define	PREQ_TFLAGS(n)	preq.preq_targets[n].target_flags
 #define	PREQ_TADDR(n)	preq.preq_targets[n].target_addr
 #define	PREQ_TSEQ(n)	preq.preq_targets[n].target_seq
+static void
+hwmp_rediscover_cb(void *arg)
+{
+	struct ieee80211_mesh_route *rt = arg;
+	struct ieee80211vap *vap = rt->rt_vap;
+	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
+	struct ieee80211_mesh_state *ms = vap->iv_mesh;
+	struct ieee80211_hwmp_route *hr;
+	struct ieee80211_meshpreq_ie preq; /* Optimize: storing first preq? */
+
+	if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID))
+		return ; /* nothing to do */
+
+	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+	if (hr->hr_preqretries >=
+		ieee80211_hwmp_maxpreq_retries) {
+		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
+			rt->rt_dest, NULL, "%s",
+			"no valid path , max number of discovery, send GATE");
+		/* TODO: send to known gates */
+		vap->iv_stats.is_mesh_fwd_nopath++;
+		rt->rt_flags = 0; /* Mark invalid */
+		return ; /* XXX: flush queue? */
+	}
+
+	hr->hr_preqretries++;
+
+
+	IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, rt->rt_dest,
+	    "start path rediscovery , target seq %u", hr->hr_seq);
+	/*
+	 * Try to discover the path for this node.
+	 * Group addressed PREQ Case A
+	 */
+	preq.preq_flags = 0;
+	preq.preq_hopcount = 0;
+	preq.preq_ttl = ms->ms_ttl;
+	preq.preq_id = ++hs->hs_preqid;
+	IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr);
+	preq.preq_origseq = hr->hr_origseq;
+	preq.preq_lifetime = ticks_to_msecs(ieee80211_hwmp_pathtimeout);
+	preq.preq_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
+	preq.preq_tcount = 1;
+	IEEE80211_ADDR_COPY(PREQ_TADDR(0), rt->rt_dest);
+	PREQ_TFLAGS(0) = 0;
+	if (ieee80211_hwmp_targetonly)
+		PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_TO;
+	PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN;
+	PREQ_TSEQ(0) = 0; /* RESERVED when USN flag is set */
+	/* XXX check return value */
+	hwmp_send_preq(vap->iv_bss, vap->iv_myaddr,
+		broadcastaddr, &preq, &hr->hr_lastpreq,
+		&ieee80211_hwmp_preqminint);
+	callout_reset(&rt->rt_discovery,
+		ieee80211_hwmp_net_diameter_traversaltime * 2,
+		hwmp_rediscover_cb, rt);
+}
+
 static struct ieee80211_node *
 hwmp_discover(struct ieee80211vap *vap,
     const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
@@ -1857,13 +1915,11 @@ hwmp_discover(struct ieee80211vap *vap,
 				vap->iv_stats.is_mesh_fwd_nopath++;
 				goto done;
 			}
+			rt->rt_flags = IEEE80211_MESHRT_FLAGS_DISCOVER;
 			hr->hr_preqretries++;
 			if (hr->hr_origseq == 0)
 				hr->hr_origseq = ++hs->hs_seq;
 			rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
-			/* XXX: special discovery timeout, larger lifetime? */
-			ieee80211_mesh_rt_update(rt,
-			    ticks_to_msecs(ieee80211_hwmp_pathtimeout));
 			sendpreq = 1;
 			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, dest,
 			    "start path discovery (src %s), target seq %u",
@@ -1894,6 +1950,9 @@ hwmp_discover(struct ieee80211vap *vap,
 			hwmp_send_preq(vap->iv_bss, vap->iv_myaddr,
 			    broadcastaddr, &preq, &hr->hr_lastpreq,
 			    &ieee80211_hwmp_preqminint);
+			callout_reset(&rt->rt_discovery,
+			    ieee80211_hwmp_net_diameter_traversaltime * 2,
+			    hwmp_rediscover_cb, rt);
 		}
 		if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)
 			ni = ieee80211_find_txnode(vap, rt->rt_nexthop);

Modified: head/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- head/sys/net80211/ieee80211_ioctl.h	Tue May  1 16:15:34 2012	(r234893)
+++ head/sys/net80211/ieee80211_ioctl.h	Tue May  1 16:16:20 2012	(r234894)
@@ -339,8 +339,9 @@ enum {
 
 struct ieee80211req_mesh_route {
 	uint8_t		imr_flags;
-#define	IEEE80211_MESHRT_FLAGS_VALID	0x01
-#define	IEEE80211_MESHRT_FLAGS_PROXY	0x02
+#define	IEEE80211_MESHRT_FLAGS_DISCOVER	0x01
+#define	IEEE80211_MESHRT_FLAGS_VALID	0x02
+#define	IEEE80211_MESHRT_FLAGS_PROXY	0x04
 	uint8_t		imr_dest[IEEE80211_ADDR_LEN];
 	uint8_t		imr_nexthop[IEEE80211_ADDR_LEN];
 	uint16_t	imr_nhops;

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c	Tue May  1 16:15:34 2012	(r234893)
+++ head/sys/net80211/ieee80211_mesh.c	Tue May  1 16:16:20 2012	(r234894)
@@ -175,9 +175,10 @@ mesh_rt_find_locked(struct ieee80211_mes
 }
 
 static struct ieee80211_mesh_route *
-mesh_rt_add_locked(struct ieee80211_mesh_state *ms,
+mesh_rt_add_locked(struct ieee80211vap *vap,
     const uint8_t dest[IEEE80211_ADDR_LEN])
 {
+	struct ieee80211_mesh_state *ms = vap->iv_mesh;
 	struct ieee80211_mesh_route *rt;
 
 	KASSERT(!IEEE80211_ADDR_EQ(broadcastaddr, dest),
@@ -188,9 +189,11 @@ mesh_rt_add_locked(struct ieee80211_mesh
 	rt = malloc(ALIGN(sizeof(struct ieee80211_mesh_route)) +
 	    ms->ms_ppath->mpp_privlen, M_80211_MESH_RT, M_NOWAIT | M_ZERO);
 	if (rt != NULL) {
+		rt->rt_vap = vap;
 		IEEE80211_ADDR_COPY(rt->rt_dest, dest);
 		rt->rt_priv = (void *)ALIGN(&rt[1]);
 		mtx_init(&rt->rt_lock, "MBSS_RT", "802.11s route entry", MTX_DEF);
+		callout_init(&rt->rt_discovery, CALLOUT_MPSAFE);
 		rt->rt_updtime = ticks;	/* create time */
 		TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next);
 	}
@@ -223,7 +226,7 @@ ieee80211_mesh_rt_add(struct ieee80211va
 	    ("%s: adding self to the routing table", __func__));
 
 	MESH_RT_LOCK(ms);
-	rt = mesh_rt_add_locked(ms, dest);
+	rt = mesh_rt_add_locked(vap, dest);
 	MESH_RT_UNLOCK(ms);
 	return rt;
 }
@@ -285,7 +288,7 @@ ieee80211_mesh_proxy_check(struct ieee80
 	MESH_RT_LOCK(ms);
 	rt = mesh_rt_find_locked(ms, dest);
 	if (rt == NULL) {
-		rt = mesh_rt_add_locked(ms, dest);
+		rt = mesh_rt_add_locked(vap, dest);
 		if (rt == NULL) {
 			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_MESH, dest,
 			    "%s", "unable to add proxy entry");
@@ -330,6 +333,7 @@ mesh_rt_del(struct ieee80211_mesh_state 
 	 * is holding the route.
 	 */
 	RT_ENTRY_LOCK(rt);
+	callout_drain(&rt->rt_discovery);
 	mtx_destroy(&rt->rt_lock);
 	free(rt, M_80211_MESH_RT);
 }
@@ -402,13 +406,11 @@ mesh_rt_flush_invalid(struct ieee80211va
 		return;
 	MESH_RT_LOCK(ms);
 	TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
+		/* Discover paths will be deleted by their own callout */
+		if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_DISCOVER)
+			continue;
 		ieee80211_mesh_rt_update(rt, 0);
-		/*
-		 * NB: we check for lifetime == 0 so that we give a chance
-		 * for route discovery to complete.
-		 */
-		if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0 &&
-		    rt->rt_lifetime == 0)
+		if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0)
 			mesh_rt_del(ms, rt);
 	}
 	MESH_RT_UNLOCK(ms);

Modified: head/sys/net80211/ieee80211_mesh.h
==============================================================================
--- head/sys/net80211/ieee80211_mesh.h	Tue May  1 16:15:34 2012	(r234893)
+++ head/sys/net80211/ieee80211_mesh.h	Tue May  1 16:16:20 2012	(r234894)
@@ -410,7 +410,9 @@ MALLOC_DECLARE(M_80211_MESH_RT);
  */
 struct ieee80211_mesh_route {
 	TAILQ_ENTRY(ieee80211_mesh_route)	rt_next;
+	struct ieee80211vap	*rt_vap;
 	struct mtx		rt_lock;	/* fine grained route lock */
+	struct callout		rt_discovery;	/* discovery timeout */
 	int			rt_updtime;	/* last update time */
 	uint8_t			rt_dest[IEEE80211_ADDR_LEN];
 	uint8_t			rt_mesh_gate[IEEE80211_ADDR_LEN]; /* meshDA */
@@ -418,8 +420,9 @@ struct ieee80211_mesh_route {
 	uint32_t		rt_metric;	/* path metric */
 	uint16_t		rt_nhops;	/* number of hops */
 	uint16_t		rt_flags;
-#define	IEEE80211_MESHRT_FLAGS_VALID	0x01	/* path discovery complete */
-#define	IEEE80211_MESHRT_FLAGS_PROXY	0x02	/* proxy entry */
+#define	IEEE80211_MESHRT_FLAGS_DISCOVER	0x01	/* path discovery */
+#define	IEEE80211_MESHRT_FLAGS_VALID	0x02	/* path discovery complete */
+#define	IEEE80211_MESHRT_FLAGS_PROXY	0x04	/* proxy entry */
 	uint32_t		rt_lifetime;	/* route timeout */
 	uint32_t		rt_lastmseq;	/* last seq# seen dest */
 	uint32_t		rt_ext_seq;	/* proxy seq number */



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