Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 1 Jun 2009 12:18:51 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r193226 - projects/mesh11s/sys/net80211
Message-ID:  <200906011218.n51CIp60078512@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Mon Jun  1 12:18:51 2009
New Revision: 193226
URL: http://svn.freebsd.org/changeset/base/193226

Log:
  * add hwmp_add_meshpreq(), hwmp_add_meshprep(), hwmp_add_meshperr()
    hwmp_add_meshrann() functions that construct the respective IE.
  * add HWMP state struct containing the head of the forwarding
    information table, the next sequence number to be used and the lock for
    the table;
  * implement vattach and vdetach routines in HWMP. These alloc/setup and
    destroy an HWMP state struct respectively;
  * lock/unlock when doing table lookups (inserts not yet implemented)
  * use the seq number now that we have it
  * remove ie/len code setup from send functions.
  * add _KERNEL protection in ieee80211_hwmp.h
  * add hwmp state pointer to ieee80211_vap
  
  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
  projects/mesh11s/sys/net80211/ieee80211_var.h

Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c	Mon Jun  1 11:38:38 2009	(r193225)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c	Mon Jun  1 12:18:51 2009	(r193226)
@@ -63,29 +63,35 @@ __FBSDID("$FreeBSD$");
 #include <net80211/ieee80211_hwmp.h>
 #include <net80211/ieee80211_input.h>
 
-TAILQ_HEAD(, ieee80211_hwmp_fi)	ieee80211_hwmp_ft;
-
 static int	ieee80211_hwmp_send_action(struct ieee80211_node *,
 	const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
 	const uint8_t *, size_t);
+static uint8_t *hwmp_add_meshpreq(uint8_t *,
+    const struct ieee80211_meshpreq_ie *);
+static uint8_t *hwmp_add_meshprep(uint8_t *,
+    const struct ieee80211_meshprep_ie *);
+static uint8_t *hwmp_add_meshperr(uint8_t *,
+    const struct ieee80211_meshperr_ie *);
+static uint8_t *hwmp_add_meshrann(uint8_t *,
+    const struct ieee80211_meshrann_ie *);
 static void	hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *,
     const struct ieee80211_meshpreq_ie *);
-static int	hwmp_send_preq(struct ieee80211_node *,
+static inline int hwmp_send_preq(struct ieee80211_node *,
     const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
     struct ieee80211_meshpreq_ie *);
 static void	hwmp_recv_prep(struct ieee80211vap *, struct ieee80211_node *,
     const struct ieee80211_meshprep_ie *);
-static int	hwmp_send_prep(struct ieee80211_node *,
+static inline int hwmp_send_prep(struct ieee80211_node *,
     const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
     struct ieee80211_meshprep_ie *);
 static void	hwmp_recv_perr(struct ieee80211vap *, struct ieee80211_node *,
     const struct ieee80211_meshperr_ie *);
-static int	hwmp_send_perr(struct ieee80211_node *,
+static inline int hwmp_send_perr(struct ieee80211_node *,
     const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
     struct ieee80211_meshperr_ie *);
 static void	hwmp_recv_rann(struct ieee80211vap *, struct ieee80211_node *,
    const  struct ieee80211_meshrann_ie *);
-static int	hwmp_send_rann(struct ieee80211_node *,
+static inline int hwmp_send_rann(struct ieee80211_node *,
     const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
     struct ieee80211_meshrann_ie *);
 
@@ -138,6 +144,34 @@ SYSCTL_INT(_net_wlan_hwmp, OID_AUTO, roo
 extern int	ieee80211_mesh_ttl;
 extern int	ieee80211_mesh_forwarding;
 
+void
+ieee80211_hwmp_vattach(struct ieee80211vap *vap)
+{
+	struct ieee80211_hwmp_state *hs;
+
+	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_VAP,
+	    M_NOWAIT | M_ZERO);
+	if (hs == NULL) {
+		printf("%s: couldn't alloc HWMP state\n", __func__);
+		return;
+	}
+	TAILQ_INIT(&hs->hs_head);
+	mtx_init(&hs->hs_lock, "HWMP", "802.11s HWMP", MTX_DEF);
+	vap->iv_hwmp = hs;
+}
+
+void
+ieee80211_hwmp_vdetach(struct ieee80211vap *vap)
+{
+	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
+
+	/* XXX missing flush table */
+	mtx_destroy(&hs->hs_lock);
+	free(vap->iv_hwmp, M_80211_VAP);
+}
 
 void
 ieee80211_hwmp_recv_action(struct ieee80211vap *vap, struct ieee80211_node *ni,
@@ -290,17 +324,23 @@ ieee80211_hwmp_send_action(struct ieee80
 	switch (*ie) {
 	case IEEE80211_ELEMID_MESHPREQ:
 		*frm++ = IEEE80211_ACTION_MESHPATH_REQ;
+		frm = hwmp_add_meshpreq(frm,
+		    (struct ieee80211_meshpreq_ie *)&ie);
 		break;
 	case IEEE80211_ELEMID_MESHPREP:
 		*frm++ = IEEE80211_ACTION_MESHPATH_REP;
-		frm = ieee80211_add_meshprep(frm,
+		frm = hwmp_add_meshprep(frm,
 		    (struct ieee80211_meshprep_ie *)&ie);
 		break;
 	case IEEE80211_ELEMID_MESHPERR:
 		*frm++ = IEEE80211_ACTION_MESHPATH_ERR;
+		frm = hwmp_add_meshperr(frm,
+		    (struct ieee80211_meshperr_ie *)&ie);
 		break;
 	case IEEE80211_ELEMID_MESHRANN:
 		*frm++ = IEEE80211_ACTION_MESHPATH_RANN;
+		frm = hwmp_add_meshrann(frm,
+		    (struct ieee80211_meshrann_ie *)&ie);
 		break;
 	}
 
@@ -336,29 +376,96 @@ ieee80211_hwmp_send_action(struct ieee80
 	frm += 4;			\
 } while (0)
 /*
- * Add a Mesh Path Reply IE to a frame.
+ * Add a Mesh Path Request IE to a frame.
  */
-uint8_t *
-ieee80211_add_meshprep(uint8_t *frm, const struct ieee80211_meshprep_ie *prep)
+static uint8_t *
+hwmp_add_meshpreq(uint8_t *frm, const struct ieee80211_meshpreq_ie *preq)
 {
+	int i;
+
+	*frm++ = IEEE80211_ELEMID_MESHPREQ;
+	*frm++ = sizeof(struct ieee80211_meshpreq_ie) - 2 +
+	    (preq->preq_tcount - 1) * sizeof(*preq->preq_targets);
+	*frm++ = preq->preq_flags;
+	*frm++ = preq->preq_hopcount;
+	*frm++ = preq->preq_ttl;
+	ADDWORD(frm, preq->preq_id);
+	IEEE80211_ADDR_COPY(frm, preq->preq_origaddr); frm += 6;
+	ADDWORD(frm, preq->preq_origseq);
+	ADDWORD(frm, preq->preq_lifetime);
+	ADDWORD(frm, preq->preq_metric);
+	*frm++ = preq->preq_tcount;
+	for (i = 0; i < preq->preq_tcount; i++) {
+		*frm++ = preq->preq_targets[i].target_flags;
+		IEEE80211_ADDR_COPY(frm, preq->preq_targets[i].target_addr);
+		frm += 6;
+		ADDWORD(frm, preq->preq_targets[i].target_seq);
+	}
+
+	return frm;
+}
 
+/*
+ * Add a Mesh Path Reply IE to a frame.
+ */
+static uint8_t *
+hwmp_add_meshprep(uint8_t *frm, const struct ieee80211_meshprep_ie *prep)
+{
 	*frm++ = IEEE80211_ELEMID_MESHPREP;
 	*frm++ = sizeof(struct ieee80211_meshprep_ie) - 2;
 	*frm++ = prep->prep_flags;
 	*frm++ = prep->prep_hopcount;
 	*frm++ = prep->prep_ttl;
-	IEEE80211_ADDR_COPY(frm, prep->prep_targetaddr);
-	frm += 6;
+	IEEE80211_ADDR_COPY(frm, prep->prep_targetaddr); frm += 6;
 	ADDWORD(frm, prep->prep_targetseq);
 	ADDWORD(frm, prep->prep_lifetime);
 	ADDWORD(frm, prep->prep_metric);
-	IEEE80211_ADDR_COPY(frm, prep->prep_origaddr);
-	frm += 6;
+	IEEE80211_ADDR_COPY(frm, prep->prep_origaddr); frm += 6;
 	ADDWORD(frm, prep->prep_origseq);
 
 	return frm;
 }
 
+/*
+ * Add a Mesh Path Error IE to a frame.
+ */
+static uint8_t *
+hwmp_add_meshperr(uint8_t *frm, const struct ieee80211_meshperr_ie *perr)
+{
+	int i;
+
+	*frm++ = IEEE80211_ELEMID_MESHPERR;
+	*frm++ = sizeof(struct ieee80211_meshperr_ie) - 2 +
+	    (perr->perr_ndests - 1) * sizeof(*perr->perr_dests);
+	*frm++ = perr->perr_mode;
+	*frm++ = perr->perr_ndests;
+	for (i = 0; i < perr->perr_ndests; i++) {
+		IEEE80211_ADDR_COPY(frm, perr->perr_dests[i].dest_addr);
+		frm += 6;
+		ADDWORD(frm, perr->perr_dests[i].dest_seq);
+	}
+
+	return frm;
+}
+
+/*
+ * Add a Root Annoucement IE to a frame.
+ */
+static uint8_t *
+hwmp_add_meshrann(uint8_t *frm, const struct ieee80211_meshrann_ie *rann)
+{
+	*frm++ = IEEE80211_ELEMID_MESHRANN;
+	*frm++ = sizeof(struct ieee80211_meshrann_ie) - 2;
+	*frm++ = rann->rann_flags;
+	*frm++ = rann->rann_hopcount;
+	*frm++ = rann->rann_ttl;
+	IEEE80211_ADDR_COPY(frm, rann->rann_addr); frm += 6;
+	ADDWORD(frm, rann->rann_seq);
+	ADDWORD(frm, rann->rann_metric);
+
+	return frm;
+}
+
 #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
@@ -366,7 +473,8 @@ static void
 hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
     const struct ieee80211_meshpreq_ie *preq)
 {
-	struct ieee80211_hwmp_fi *fi;
+	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
+	struct ieee80211_hwmp_fi *fi = NULL;
 
 	/*
 	 * Acceptance criteria: if the PREQ is not for us and
@@ -376,13 +484,12 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 	    !ieee80211_mesh_forwarding)
 		return;
 
-	fi = NULL;
-	/*HWMP_LOCK();*/
-	TAILQ_FOREACH(fi, &ieee80211_hwmp_ft, fi_next) {
+	mtx_lock(&hs->hs_lock);
+	TAILQ_FOREACH(fi, &hs->hs_head, fi_next) {
 		if (IEEE80211_ADDR_EQ(PREQ_TADDR(0), fi->fi_dest))
 			break;
 	}
-	/*HWMP_UNLOCK();*/
+	mtx_unlock(&hs->hs_lock);
 
 	/*
 	 * Step 1. Record the PREQ ID and the originator MAC address.
@@ -410,8 +517,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		prep.prep_lifetime = preq->preq_lifetime;
 		prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
 		IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr);
-		/* XXX */
-		prep.prep_origseq = 1;
+		prep.prep_origseq = hs->hs_seq++;
 		/* XXX addr1 = next hop */
 		hwmp_send_prep(ni, preq->preq_origaddr, vap->iv_myaddr, &prep);
 		return;
@@ -463,8 +569,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 			prep.prep_metric = fi->fi_metric;
 			IEEE80211_ADDR_COPY(&prep.prep_origaddr,
 			    vap->iv_myaddr);
-			/* XXX */
-			prep.prep_origseq = 1;
+			prep.prep_origseq = hs->hs_seq++;
 			hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr,
 			    &prep);
 		} else {
@@ -520,10 +625,6 @@ hwmp_send_preq(struct ieee80211_node *ni
 	 *     [1] category
 	 *     [tlv] mesh path request
 	 */
-	/* XXX target count > 1 */
-	preq->preq_ie = IEEE80211_ELEMID_MESHPREQ;
-	preq->preq_len = sizeof(struct ieee80211_meshpreq_ie) - 2;
-
 	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&preq,
 	    sizeof(*preq));
 }
@@ -559,7 +660,6 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		pprep.prep_ttl -= 1;
 		pprep.prep_metric += ieee80211_airtime_calc(ni);
 		IEEE80211_ADDR_COPY(pprep.prep_origaddr, vap->iv_myaddr);
-		pprep.prep_origseq = 1; /* XXX */
 		hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr,
 		    &pprep);
 		/*
@@ -596,9 +696,6 @@ hwmp_send_prep(struct ieee80211_node *ni
 	 *     [1] category
 	 *     [tlv] mesh path reply
 	 */
-	prep->prep_ie = IEEE80211_ELEMID_MESHPREP;
-	prep->prep_len = sizeof(struct ieee80211_meshprep_ie) - 2;
-
 	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&prep,
 	    sizeof(*prep));
 }
@@ -609,7 +706,8 @@ static void
 hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
     const struct ieee80211_meshperr_ie *perr)
 {
-	struct ieee80211_hwmp_fi *fi;
+	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
+	struct ieee80211_hwmp_fi *fi = NULL;
 /* 	struct ieee80211_meshperr_ie pperr;*/
 
 	/*
@@ -621,12 +719,12 @@ hwmp_recv_perr(struct ieee80211vap *vap,
 	    !ieee80211_mesh_forwarding)
 		return;
 
-	fi = NULL;
-	/*HWMP_LOCK();*/
-	TAILQ_FOREACH(fi, &ieee80211_hwmp_ft, fi_next) {
+	mtx_lock(&hs->hs_lock);
+	TAILQ_FOREACH(fi, &hs->hs_head, fi_next) {
 		if (IEEE80211_ADDR_EQ(PERR_DADDR(0), fi->fi_dest))
 			break;
 	}
+	mtx_unlock(&hs->hs_lock);
 
 	if (fi == NULL)
 		return;
@@ -652,9 +750,6 @@ hwmp_send_perr(struct ieee80211_node *ni
 	 *     [1] category
 	 *     [tlv] mesh path error
 	 */
-	perr->perr_ie = IEEE80211_ELEMID_MESHPERR;
-	perr->perr_len = sizeof(struct ieee80211_meshperr_ie) - 2;
-
 	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&perr,
 	    sizeof(*perr));
 }
@@ -663,19 +758,19 @@ static void
 hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni,
     const struct ieee80211_meshrann_ie *rann)
 {
-	struct ieee80211_hwmp_fi *fi;
+	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
+	struct ieee80211_hwmp_fi *fi = NULL;
 
 	/*
 	 * Acceptance criteria: check the HWMP sequence number
 	 * and the path metric is better than what we have.
 	 */
-	fi = NULL;
-	/*HWMP_LOCK();*/
-	TAILQ_FOREACH(fi, &ieee80211_hwmp_ft, fi_next) {
+	mtx_lock(&hs->hs_lock);
+	TAILQ_FOREACH(fi, &hs->hs_head, fi_next) {
 		if (IEEE80211_ADDR_EQ(rann->rann_addr, fi->fi_dest))
 			break;
 	}
-	/*HWMP_UNLOCK();*/
+	mtx_unlock(&hs->hs_lock);
 
 	if (fi == NULL) {
 		struct ieee80211_meshpreq_ie preq;
@@ -688,7 +783,7 @@ hwmp_recv_rann(struct ieee80211vap *vap,
 		preq.preq_ttl = ieee80211_mesh_ttl;
 		IEEE80211_ADDR_COPY(&preq.preq_origaddr,
 		    vap->iv_myaddr);
-		preq.preq_origseq = 0; /* XXX */
+		preq.preq_origseq = hs->hs_seq++;
 		preq.preq_targets[0].target_flags |=
 		    IEEE80211_MESHPREQ_TFLAGS_TO;
 		IEEE80211_ADDR_COPY(preq.preq_targets[0].target_addr,
@@ -713,7 +808,7 @@ hwmp_recv_rann(struct ieee80211vap *vap,
 	}
 }
 
-static int
+static inline int
 hwmp_send_rann(struct ieee80211_node *ni,
     const uint8_t addr1[IEEE80211_ADDR_LEN],
     const uint8_t addr2[IEEE80211_ADDR_LEN],
@@ -728,9 +823,6 @@ hwmp_send_rann(struct ieee80211_node *ni
 	 *     [1] category
 	 *     [tlv] root annoucement
 	 */
-	rann->rann_ie = IEEE80211_ELEMID_MESHRANN;
-	rann->rann_len = sizeof(struct ieee80211_meshrann_ie) - 2;
-
 	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&rann,
 	    sizeof(*rann));
 }

Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.h	Mon Jun  1 11:38:38 2009	(r193225)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.h	Mon Jun  1 12:18:51 2009	(r193226)
@@ -45,15 +45,17 @@ struct ieee80211_hwmp_fi {
 	uint32_t	fi_lifetime;
 };
 
+#ifdef _KERNEL
+struct ieee80211_hwmp_state {
+	TAILQ_HEAD(, ieee80211_hwmp_fi)	hs_head;
+	ieee80211_seq			hs_seq;	    /* next seq to be used */
+	struct mtx			hs_lock;    /* lock for the fi table */
+};
+
+void		ieee80211_hwmp_vattach(struct ieee80211vap *);
+void		ieee80211_hwmp_vdetach(struct ieee80211vap *);
 void		ieee80211_hwmp_recv_action(struct ieee80211vap *,
     struct ieee80211_node *, struct mbuf *);
-uint8_t *	ieee80211_add_meshprep(uint8_t *,
-    const struct ieee80211_meshprep_ie *);
-#if 0
-uint8_t	*	ieee80211_add_meshpreq(uint8_t *,
-    struct ieee80211_meshpreq_ie *);
-uint8_t *	ieee80211_add_meshperr(uint8_t *,
-    struct ieee80211_meshperr_ie *);
-#endif
+#endif /* _KERNEL */
 
 #endif /* _NET80211_IEEE80211_HWMP_H_ */

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c	Mon Jun  1 11:38:38 2009	(r193225)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c	Mon Jun  1 12:18:51 2009	(r193226)
@@ -119,6 +119,7 @@ ieee80211_mesh_detach(struct ieee80211co
 static void
 mesh_vdetach(struct ieee80211vap *vap)
 {
+	ieee80211_hwmp_vdetach(vap);
 }
 
 static void
@@ -128,6 +129,7 @@ mesh_vattach(struct ieee80211vap *vap)
 	vap->iv_input = mesh_input;
 	vap->iv_opdetach = mesh_vdetach;
 	vap->iv_recv_mgmt = mesh_recv_mgmt;
+	ieee80211_hwmp_vattach(vap);
 }
 
 /*

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.h	Mon Jun  1 11:38:38 2009	(r193225)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.h	Mon Jun  1 12:18:51 2009	(r193226)
@@ -272,7 +272,7 @@ struct ieee80211_meshprep_ie {
 struct ieee80211_meshperr_ie {
 	uint8_t		perr_ie;	/* IEEE80211_ELEMID_MESHPERR */
 	uint8_t		perr_len;
-	uint8_t		perr_mode;
+	uint8_t		perr_mode;	/* NB: reserved */
 	uint8_t		perr_ndests;	/* Number of Destinations */
 	struct {
 		uint8_t		dest_addr[IEEE80211_ADDR_LEN];

Modified: projects/mesh11s/sys/net80211/ieee80211_var.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_var.h	Mon Jun  1 11:38:38 2009	(r193225)
+++ projects/mesh11s/sys/net80211/ieee80211_var.h	Mon Jun  1 12:18:51 2009	(r193226)
@@ -427,6 +427,7 @@ struct ieee80211vap {
 	void			*iv_as;		/* private aclator state */
 
 	struct ieee80211_tdma_state *iv_tdma;	/* tdma state */
+	struct ieee80211_hwmp_state *iv_hwmp;	/* HWMP state */
 
 	/* operate-mode detach hook */
 	void			(*iv_opdetach)(struct ieee80211vap *);



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