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>