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

Rui Paulo rpaulo at FreeBSD.org
Mon Jul 6 12:20:00 UTC 2009


Author: rpaulo
Date: Mon Jul  6 12:19:59 2009
New Revision: 195406
URL: http://svn.freebsd.org/changeset/base/195406

Log:
  Modularize path metric code.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/mesh11s/sys/net80211/ieee80211_hwmp.c
  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 11:46:18 2009	(r195405)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c	Mon Jul  6 12:19:59 2009	(r195406)
@@ -757,7 +757,8 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 				 */
 				ppreq.preq_hopcount += 1;
 				ppreq.preq_ttl -= 1;
-				ppreq.preq_metric += ieee80211_airtime_calc(ni);
+				ppreq.preq_metric +=
+				    ms->ms_pmetric->mpm_metric(ni);
 				/*
 				 * Set TO and unset RF bits because we are going
 				 * to send a PREP next.
@@ -787,7 +788,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 				prep.prep_targetseq = hr->hr_seq;
 				prep.prep_lifetime = preq->preq_lifetime;
 				prep.prep_metric = rt->rt_metric +
-				    ieee80211_airtime_calc(ni);
+				    ms->ms_pmetric->mpm_metric(ni);
 				IEEE80211_ADDR_COPY(&prep.prep_origaddr,
 				    PREQ_TADDR(0));
 				prep.prep_origseq = hs->hs_seq++;
@@ -814,7 +815,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 			    ether_sprintf(preq->preq_origaddr));
 			ppreq.preq_hopcount += 1;
 			ppreq.preq_ttl -= 1;
-			ppreq.preq_metric += ieee80211_airtime_calc(ni);
+			ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni);
 			hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr,
 			    &ppreq);
 		}
@@ -895,7 +896,7 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		memcpy(&pprep, prep, sizeof(pprep));
 		pprep.prep_hopcount += 1;
 		pprep.prep_ttl -= 1;
-		pprep.prep_metric += ieee80211_airtime_calc(ni);
+		pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni);
 		IEEE80211_ADDR_COPY(pprep.prep_origaddr, vap->iv_myaddr);
 		hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep);
 	}
@@ -1131,7 +1132,7 @@ hwmp_recv_rann(struct ieee80211vap *vap,
 		memcpy(&prann, rann, sizeof(prann));
 		prann.rann_hopcount += 1;
 		prann.rann_ttl -= 1;
-		prann.rann_metric += ieee80211_airtime_calc(ni);
+		prann.rann_metric += ms->ms_pmetric->mpm_metric(ni);
 		hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr,
 		    &prann);
 	}

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c	Mon Jul  6 11:46:18 2009	(r195405)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c	Mon Jul  6 12:19:59 2009	(r195406)
@@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$");
 #include <net80211/ieee80211_input.h>
 #include <net80211/ieee80211_mesh.h>
 
+static int	mesh_select_proto_metric(struct ieee80211vap *, const char *);
 static void	mesh_vattach(struct ieee80211vap *);
 static int	mesh_newstate(struct ieee80211vap *, enum ieee80211_state, int);
 static inline void	mesh_linkchange(struct ieee80211_node *,
@@ -84,6 +85,7 @@ static inline void	mesh_peer_timeout_sto
 static int	mesh_verify_meshpeerver(struct ieee80211vap *, const uint8_t *);
 static int	mesh_verify_meshid(struct ieee80211vap *, const uint8_t *);
 static int	mesh_verify_meshconf(struct ieee80211vap *, const uint8_t *);
+uint32_t	mesh_airtime_calc(struct ieee80211_node *);
 
 /* timeout values in miliseconds */
 static const int ieee80211_mesh_retrytimeout = 40;
@@ -108,6 +110,15 @@ 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;
 
+static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = {
+	.mpm_descr	= "AIRTIME",
+	.mpm_ie		= IEEE80211_MESHCONF_AIRTIME,
+	.mpm_metric	= mesh_airtime_calc,
+};
+
+static struct ieee80211_mesh_proto_path		mesh_proto_paths[4];
+static struct ieee80211_mesh_proto_metric	mesh_proto_metrics[4];
+
 #define	MESH_RT_LOCK(ms)	mtx_lock(&(ms)->ms_rt_lock)
 #define	MESH_RT_UNLOCK(ms)	mtx_unlock(&(ms)->ms_rt_lock)
 
@@ -198,10 +209,71 @@ ieee80211_mesh_rt_flush(struct ieee80211
 	MESH_RT_UNLOCK(ms);
 }
 
+#define	N(a)	(sizeof(a) / sizeof(a[0]))
+int
+ieee80211_mesh_register_proto_path(const struct ieee80211_mesh_proto_path *mpp)
+{
+	int i, firstempty = -1;
+	static const uint8_t emptyie[4] = { 0, 0, 0, 0 };
+
+	for (i = 0; i < N(mesh_proto_paths); i++) {
+		if (memcmp(mpp->mpp_ie, mesh_proto_paths[i].mpp_ie, 4) == 0)
+			return EEXIST;
+		if (memcmp(mesh_proto_paths[i].mpp_ie, emptyie, 4) == 0 &&
+		    firstempty == -1)
+			firstempty = i;
+	}
+	if (firstempty < 0)
+		return ENOSPC;
+	memcpy(&mesh_proto_paths[firstempty], mpp, sizeof(*mpp));
+	return 0;
+}
+
+int
+ieee80211_mesh_register_proto_metric(const struct
+    ieee80211_mesh_proto_metric *mpm)
+{
+	int i, firstempty = -1;
+	static const uint8_t emptyie[4] = { 0, 0, 0, 0 };
+
+	for (i = 0; i < N(mesh_proto_metrics); i++) {
+		if (memcmp(mpm->mpm_ie, mesh_proto_metrics[i].mpm_ie, 4) == 0)
+			return EEXIST;
+		if (memcmp(mesh_proto_metrics[i].mpm_ie, emptyie, 4) == 0 &&
+		    firstempty == -1)
+			firstempty = i;
+	}
+	if (firstempty < 0)
+		return ENOSPC;
+	memcpy(&mesh_proto_metrics[firstempty], mpm, sizeof(*mpm));
+	return 0;
+}
+
+static int
+mesh_select_proto_metric(struct ieee80211vap *vap, const char *name)
+{
+	struct ieee80211_mesh_state *ms = vap->iv_mesh;
+	int i;
+
+	for (i = 0; i < N(mesh_proto_metrics); i++) {
+		if (strcmp(mesh_proto_metrics[i].mpm_descr, name) == 0) {
+			ms->ms_pmetric = &mesh_proto_metrics[i];
+			if (vap->iv_state == IEEE80211_S_RUN)
+				vap->iv_newstate(vap, IEEE80211_S_INIT, 0);
+			return 0;
+		}
+	}
+	return ENOENT;
+}
+
+#undef	N
 
 static void
 ieee80211_mesh_init(void)
 {
+	memset(mesh_proto_paths, 0, sizeof(mesh_proto_paths));
+	memset(mesh_proto_metrics, 0, sizeof(mesh_proto_metrics));
+
 	/*
 	 * Register action frame handlers.
 	 */
@@ -234,6 +306,12 @@ ieee80211_mesh_init(void)
 	ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC, 
 	    IEEE80211_ACTION_MESHLMETRIC_REP,
 	    mesh_send_action_meshlink_reply);
+
+	/*
+	 * Register Airtime Link Metric.
+	 */
+	ieee80211_mesh_register_proto_metric(&mesh_metric_airtime);
+
 }
 SYSINIT(wlan_mesh, SI_SUB_DRIVERS, SI_ORDER_FIRST, ieee80211_mesh_init, NULL);
 
@@ -284,7 +362,6 @@ static void
 mesh_vattach(struct ieee80211vap *vap)
 {
 	struct ieee80211_mesh_state *ms;
-
 	vap->iv_newstate = mesh_newstate;
 	vap->iv_input = mesh_input;
 	vap->iv_opdetach = mesh_vdetach;
@@ -301,6 +378,7 @@ mesh_vattach(struct ieee80211vap *vap)
 	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);
+	mesh_select_proto_metric(vap, "AIRTIME");
 	ieee80211_hwmp_vattach(vap);
 }
 
@@ -326,7 +404,7 @@ mesh_newstate(struct ieee80211vap *vap, 
                 ieee80211_cancel_scan(vap);     /* background scan */
 	ni = vap->iv_bss;			/* NB: no reference held */
 	/* Flush the routing table */
-	if (nstate != INIT && ostate == INIT)
+	if (nstate != IEEE80211_S_INIT && ostate == IEEE80211_S_INIT)
 		ieee80211_mesh_rt_flush(vap);
 	switch (nstate) {
 	case IEEE80211_S_INIT:
@@ -1541,8 +1619,7 @@ mesh_recv_action_meshlmetric_req(struct 
 {
 	uint32_t metric;
 
-	/* XXX: check if we are using airtime or aother algorithm */
-	metric = ieee80211_airtime_calc(ni);
+	metric = mesh_airtime_calc(ni);
 	ieee80211_send_action(ni,
 	    IEEE80211_ACTION_CAT_MESHLMETRIC,
 	    IEEE80211_ACTION_MESHLMETRIC_REP,
@@ -2188,7 +2265,7 @@ ieee80211_add_meshpeer(uint8_t *frm, uin
          + IEEE80211_WEP_MICLEN \
          + IEEE80211_CRC_LEN)
 uint32_t
-ieee80211_airtime_calc(struct ieee80211_node *ni)
+mesh_airtime_calc(struct ieee80211_node *ni)
 {
 #define M_BITS 8
 #define S_FACTOR (2 * M_BITS)

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.h	Mon Jul  6 11:46:18 2009	(r195405)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.h	Mon Jul  6 12:19:59 2009	(r195406)
@@ -389,25 +389,42 @@ struct ieee80211_mesh_route {
 };
 #define	IEEE80211_MESH_ROUTE_PRIV(rt, cast)	(cast *)rt->rt_priv
 
-struct ieee80211_mesh_proto {
-	/* Action frame categories to intercept */
-	uint8_t			mpr_actpath;
-	uint8_t			mpr_actlinkmetric;
-	/* Values to be sent in the Mesh Configuration IE */
-	uint8_t			mpr_pathid[4];
-	uint8_t			mpr_metricid[4];
-	uint8_t			mpr_congid[4];
-	uint8_t			mpr_syncid[4];
-	uint8_t			mpr_authid[4];
-	void			(*mpr_recv_action)(struct ieee80211vap *,
-				struct ieee80211_node *, struct mbuf *);
-	struct ieee80211_node * (*mpr_discover)(struct ieee80211vap *,
-				uint8_t [IEEE80211_ADDR_LEN], struct mbuf *);
-	struct ieee80211_node * (*mpr_find_txnode)(struct ieee80211vap *vap,
-				uint8_t dest[IEEE80211_ADDR_LEN]);
-	uint32_t		(*mpr_linkmetric)(struct ieee80211_node *);
-	/* XXX needs more methods */
+/*
+ * Mesh Path Selection Protocol.
+ */
+struct ieee80211_mesh_proto_path {
+	char 		mpp_descr[12];
+	uint8_t		mpp_ie[4];
+	struct ieee80211_node *
+	    		(*mpr_discover)(struct ieee80211vap *,
+				uint8_t [IEEE80211_ADDR_LEN],
+				struct mbuf *);
+	size_t		mpp_privlen;	/* size required in the routing table
+					   for private data */
 };
+/*
+ * Mesh Link Metric Report Protocol.
+ */
+struct ieee80211_mesh_proto_metric {
+	char		mpm_descr[12];
+	uint8_t		mpm_ie[4];
+	uint32_t	(*mpm_metric)(struct ieee80211_node *);
+};
+
+#ifdef notyet
+/*
+ * Mesh Authentication Protocol.
+ */
+struct ieee80211_mesh_proto_auth {
+	uint8_t		mpa_ie[4];
+};
+
+struct ieee80211_mesh_proto_congestion {
+};
+
+struct ieee80211_mesh_proto_sync {
+};
+#endif
 
 typedef uint32_t ieee80211_mesh_seq;
 #define	IEEE80211_MESH_SEQ_LEQ(a, b)	((int32_t)((a)-(b)) <= 0)
@@ -423,8 +440,10 @@ struct ieee80211_mesh_state {
 #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;
+	TAILQ_HEAD(, ieee80211_mesh_route)
+	   			ms_routes;
+	struct ieee80211_mesh_proto_metric
+	    			*ms_pmetric;
 };
 void		ieee80211_mesh_attach(struct ieee80211com *);
 void		ieee80211_mesh_detach(struct ieee80211com *);
@@ -439,12 +458,16 @@ void		ieee80211_mesh_rt_del(struct ieee8
 		    const uint8_t [IEEE80211_ADDR_LEN]);
 void		ieee80211_mesh_rt_flush(struct ieee80211vap *);
 
+int		ieee80211_mesh_register_proto_path(const
+		    struct ieee80211_mesh_proto_path *);
+int		ieee80211_mesh_register_proto_metric(const
+		    struct ieee80211_mesh_proto_metric *);
+
 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 *);
 uint8_t *	ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
 		    uint16_t);
-uint32_t	ieee80211_airtime_calc(struct ieee80211_node *);
 uint8_t *	ieee80211_add_meshlmetric(uint8_t *, uint32_t);
 
 void		ieee80211_mesh_node_init(struct ieee80211vap *,


More information about the svn-src-projects mailing list