svn commit: r193226 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Mon Jun 1 12:18:51 UTC 2009
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 *);
More information about the svn-src-projects
mailing list