svn commit: r195404 - projects/mesh11s/sys/net80211

Rui Paulo rpaulo at FreeBSD.org
Mon Jul 6 10:40:47 UTC 2009


Author: rpaulo
Date: Mon Jul  6 10:40:46 2009
New Revision: 195404
URL: http://svn.freebsd.org/changeset/base/195404

Log:
  Overhaul the routing structures used and move them to common mesh code
  so that they can be used by future routing protocols.
  XXX not finished
  
  Sponsored by:	The FreeBSD Foundation

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

Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c	Mon Jul  6 09:31:04 2009	(r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c	Mon Jul  6 10:40:46 2009	(r195404)
@@ -64,15 +64,6 @@ __FBSDID("$FreeBSD$");
 #include <net80211/ieee80211_hwmp.h>
 #include <net80211/ieee80211_input.h>
 
-static struct ieee80211_hwmp_route *
-		hwmp_rt_find(struct ieee80211vap *,
-		    const uint8_t [IEEE80211_ADDR_LEN]);
-static struct ieee80211_hwmp_route *
-		hwmp_rt_add(struct ieee80211vap *,
-		    const uint8_t [IEEE80211_ADDR_LEN]);
-static void	hwmp_rt_del(struct ieee80211vap *,
-		    const uint8_t [IEEE80211_ADDR_LEN]);
-static void	hwmp_rt_flush(struct ieee80211vap *);
 static int	ieee80211_hwmp_send_action(struct ieee80211_node *,
 		    const uint8_t [IEEE80211_ADDR_LEN],
 		    const uint8_t [IEEE80211_ADDR_LEN],
@@ -137,9 +128,6 @@ static const struct timeval ieee80211_hw
 #define	HWMP_ROOTMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hwmp_rootint))
 #define	HWMP_RANNMODEINT msecs_to_ticks(timeval2msecs(ieee80211_hwmp_rannint))
 
-#define	HWMP_LOCK(hs)		mtx_lock(&(hs)->hs_lock)
-#define	HWMP_UNLOCK(hs)		mtx_unlock(&(hs)->hs_lock)
-
 /* unalligned little endian access */
 #define LE_WRITE_2(p, v) do {				\
 	((uint8_t *)(p))[0] = (v) & 0xff;		\
@@ -166,8 +154,6 @@ SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, tar
 SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, replyforward, CTLTYPE_INT | CTLFLAG_RW,
     &ieee80211_hwmp_replyforward, 0, "Set RF bit on generated PREQs");
 
-MALLOC_DEFINE(M_80211_HWMP, "80211hwmp", "802.11 HWMP routing table");
-
 #define	IEEE80211_HWMP_DEFAULT_MAXHOPS	31
 #define	IEEE80211_HWMP_DEFAULT_TTL	31
 
@@ -193,83 +179,6 @@ ieee80211_hwmp_init(void)
 }
 SYSINIT(wlan_hwmp, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_hwmp_init, NULL);
 
-/*
- * Helper functions to manipulate the HWMP routing table.
- */
-static struct ieee80211_hwmp_route *
-hwmp_rt_find(struct ieee80211vap *vap, const uint8_t dest[IEEE80211_ADDR_LEN])
-{
-	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt;
-
-	HWMP_LOCK(hs);
-	TAILQ_FOREACH(rt, &hs->hs_routes, rt_next) {
-		if (IEEE80211_ADDR_EQ(dest, rt->rt_dest)) {
-			HWMP_UNLOCK(hs);
-			return rt;
-		}
-	}
-	HWMP_UNLOCK(hs);
-	return NULL;
-}
-
-static struct ieee80211_hwmp_route *
-hwmp_rt_add(struct ieee80211vap *vap, const uint8_t dest[IEEE80211_ADDR_LEN])
-{
-	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt;
-
-	KASSERT(hwmp_rt_find(vap, dest) == NULL,
-	    ("%s: duplicate entry in the routing table", __func__));
-	KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest),
-	    ("%s: adding self to the routing table", __func__));
-	KASSERT(!IEEE80211_ADDR_EQ(broadcastaddr, dest),
-	    ("%s: adding broadcast to the routing table", __func__));
-
-	rt = malloc(sizeof(struct ieee80211_hwmp_route), M_80211_HWMP,
-	    M_NOWAIT | M_ZERO);
-	IEEE80211_ADDR_COPY(rt->rt_dest, dest);
-	HWMP_LOCK(hs);
-	TAILQ_INSERT_TAIL(&hs->hs_routes, rt, rt_next);
-	HWMP_UNLOCK(hs);
-	return rt;
-}
-
-static void
-hwmp_rt_del(struct ieee80211vap *vap, const uint8_t dest[IEEE80211_ADDR_LEN])
-{
-	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt, *next;
-
-	KASSERT(hs != NULL, ("no HWMP state"));
-	HWMP_LOCK(hs);
-	TAILQ_FOREACH_SAFE(rt, &hs->hs_routes, rt_next, next) {
-		if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) {
-			TAILQ_REMOVE(&hs->hs_routes, rt, rt_next);
-			free(rt, M_80211_HWMP);
-			HWMP_UNLOCK(hs);
-			return;
-		}
-	}
-	HWMP_UNLOCK(hs);
-}
-
-static void
-hwmp_rt_flush(struct ieee80211vap *vap)
-{
-	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt, *next;
-
-	if (hs == NULL)
-		return;
-	HWMP_LOCK(hs);
-	TAILQ_FOREACH_SAFE(rt, &hs->hs_routes, rt_next, next) {
-		TAILQ_REMOVE(&hs->hs_routes, rt, rt_next);
-		free(rt, M_80211_HWMP);
-	}
-	HWMP_UNLOCK(hs);
-}
-
 void
 ieee80211_hwmp_vattach(struct ieee80211vap *vap)
 {
@@ -278,14 +187,12 @@ ieee80211_hwmp_vattach(struct ieee80211v
 	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS,
 	    ("not a mesh vap, opmode %d", vap->iv_opmode));
 
-	hs = malloc(sizeof(struct ieee80211_hwmp_state), M_80211_HWMP,
+	hs = malloc(sizeof(struct ieee80211_hwmp_state), M_80211_VAP,
 	    M_NOWAIT | M_ZERO);
 	if (hs == NULL) {
 		printf("%s: couldn't alloc HWMP state\n", __func__);
 		return;
 	}
-	TAILQ_INIT(&hs->hs_routes);
-	mtx_init(&hs->hs_lock, "HWMP", "802.11s HWMP", MTX_DEF);
 	hs->hs_maxhops = IEEE80211_HWMP_DEFAULT_MAXHOPS;
 	hs->hs_ttl = IEEE80211_HWMP_DEFAULT_TTL;
 	callout_init(&hs->hs_roottimer, CALLOUT_MPSAFE);                                        
@@ -297,11 +204,9 @@ ieee80211_hwmp_vdetach(struct ieee80211v
 {
 	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
 
-	hwmp_rt_flush(vap);
 	if (callout_active(&hs->hs_roottimer))
 		callout_drain(&hs->hs_roottimer);
-	mtx_destroy(&hs->hs_lock);
-	free(vap->iv_hwmp, M_80211_HWMP);
+	free(vap->iv_hwmp, M_80211_VAP);
 	vap->iv_hwmp = NULL;
 } 
 
@@ -316,10 +221,8 @@ ieee80211_hwmp_newstate(struct ieee80211
             ieee80211_state_name[nstate], arg);
 
 	/* Flush the table on !INIT -> INIT, e.g. interface down & up */
-	if (nstate != IEEE80211_S_INIT && ostate == IEEE80211_S_INIT) {
-		hwmp_rt_flush(vap);
+	if (nstate != IEEE80211_S_INIT && ostate == IEEE80211_S_INIT)
 		callout_drain(&hs->hs_roottimer);
-	}
 	return 0;
 }
 
@@ -724,8 +627,9 @@ hwmp_recv_preq(struct ieee80211vap *vap,
     const struct ieee80211_frame *wh, const struct ieee80211_meshpreq_ie *preq)
 {
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
+	struct ieee80211_mesh_route *rt = NULL;
+	struct ieee80211_hwmp_route *hr;
 	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt = NULL;
 	struct ieee80211_meshprep_ie prep;
 
 	if (ni == vap->iv_bss ||
@@ -774,7 +678,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		/*
 		 * Build the reverse path, if we don't have it already.
 		 */
-		rt = hwmp_rt_find(vap, preq->preq_origaddr);
+		rt = ieee80211_mesh_rt_find(vap, preq->preq_origaddr);
 		if (rt == NULL)
 			ieee80211_hwmp_discover(vap, preq->preq_origaddr, NULL);
 		else if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr))
@@ -795,9 +699,10 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		    "root mesh station @ %s",
 		    ether_sprintf(preq->preq_origaddr));
 		IEEE80211_ADDR_COPY(rootmac, preq->preq_origaddr);
-		rt = hwmp_rt_find(vap, rootmac);
+		rt = ieee80211_mesh_rt_find(vap, rootmac);
 		if (rt == NULL)
-			rt = hwmp_rt_add(vap, rootmac);
+			rt = ieee80211_mesh_rt_add(vap, rootmac,
+			    sizeof(struct ieee80211_hwmp_route));
 		/*
 		 * Reply with a PREP if we don't have a path to the root
 		 * or if the root sent us a proactive PREQ.
@@ -822,7 +727,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		ieee80211_hwmp_discover(vap, rootmac, NULL);
 		return;
 	}
-	rt = hwmp_rt_find(vap, PREQ_TADDR(0));
+	rt = ieee80211_mesh_rt_find(vap, PREQ_TADDR(0));
 
 	/* XXX missing. Check for AE bit and update proxy information */
 
@@ -838,10 +743,12 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		 */
 		if (rt != NULL &&
 		    !IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr)) {
-			rt->rt_preqid = preq->preq_id;
-			rt->rt_seq = preq->preq_origseq;
-			if (preq->preq_ttl > 1) {
 
+			hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+			    struct ieee80211_hwmp_route);
+			hr->hr_preqid = preq->preq_id;
+			hr->hr_seq = preq->preq_origseq;
+			if (preq->preq_ttl > 1) {
 				IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 				    "forwarding PREQ from %s",
 				    ether_sprintf(preq->preq_origaddr));
@@ -877,7 +784,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 				prep.prep_ttl = hs->hs_ttl;
 				IEEE80211_ADDR_COPY(&prep.prep_targetaddr,
 				    preq->preq_origaddr);
-				prep.prep_targetseq = rt->rt_seq;
+				prep.prep_targetseq = hr->hr_seq;
 				prep.prep_lifetime = preq->preq_lifetime;
 				prep.prep_metric = rt->rt_metric +
 				    ieee80211_airtime_calc(ni);
@@ -893,11 +800,14 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		 */
 		} else if (preq->preq_ttl > 1) {
 			if (rt == NULL)
-				rt = hwmp_rt_add(vap, PREQ_TADDR(0));
+				rt = ieee80211_mesh_rt_add(vap, PREQ_TADDR(0),
+				    sizeof(struct ieee80211_hwmp_route));
+			hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+			    struct ieee80211_hwmp_route);
 			rt->rt_metric = preq->preq_metric;
 			rt->rt_lifetime = preq->preq_lifetime;
-			rt->rt_seq = preq->preq_origseq;
-			rt->rt_preqid = preq->preq_id;
+			hr->hr_seq = preq->preq_origseq;
+			hr->hr_preqid = preq->preq_id;
 
 			IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 			    "forwarding PREQ from %s",
@@ -950,7 +860,8 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 {
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
 	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt = NULL;
+	struct ieee80211_mesh_route *rt = NULL;
+	struct ieee80211_hwmp_route *hr;
 	struct ieee80211com *ic = vap->iv_ic;
 	struct ifnet *ifp = vap->iv_ifp;
 	struct mbuf *m, *next;
@@ -989,14 +900,14 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep);
 	}
 
-	rt = hwmp_rt_find(vap, prep->prep_origaddr);
+	rt = ieee80211_mesh_rt_find(vap, prep->prep_origaddr);
 	if (rt == NULL) {
 		/*
 		 * If we have no entry this could be a reply to a root PREQ.
 		 */
 		if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) {
-			printf("1\n");
-			rt = hwmp_rt_add(vap, prep->prep_origaddr);
+			rt = ieee80211_mesh_rt_add(vap, prep->prep_origaddr,
+			    sizeof(struct ieee80211_hwmp_route));
 			IEEE80211_ADDR_COPY(rt->rt_nexthop, wh->i_addr2);
 			rt->rt_nhops = prep->prep_hopcount;
 			rt->rt_lifetime = prep->prep_lifetime;
@@ -1005,7 +916,8 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		} 
 		return;
 	}
-	if (prep->prep_targetseq == rt->rt_seq) {
+	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+	if (prep->prep_targetseq == hr->hr_seq) {
 		int useprep = 0;
 		/*
 		 * Check if we already have a path to this node.
@@ -1093,18 +1005,20 @@ ieee80211_hwmp_peerdown(struct ieee80211
 {
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211_meshperr_ie perr;
-	struct ieee80211_hwmp_route *rt;
+	struct ieee80211_mesh_route *rt;
+	struct ieee80211_hwmp_route *hr;
 
-	rt = hwmp_rt_find(vap, ni->ni_macaddr);
+	rt = ieee80211_mesh_rt_find(vap, ni->ni_macaddr);
 	if (rt == NULL)
 		return;
+	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
 	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 	    "%s", "deleting route entry");
 	perr.perr_mode = 0;
 	perr.perr_ndests = 1;
 	IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest);
-	PERR_DSEQ(0) = rt->rt_seq;
-	hwmp_rt_del(vap, ni->ni_macaddr);
+	PERR_DSEQ(0) = hr->hr_seq;
+	ieee80211_mesh_rt_del(vap, ni->ni_macaddr);
 	hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
 }
 #undef	PERR_DADDR
@@ -1118,7 +1032,8 @@ hwmp_recv_perr(struct ieee80211vap *vap,
     const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr)
 {
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
-	struct ieee80211_hwmp_route *rt = NULL;
+	struct ieee80211_mesh_route *rt = NULL;
+	struct ieee80211_hwmp_route *hr;
  	struct ieee80211_meshperr_ie pperr;
 	int i, forward = 0;
 
@@ -1134,11 +1049,13 @@ hwmp_recv_perr(struct ieee80211vap *vap,
 	 * Find all routing entries that match and delete them.
 	 */
 	for (i = 0; i < perr->perr_ndests; i++) {
-		rt = hwmp_rt_find(vap, PERR_DADDR(i));
+		rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i));
 		if (rt == NULL)
 			continue;
-		if (PERR_DSEQ(i) >= rt->rt_seq) {
-			hwmp_rt_del(vap, rt->rt_dest);
+		hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+		    struct ieee80211_hwmp_route);
+		if (PERR_DSEQ(i) >= hr->hr_seq) {
+			ieee80211_mesh_rt_del(vap, rt->rt_dest);
 			rt = NULL;
 			forward = 1;
 		}
@@ -1191,21 +1108,25 @@ hwmp_recv_rann(struct ieee80211vap *vap,
     const struct ieee80211_frame *wh, const struct ieee80211_meshrann_ie *rann)
 {
 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
-	struct ieee80211_hwmp_route *rt = NULL;
+	struct ieee80211_mesh_route *rt = NULL;
+	struct ieee80211_hwmp_route *hr;
 	struct ieee80211_meshrann_ie prann;
 
 	if (ni == vap->iv_bss ||
 	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
 		return;
 
-	rt = hwmp_rt_find(vap, rann->rann_addr);
+	rt = ieee80211_mesh_rt_find(vap, rann->rann_addr);
 	/*
 	 * Discover the path to the root mesh STA.
 	 * If we already know it, propagate the RANN element.
 	 */
-	if (rt == NULL)
+	if (rt == NULL) {
 		ieee80211_hwmp_discover(vap, rann->rann_addr, NULL);
-	else if (rann->rann_seq > rt->rt_seq && rann->rann_ttl > 1 &&
+		return;
+	}
+	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+	if (rann->rann_seq > hr->hr_seq && rann->rann_ttl > 1 &&
 	    (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) {
 		memcpy(&prann, rann, sizeof(prann));
 		prann.rann_hopcount += 1;
@@ -1244,10 +1165,11 @@ ieee80211_hwmp_discover(struct ieee80211
     const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
 {
 	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt = NULL;
+	struct ieee80211_mesh_route *rt = NULL;
+	struct ieee80211_hwmp_route *hr;
 	struct ieee80211_meshpreq_ie preq;
 	struct ieee80211_node *ni;
-	int sendpreq = 0, unknowndst = 0;
+	int sendpreq = 0;
 
 	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS,
 	    ("not a mesh vap, opmode %d", vap->iv_opmode));
@@ -1257,25 +1179,25 @@ ieee80211_hwmp_discover(struct ieee80211
 
 	ni = NULL;
 	if (!IEEE80211_IS_MULTICAST(dest)) {
-		rt = hwmp_rt_find(vap, dest);
+		rt = ieee80211_mesh_rt_find(vap, dest);
 		if (rt == NULL) {
-			rt = hwmp_rt_add(vap, dest);
+			rt = ieee80211_mesh_rt_add(vap, dest,
+			    sizeof(struct ieee80211_hwmp_route));
 			if (rt == NULL) {
 				/* XXX stat+msg */
 				goto done;
 			}
 		}
+		hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+		    struct ieee80211_hwmp_route);
 		if (IEEE80211_ADDR_EQ(rt->rt_nexthop, invalidaddr)) {
-			rt->rt_seq = ++hs->hs_seq;
-			rt->rt_preqid = ++hs->hs_preqid;
+			hr->hr_seq = ++hs->hs_seq;
+			hr->hr_preqid = ++hs->hs_preqid;
 			rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
 			rt->rt_lifetime =
 			    timeval2msecs(ieee80211_hwmp_pathtimeout);
 			/* XXX check preq retries */
 			sendpreq = 1;
-			unknowndst = 1;
-		}
-		if (sendpreq) {
 			IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_HWMP, dest,
 			    "%s", "initiating path discovery");
 			/*
@@ -1284,9 +1206,9 @@ ieee80211_hwmp_discover(struct ieee80211
 			preq.preq_flags = 0;
 			preq.preq_hopcount = 0;
 			preq.preq_ttl = hs->hs_ttl;
-			preq.preq_id = rt->rt_preqid;
+			preq.preq_id = hr->hr_preqid;
 			IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr);
-			preq.preq_origseq = rt->rt_seq;
+			preq.preq_origseq = hr->hr_seq;
 			preq.preq_lifetime = rt->rt_lifetime;
 			preq.preq_metric = rt->rt_metric;
 			preq.preq_tcount = 1;
@@ -1296,11 +1218,8 @@ ieee80211_hwmp_discover(struct ieee80211
 				PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_TO;
 			if (ieee80211_hwmp_replyforward)
 				PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_RF;
-			if (unknowndst) {
-				PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN;
-				PREQ_TSEQ(0) = 0;
-			} else
-				PREQ_TSEQ(0) = rt->rt_seq;
+			PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN;
+			PREQ_TSEQ(0) = 0;
 			/* XXX check return value */
 			hwmp_send_preq(vap->iv_bss, vap->iv_myaddr,
 			    broadcastaddr, &preq);
@@ -1336,55 +1255,22 @@ done:
 #undef	PREQ_TADDR
 #undef	PREQ_TSEQ
 
-/*
- * Iterate the forwarding information table and locate the
- * next hop.
- */
-struct ieee80211_node *
-ieee80211_hwmp_find_txnode(struct ieee80211vap *vap,
-    const uint8_t dest[IEEE80211_ADDR_LEN])
-{
-	struct ieee80211_hwmp_route *rt;
-
-	rt = hwmp_rt_find(vap, dest);
-	if (rt == NULL)
-		return NULL;
-	return ieee80211_find_txnode(vap, rt->rt_nexthop);
-}
-
-int
-ieee80211_hwmp_checkpseq(struct ieee80211vap *vap,
-    const uint8_t source[IEEE80211_ADDR_LEN], uint32_t seq)
-{
-	struct ieee80211_hwmp_route *rt;
-
-	rt = hwmp_rt_find(vap, source);
-	if (rt == NULL) {
-		rt = hwmp_rt_add(vap, source);
-		rt->rt_lastpseq = seq;
-		return 0;
-	}
-	if (IEEE80211_MESH_SEQ_GEQ(rt->rt_lastpseq, seq)) {
-		return 1;
-	} else {
-		rt->rt_lastpseq = seq;
-		return 0;
-	}
-}
-
 static int
 hwmp_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
 {
 	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
-	struct ieee80211_hwmp_route *rt;
+#if 0
+	struct ieee80211_mesh_route *rt;
 	size_t len, off;
 	uint8_t *p;
+#endif
 	int error;
  
 	if (vap->iv_opmode != IEEE80211_M_MBSS)
 		return ENOSYS;
 	error = 0;
 	switch (ireq->i_type) {
+#if 0
 	case IEEE80211_IOC_HWMP_CMD:
 		switch (ireq->i_val) {
 		case IEEE80211_HWMP_CMD_LIST:
@@ -1421,6 +1307,7 @@ hwmp_ioctl_get80211(struct ieee80211vap 
 			return ENOSYS;
 		}
 		break;
+#endif
 	case IEEE80211_IOC_HWMP_ROOTMODE:
 		ireq->i_val = hs->hs_rootmode;
 		break;
@@ -1447,6 +1334,7 @@ hwmp_ioctl_set80211(struct ieee80211vap 
 		return ENOSYS;
 	error = 0;
 	switch (ireq->i_type) {
+#if 0
 	case IEEE80211_IOC_HWMP_CMD:
 		switch (ireq->i_val) {
 		case IEEE80211_HWMP_CMD_LIST:
@@ -1464,6 +1352,7 @@ hwmp_ioctl_set80211(struct ieee80211vap 
 			return ENOSYS;
 		}
 		break;
+#endif
 	case IEEE80211_IOC_HWMP_ROOTMODE:
 		if (ireq->i_val < 0 || ireq->i_val > 3)
 			return EINVAL;

Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.h	Mon Jul  6 09:31:04 2009	(r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.h	Mon Jul  6 10:40:46 2009	(r195404)
@@ -31,38 +31,25 @@
 #ifndef _NET80211_IEEE80211_HWMP_H_
 #define _NET80211_IEEE80211_HWMP_H_
 
+#ifdef _KERNEL
 /* HWMP sequence numbers are 32 bit, so we can't use ieee80211_seq */
 typedef uint32_t ieee80211_hwmp_seq;
-
+#define	IEEE80211_HWMP_SEQ_LEQ(a, b)	((int32_t)((a)-(b)) <= 0)
+#define	IEEE80211_HWMP_SEQ_GEQ(a, b)	((int32_t)((a)-(b)) >= 0)
 /*
- * HWMP Forwarding Information table, part of each VAP.
+ * Private extension of ieee80211_mesh_route.
  */
 struct ieee80211_hwmp_route {
-	TAILQ_ENTRY(ieee80211_hwmp_route) rt_next;
-	uint8_t			rt_dest[IEEE80211_ADDR_LEN];
-	ieee80211_hwmp_seq	rt_seq;		/* HWMP sequence number */
-	ieee80211_hwmp_seq	rt_preqid;	/* Last PREQ ID seen */
-	uint8_t			rt_nexthop[IEEE80211_ADDR_LEN];
-	uint32_t		rt_metric;	/* Path Metric */
-	uint32_t		rt_nhops;	/* Number of Hops */
-	uint32_t		rt_lifetime;
-	int			rt_preqretries;
-	uint32_t		rt_lastpseq;	/* last mesh seq number
-						   from this node */
+	ieee80211_hwmp_seq	hr_seq;		/* HWMP sequence number */
+	ieee80211_hwmp_seq	hr_preqid;	/* Last PREQ ID seen */
+	int			hr_preqretries;
 };
-
-#ifdef _KERNEL
-
-MALLOC_DECLARE(M_80211_HWMP);
-
 struct ieee80211_hwmp_state {
-	TAILQ_HEAD(, ieee80211_hwmp_route)	hs_routes;
 	ieee80211_hwmp_seq	hs_seq;		/* next seq to be used */
 	ieee80211_hwmp_seq	hs_preqid;	/* next PREQ ID to be used */
 	struct timeval		hs_lastpreq;	/* last time we sent a PREQ */
 	struct timeval		hs_lastprep;	/* last time we sent a PREP */
 	struct timeval		hs_lastperr;	/* last time we sent a PERR */
-	struct mtx		hs_lock;	/* lock for the fi table */
 	int			hs_rootmode;	/* proactive HWMP */
 	struct callout		hs_roottimer;
 	uint8_t			hs_maxhops;	/* max hop count */
@@ -78,11 +65,6 @@ void		ieee80211_hwmp_recv_action(struct 
 struct ieee80211_node *
 		ieee80211_hwmp_discover(struct ieee80211vap *,
 		    const uint8_t [IEEE80211_ADDR_LEN], struct mbuf *);
-struct ieee80211_node *
-		ieee80211_hwmp_find_txnode(struct ieee80211vap *vap,
-		    const uint8_t dest[IEEE80211_ADDR_LEN]);
-int		ieee80211_hwmp_checkpseq(struct ieee80211vap *,
-		    const uint8_t [IEEE80211_ADDR_LEN], uint32_t);
 void		ieee80211_hwmp_peerdown(struct ieee80211_node *);
 #endif /* _KERNEL */
 

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c	Mon Jul  6 09:31:04 2009	(r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c	Mon Jul  6 10:40:46 2009	(r195404)
@@ -64,11 +64,19 @@ __FBSDID("$FreeBSD$");
 static void	mesh_vattach(struct ieee80211vap *);
 static int	mesh_newstate(struct ieee80211vap *, enum ieee80211_state, int);
 static inline void	mesh_linkchange(struct ieee80211_node *,
-    enum ieee80211_mesh_mlstate);
+			    enum ieee80211_mesh_mlstate);
+static void	mesh_checkid(void *, struct ieee80211_node *);
 static uint32_t	mesh_generateid(struct ieee80211vap *);
+static int	mesh_checkpseq(struct ieee80211vap *,
+		    const uint8_t [IEEE80211_ADDR_LEN], uint32_t);
+static struct ieee80211_node *
+		mesh_find_txnode(struct ieee80211vap *,
+		    const uint8_t [IEEE80211_ADDR_LEN]);
+static void	mesh_forward(struct ieee80211vap *, struct mbuf *,
+		    const struct ieee80211_meshcntl *);
 static int	mesh_input(struct ieee80211_node *, struct mbuf *, int, int);
 static void	mesh_recv_mgmt(struct ieee80211_node *, struct mbuf *, int,
-    int, int);
+		    int, int);
 static inline void	mesh_peer_timeout_setup(struct ieee80211_node *);
 static void		mesh_peer_timeout_backoff(struct ieee80211_node *);
 static void		mesh_peer_timeout_cb(void *);
@@ -86,9 +94,6 @@ static const int ieee80211_mesh_confirmt
 #define	CONFIRM_TIMEOUT	msecs_to_ticks(ieee80211_mesh_confirmtimeout)
 static const int ieee80211_mesh_maxretries = 2;
 
-SYSCTL_NODE(_net_wlan, OID_AUTO, mesh, CTLFLAG_RD, 0,
-    "IEEE 802.11s parameters");
-
 #define	IEEE80211_MESH_DEFAULT_TTL	31
 
 static	ieee80211_recv_action_func mesh_recv_action_meshpeering_open;
@@ -103,6 +108,97 @@ static	ieee80211_send_action_func mesh_s
 static	ieee80211_send_action_func mesh_send_action_meshlink_request;
 static	ieee80211_send_action_func mesh_send_action_meshlink_reply;
 
+#define	MESH_RT_LOCK(ms)	mtx_lock(&(ms)->ms_rt_lock)
+#define	MESH_RT_UNLOCK(ms)	mtx_unlock(&(ms)->ms_rt_lock)
+
+MALLOC_DEFINE(M_80211_MESH_RT, "80211mesh", "802.11s routing table");
+
+/*
+ * Helper functions to manipulate the Mesh routing table.
+ */
+struct ieee80211_mesh_route *
+ieee80211_mesh_rt_find(struct ieee80211vap *vap,
+    const uint8_t dest[IEEE80211_ADDR_LEN])
+{
+        struct ieee80211_mesh_state *ms = vap->iv_mesh;
+        struct ieee80211_mesh_route *rt;
+
+        MESH_RT_LOCK(ms);
+        TAILQ_FOREACH(rt, &ms->ms_routes, rt_next) {
+                if (IEEE80211_ADDR_EQ(dest, rt->rt_dest)) {
+                        MESH_RT_UNLOCK(ms);
+                        return rt;
+                }
+        }
+        MESH_RT_UNLOCK(ms);
+        return NULL;
+}
+
+struct ieee80211_mesh_route *
+ieee80211_mesh_rt_add(struct ieee80211vap *vap,
+    const uint8_t dest[IEEE80211_ADDR_LEN], size_t privlen)
+{
+        struct ieee80211_mesh_state *ms = vap->iv_mesh;
+        struct ieee80211_mesh_route *rt;
+	static const uint8_t broadcastaddr[IEEE80211_ADDR_LEN] =
+		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+        KASSERT(ieee80211_mesh_rt_find(vap, dest) == NULL,
+            ("%s: duplicate entry in the routing table", __func__));
+        KASSERT(!IEEE80211_ADDR_EQ(vap->iv_myaddr, dest),
+            ("%s: adding self to the routing table", __func__));
+        KASSERT(!IEEE80211_ADDR_EQ(broadcastaddr, dest),
+            ("%s: adding broadcast to the routing table", __func__));
+
+        rt = malloc(sizeof(struct ieee80211_mesh_route), M_80211_MESH_RT,
+            M_NOWAIT | M_ZERO);
+        IEEE80211_ADDR_COPY(rt->rt_dest, dest);
+	rt->rt_priv = malloc(privlen, M_80211_MESH_RT, M_NOWAIT | M_ZERO);
+        MESH_RT_LOCK(ms);
+        TAILQ_INSERT_TAIL(&ms->ms_routes, rt, rt_next);
+        MESH_RT_UNLOCK(ms);
+        return rt;
+}
+
+void                                                                                           
+ieee80211_mesh_rt_del(struct ieee80211vap *vap,
+    const uint8_t dest[IEEE80211_ADDR_LEN])
+{
+	struct ieee80211_mesh_state *ms = vap->iv_mesh;
+	struct ieee80211_mesh_route *rt, *next;
+
+	KASSERT(ms != NULL, ("no HWMP state"));
+	MESH_RT_LOCK(ms);
+	TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
+		if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) {
+			TAILQ_REMOVE(&ms->ms_routes, rt, rt_next);
+			free(rt->rt_priv, M_80211_MESH_RT);
+			free(rt, M_80211_MESH_RT);
+			MESH_RT_UNLOCK(ms);
+			return;
+		}
+	}
+	MESH_RT_UNLOCK(ms);
+}
+
+void                                                                                           
+ieee80211_mesh_rt_flush(struct ieee80211vap *vap)
+{
+	struct ieee80211_mesh_state *ms = vap->iv_mesh;
+	struct ieee80211_mesh_route *rt, *next;
+
+	if (ms == NULL)
+		return;
+	MESH_RT_LOCK(ms);
+	TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
+		TAILQ_REMOVE(&ms->ms_routes, rt, rt_next);
+		free(rt->rt_priv, M_80211_MESH_RT);
+		free(rt, M_80211_MESH_RT);
+	}
+	MESH_RT_UNLOCK(ms);
+}
+
+
 static void
 ieee80211_mesh_init(void)
 {
@@ -173,8 +269,12 @@ mesh_vdetach_peers(void *arg, struct iee
 static void
 mesh_vdetach(struct ieee80211vap *vap)
 {
+	struct ieee80211_mesh_state *ms = vap->iv_mesh;
+
 	ieee80211_iterate_nodes(&vap->iv_ic->ic_sta, mesh_vdetach_peers,
 	    NULL);
+	ieee80211_mesh_rt_flush(vap);
+	mtx_destroy(&ms->ms_rt_lock);
 	ieee80211_hwmp_vdetach(vap);
 	free(vap->iv_mesh, M_80211_VAP);
 	vap->iv_mesh = NULL;
@@ -199,6 +299,8 @@ mesh_vattach(struct ieee80211vap *vap)
 	ms->ms_seq = 0;
 	ms->ms_flags = (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_FWD);
 	ms->ms_ttl = IEEE80211_MESH_DEFAULT_TTL;
+	TAILQ_INIT(&ms->ms_routes);
+	mtx_init(&ms->ms_rt_lock, "MBSS", "802.11s routing table", MTX_DEF);
 	ieee80211_hwmp_vattach(vap);
 }
 
@@ -223,6 +325,9 @@ mesh_newstate(struct ieee80211vap *vap, 
         if (ostate != IEEE80211_S_SCAN)
                 ieee80211_cancel_scan(vap);     /* background scan */
 	ni = vap->iv_bss;			/* NB: no reference held */
+	/* Flush the routing table */
+	if (nstate != INIT && ostate == INIT)
+		ieee80211_mesh_rt_flush(vap);
 	switch (nstate) {
 	case IEEE80211_S_INIT:
 		switch (ostate) {
@@ -426,6 +531,45 @@ mesh_generateid(struct ieee80211vap *vap
 }
 
 /*
+ * Verifies if we already received this packet by checking its
+ * sequence number.
+ */
+static int
+mesh_checkpseq(struct ieee80211vap *vap,
+    const uint8_t source[IEEE80211_ADDR_LEN], uint32_t seq)
+{
+	struct ieee80211_mesh_route *rt;
+
+	rt = ieee80211_mesh_rt_find(vap, source);
+	if (rt == NULL) {
+		rt = ieee80211_mesh_rt_add(vap, source, 12);
+		rt->rt_lastmseq = seq;
+		return 0;
+	}
+	if (IEEE80211_MESH_SEQ_GEQ(rt->rt_lastmseq, seq)) {
+		return 1;
+	} else {
+		rt->rt_lastmseq = seq;
+		return 0;
+	}
+}
+
+/*
+ * Iterate the routing table and locate the next hop.
+ */
+static struct ieee80211_node *
+mesh_find_txnode(struct ieee80211vap *vap,
+    const uint8_t dest[IEEE80211_ADDR_LEN])
+{
+        struct ieee80211_mesh_route *rt;
+
+        rt = ieee80211_mesh_rt_find(vap, dest);
+        if (rt == NULL)
+                return NULL;
+        return ieee80211_find_txnode(vap, rt->rt_nexthop);
+}
+
+/*
  * Forward the specified frame.
  * Decrement the TTL and set TA to our MAC address.
  */
@@ -491,7 +635,7 @@ mesh_forward(struct ieee80211vap *vap, s
 		params.ibp_try0 = 1;
 		mcopy->m_flags |= M_MCAST;
 	} else {
-		ni = ieee80211_hwmp_find_txnode(vap, whcopy->i_addr3);
+		ni = mesh_find_txnode(vap, whcopy->i_addr3);
 		if (ni == NULL) {
 			IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
 			    "%s", "frame not fwd'd, no path");
@@ -679,7 +823,7 @@ mesh_input(struct ieee80211_node *ni, st
 			vap->iv_stats.is_rx_wrongbss++;	/* XXX kinda */
 			goto out;
 		}
-		if (ieee80211_hwmp_checkpseq(vap, addr, seq) != 0) {
+		if (mesh_checkpseq(vap, addr, seq) != 0) {
 			IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
 			    addr, "data", "duplicate mesh seqno %u ttl %u",
 			    seq, mc->mc_ttl);

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.h	Mon Jul  6 09:31:04 2009	(r195403)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.h	Mon Jul  6 10:40:46 2009	(r195404)
@@ -371,7 +371,24 @@ struct ieee80211_meshcntl_ae11 {
 	uint8_t		mc_addr6[IEEE80211_ADDR_LEN];
 } __packed;
 
+struct ieee80211req_mesh_routes {
+/* XXX TBD */	
+};
+
 #ifdef _KERNEL
+MALLOC_DECLARE(M_80211_MESH_RT);
+struct ieee80211_mesh_route {
+	TAILQ_ENTRY(ieee80211_mesh_route)	rt_next;
+	uint8_t			rt_dest[IEEE80211_ADDR_LEN];
+	uint8_t			rt_nexthop[IEEE80211_ADDR_LEN];
+	uint32_t		rt_metric;	/* path metric */
+	uint16_t		rt_nhops;	/* number of hops */
+	uint32_t		rt_lifetime;
+	uint32_t		rt_lastmseq;/* last seq# seen from this dest */
+	void			*rt_priv; /* pointer to private data */
+};
+#define	IEEE80211_MESH_ROUTE_PRIV(rt, cast)	(cast *)rt->rt_priv
+
 struct ieee80211_mesh_proto {
 	/* Action frame categories to intercept */
 	uint8_t			mpr_actpath;
@@ -405,11 +422,23 @@ struct ieee80211_mesh_state {
 #define IEEE80211_MESHFLAGS_PORTAL	0x02	/* mesh portal role */
 #define IEEE80211_MESHFLAGS_FWD		0x04	/* forward packets */
 	uint8_t			ms_flags;
+	struct mtx		ms_rt_lock;
+	TAILQ_HEAD(, ieee80211_mesh_route)	ms_routes;
 	struct ieee80211_mesh_proto	*ms_proto;
 };
 void		ieee80211_mesh_attach(struct ieee80211com *);
 void		ieee80211_mesh_detach(struct ieee80211com *);
 
+struct ieee80211_mesh_route *
+		ieee80211_mesh_rt_find(struct ieee80211vap *,
+		    const uint8_t [IEEE80211_ADDR_LEN]);
+struct ieee80211_mesh_route *
+                ieee80211_mesh_rt_add(struct ieee80211vap *,
+		    const uint8_t [IEEE80211_ADDR_LEN], size_t);
+void		ieee80211_mesh_rt_del(struct ieee80211vap *,
+		    const uint8_t [IEEE80211_ADDR_LEN]);
+void		ieee80211_mesh_rt_flush(struct ieee80211vap *);
+
 uint8_t *	ieee80211_add_meshpeerver(uint8_t *, struct ieee80211vap *);
 uint8_t *	ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
 uint8_t *	ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);


More information about the svn-src-projects mailing list