Date: Tue, 6 Mar 2012 21:20:16 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r232625 - head/sys/net80211 Message-ID: <201203062120.q26LKGUr058096@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Tue Mar 6 21:20:16 2012 New Revision: 232625 URL: http://svn.freebsd.org/changeset/base/232625 Log: Modify HWMP to be able to allocate memory for PREQ/PREP/PERR for all scenarios. * Added verify_mesh_*_len functions that verify the length according to the amendment spec and return number of destination addresses for allocation of appropriate struct size in memory; * Modified hwmp_recv_action_meshpath to allocate HWMP ie instead of storing them on the stack and store all available field according the flags; * Modify hwmp_add_mesh* to work with all cases of HWMP according to amendment. * Modify hwmp_send_* to calculate correct len of bytes for the HWMP ie. * Added new M_80211_MESH_* malloc defines. * Added macros with magic numbers for HWMP ie sizes according to amendment. * Added the external address to all HWMP ie structs. Submitted by: monthadar@gmail.com Modified: head/sys/net80211/ieee80211_hwmp.c head/sys/net80211/ieee80211_mesh.c head/sys/net80211/ieee80211_mesh.h Modified: head/sys/net80211/ieee80211_hwmp.c ============================================================================== --- head/sys/net80211/ieee80211_hwmp.c Tue Mar 6 21:13:12 2012 (r232624) +++ head/sys/net80211/ieee80211_hwmp.c Tue Mar 6 21:20:16 2012 (r232625) @@ -279,17 +279,114 @@ hwmp_newstate(struct ieee80211vap *vap, return 0; } +/* + * Verify the length of an HWMP PREQ and return the number + * of destinations >= 1, if verification fails -1 is returned. + */ +static int +verify_mesh_preq_len(struct ieee80211vap *vap, + const struct ieee80211_frame *wh, const uint8_t *iefrm) +{ + int alloc_sz = -1; + int ndest = -1; + if (iefrm[2] & IEEE80211_MESHPREQ_FLAGS_AE) { + /* Originator External Address present */ + alloc_sz = IEEE80211_MESHPREQ_BASE_SZ_AE; + ndest = iefrm[IEEE80211_MESHPREQ_TCNT_OFFSET_AE]; + } else { + /* w/o Originator External Address */ + alloc_sz = IEEE80211_MESHPREQ_BASE_SZ; + ndest = iefrm[IEEE80211_MESHPREQ_TCNT_OFFSET]; + } + alloc_sz += ndest * IEEE80211_MESHPREQ_TRGT_SZ; + + if(iefrm[1] != (alloc_sz)) { + IEEE80211_DISCARD(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, + wh, NULL, "PREQ (AE=%s) with wrong len", + iefrm[2] & IEEE80211_MESHPREQ_FLAGS_AE ? "1" : "0"); + return (-1); + } + return ndest; +} + +/* + * Verify the length of an HWMP PREP and returns 1 on success, + * otherwise -1. + */ +static int +verify_mesh_prep_len(struct ieee80211vap *vap, + const struct ieee80211_frame *wh, const uint8_t *iefrm) +{ + int alloc_sz = -1; + if (iefrm[2] & IEEE80211_MESHPREP_FLAGS_AE) { + if (iefrm[1] == IEEE80211_MESHPREP_BASE_SZ_AE) + alloc_sz = IEEE80211_MESHPREP_BASE_SZ_AE; + } else if (iefrm[1] == IEEE80211_MESHPREP_BASE_SZ) + alloc_sz = IEEE80211_MESHPREP_BASE_SZ; + if(alloc_sz < 0) { + IEEE80211_DISCARD(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, + wh, NULL, "PREP (AE=%s) with wrong len", + iefrm[2] & IEEE80211_MESHPREP_FLAGS_AE ? "1" : "0"); + return (-1); + } + return (1); +} + +/* + * Verify the length of an HWMP PERR and return the number + * of destinations >= 1, if verification fails -1 is returned. + */ +static int +verify_mesh_perr_len(struct ieee80211vap *vap, + const struct ieee80211_frame *wh, const uint8_t *iefrm) +{ + int alloc_sz = -1; + const uint8_t *iefrm_t = iefrm; + uint8_t ndest = iefrm_t[IEEE80211_MESHPERR_NDEST_OFFSET]; + int i; + + if(ndest > IEEE80211_MESHPERR_MAXDEST) { + IEEE80211_DISCARD(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, + wh, NULL, "PERR with wrong number of destionat (>19), %u", + ndest); + return (-1); + } + + iefrm_t += IEEE80211_MESHPERR_NDEST_OFFSET + 1; /* flag is next field */ + /* We need to check each destionation flag to know size */ + for(i = 0; i<ndest; i++) { + if ((*iefrm_t) & IEEE80211_MESHPERR_FLAGS_AE) + iefrm_t += IEEE80211_MESHPERR_DEST_SZ_AE; + else + iefrm_t += IEEE80211_MESHPERR_DEST_SZ; + } + + alloc_sz = (iefrm_t - iefrm) - 2; /* action + code */ + if(alloc_sz != iefrm[1]) { + IEEE80211_DISCARD(vap, + IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, + wh, NULL, "%s", "PERR with wrong len"); + return (-1); + } + return ndest; +} + static int hwmp_recv_action_meshpath(struct ieee80211_node *ni, const struct ieee80211_frame *wh, const uint8_t *frm, const uint8_t *efrm) { struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211_meshpreq_ie preq; - struct ieee80211_meshprep_ie prep; - struct ieee80211_meshperr_ie perr; + struct ieee80211_meshpreq_ie *preq; + struct ieee80211_meshprep_ie *prep; + struct ieee80211_meshperr_ie *perr; struct ieee80211_meshrann_ie rann; const uint8_t *iefrm = frm + 2; /* action + code */ + const uint8_t *iefrm_t = iefrm; /* temporary pointer */ + int ndest = -1; int found = 0; while (efrm - iefrm > 1) { @@ -297,66 +394,132 @@ hwmp_recv_action_meshpath(struct ieee802 switch (*iefrm) { case IEEE80211_ELEMID_MESHPREQ: { - const struct ieee80211_meshpreq_ie *mpreq = - (const struct ieee80211_meshpreq_ie *) iefrm; - /* XXX > 1 target */ - if (mpreq->preq_len != - sizeof(struct ieee80211_meshpreq_ie) - 2) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "PREQ with wrong len"); + int i = 0; + + iefrm_t = iefrm; + ndest = verify_mesh_preq_len(vap, wh, iefrm_t); + if (ndest < 0) { vap->iv_stats.is_rx_mgtdiscard++; break; } - memcpy(&preq, mpreq, sizeof(preq)); - preq.preq_id = LE_READ_4(&mpreq->preq_id); - preq.preq_origseq = LE_READ_4(&mpreq->preq_origseq); - preq.preq_lifetime = LE_READ_4(&mpreq->preq_lifetime); - preq.preq_metric = LE_READ_4(&mpreq->preq_metric); - preq.preq_targets[0].target_seq = - LE_READ_4(&mpreq->preq_targets[0].target_seq); - hwmp_recv_preq(vap, ni, wh, &preq); + preq = malloc(sizeof(*preq) + + (ndest - 1) * sizeof(*preq->preq_targets), + M_80211_MESH_PREQ, M_NOWAIT | M_ZERO); + KASSERT(preq != NULL, ("preq == NULL")); + + preq->preq_ie = *iefrm_t++; + preq->preq_len = *iefrm_t++; + preq->preq_flags = *iefrm_t++; + preq->preq_hopcount = *iefrm_t++; + preq->preq_ttl = *iefrm_t++; + preq->preq_id = LE_READ_4(iefrm_t); iefrm_t += 4; + IEEE80211_ADDR_COPY(preq->preq_origaddr, iefrm_t); + iefrm_t += 6; + preq->preq_origseq = LE_READ_4(iefrm_t); iefrm_t += 4; + /* NB: may have Originator Proxied Address */ + if (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE) { + IEEE80211_ADDR_COPY( + preq->preq_orig_ext_addr, iefrm_t); + iefrm_t += 6; + } + preq->preq_lifetime = LE_READ_4(iefrm_t); iefrm_t += 4; + preq->preq_metric = LE_READ_4(iefrm_t); iefrm_t += 4; + preq->preq_tcount = *iefrm_t++; + + for (i = 0; i < preq->preq_tcount; i++) { + preq->preq_targets[i].target_flags = *iefrm_t++; + IEEE80211_ADDR_COPY( + preq->preq_targets[i].target_addr, iefrm_t); + iefrm_t += 6; + preq->preq_targets[i].target_seq = + LE_READ_4(iefrm_t); + iefrm_t += 4; + } + + hwmp_recv_preq(vap, ni, wh, preq); + free(preq, M_80211_MESH_PREQ); found++; - break; + break; } case IEEE80211_ELEMID_MESHPREP: { - const struct ieee80211_meshprep_ie *mprep = - (const struct ieee80211_meshprep_ie *) iefrm; - if (mprep->prep_len != - sizeof(struct ieee80211_meshprep_ie) - 2) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "PREP with wrong len"); + iefrm_t = iefrm; + ndest = verify_mesh_prep_len(vap, wh, iefrm_t); + if (ndest < 0) { vap->iv_stats.is_rx_mgtdiscard++; break; } - memcpy(&prep, mprep, sizeof(prep)); - prep.prep_targetseq = LE_READ_4(&mprep->prep_targetseq); - prep.prep_lifetime = LE_READ_4(&mprep->prep_lifetime); - prep.prep_metric = LE_READ_4(&mprep->prep_metric); - prep.prep_origseq = LE_READ_4(&mprep->prep_origseq); - hwmp_recv_prep(vap, ni, wh, &prep); + prep = malloc(sizeof(*prep), + M_80211_MESH_PREP, M_NOWAIT | M_ZERO); + KASSERT(prep != NULL, ("prep == NULL")); + + prep->prep_ie = *iefrm_t++; + prep->prep_len = *iefrm_t++; + prep->prep_flags = *iefrm_t++; + prep->prep_hopcount = *iefrm_t++; + prep->prep_ttl = *iefrm_t++; + IEEE80211_ADDR_COPY(prep->prep_targetaddr, iefrm_t); + iefrm_t += 6; + prep->prep_targetseq = LE_READ_4(iefrm_t); iefrm_t += 4; + /* NB: May have Target Proxied Address */ + if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) { + IEEE80211_ADDR_COPY( + prep->prep_target_ext_addr, iefrm_t); + iefrm_t += 6; + } + prep->prep_lifetime = LE_READ_4(iefrm_t); iefrm_t += 4; + prep->prep_metric = LE_READ_4(iefrm_t); iefrm_t += 4; + IEEE80211_ADDR_COPY(prep->prep_origaddr, iefrm_t); + iefrm_t += 6; + prep->prep_origseq = LE_READ_4(iefrm_t); iefrm_t += 4; + + hwmp_recv_prep(vap, ni, wh, prep); + free(prep, M_80211_MESH_PREP); found++; break; } case IEEE80211_ELEMID_MESHPERR: { - const struct ieee80211_meshperr_ie *mperr = - (const struct ieee80211_meshperr_ie *) iefrm; - /* XXX > 1 target */ - if (mperr->perr_len != - sizeof(struct ieee80211_meshperr_ie) - 2) { - IEEE80211_DISCARD(vap, - IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, - wh, NULL, "%s", "PERR with wrong len"); + int i = 0; + + iefrm_t = iefrm; + ndest = verify_mesh_perr_len(vap, wh, iefrm_t); + if (ndest < 0) { vap->iv_stats.is_rx_mgtdiscard++; break; } - memcpy(&perr, mperr, sizeof(perr)); - perr.perr_dests[0].dest_seq = - LE_READ_4(&mperr->perr_dests[0].dest_seq); - hwmp_recv_perr(vap, ni, wh, &perr); + perr = malloc(sizeof(*perr) + + (ndest - 1) * sizeof(*perr->perr_dests), + M_80211_MESH_PERR, M_NOWAIT | M_ZERO); + KASSERT(perr != NULL, ("perr == NULL")); + + perr->perr_ie = *iefrm_t++; + perr->perr_len = *iefrm_t++; + perr->perr_ttl = *iefrm_t++; + perr->perr_ndests = *iefrm_t++; + + for (i = 0; i<perr->perr_ndests; i++) { + perr->perr_dests[i].dest_flags = *iefrm_t++; + IEEE80211_ADDR_COPY( + perr->perr_dests[i].dest_addr, iefrm_t); + iefrm_t += 6; + perr->perr_dests[i].dest_seq = LE_READ_4(iefrm_t); + iefrm_t += 4; + /* NB: May have Target Proxied Address */ + if (perr->perr_dests[i].dest_flags & + IEEE80211_MESHPERR_FLAGS_AE) { + IEEE80211_ADDR_COPY( + perr->perr_dests[i].dest_ext_addr, + iefrm_t); + iefrm_t += 6; + } + perr->perr_dests[i].dest_rcode = + LE_READ_2(iefrm_t); + iefrm_t += 2; + } + + hwmp_recv_perr(vap, ni, wh, perr); + free(perr, M_80211_MESH_PERR); found++; break; } @@ -369,7 +532,7 @@ hwmp_recv_action_meshpath(struct ieee802 IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP, wh, NULL, "%s", "RAN with wrong len"); - vap->iv_stats.is_rx_mgtdiscard++; + vap->iv_stats.is_rx_mgtdiscard++; return 1; } memcpy(&rann, mrann, sizeof(rann)); @@ -492,31 +655,40 @@ hwmp_send_action(struct ieee80211_node * /* * Add a Mesh Path Request IE to a frame. */ +#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 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_len; /* len already calculated */ *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); + if (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE) { + IEEE80211_ADDR_COPY(frm, preq->preq_orig_ext_addr); + frm += 6; + } 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++ = PREQ_TFLAGS(i); + IEEE80211_ADDR_COPY(frm, PREQ_TADDR(i)); frm += 6; - ADDWORD(frm, preq->preq_targets[i].target_seq); + ADDWORD(frm, PREQ_TSEQ(i)); } return frm; } +#undef PREQ_TFLAGS +#undef PREQ_TADDR +#undef PREQ_TSEQ /* * Add a Mesh Path Reply IE to a frame. @@ -525,12 +697,16 @@ 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_len; /* len already calculated */ *frm++ = prep->prep_flags; *frm++ = prep->prep_hopcount; *frm++ = prep->prep_ttl; IEEE80211_ADDR_COPY(frm, prep->prep_targetaddr); frm += 6; ADDWORD(frm, prep->prep_targetseq); + if (prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE) { + IEEE80211_ADDR_COPY(frm, prep->prep_target_ext_addr); + frm += 6; + } ADDWORD(frm, prep->prep_lifetime); ADDWORD(frm, prep->prep_metric); IEEE80211_ADDR_COPY(frm, prep->prep_origaddr); frm += 6; @@ -541,25 +717,38 @@ hwmp_add_meshprep(uint8_t *frm, const st /* * Add a Mesh Path Error IE to a frame. */ +#define PERR_DFLAGS(n) perr->perr_dests[n].dest_flags +#define PERR_DADDR(n) perr->perr_dests[n].dest_addr +#define PERR_DSEQ(n) perr->perr_dests[n].dest_seq +#define PERR_EXTADDR(n) perr->perr_dests[n].dest_ext_addr +#define PERR_DRCODE(n) perr->perr_dests[n].dest_rcode 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_len; /* len already calculated */ *frm++ = perr->perr_ttl; *frm++ = perr->perr_ndests; for (i = 0; i < perr->perr_ndests; i++) { - *frm++ = perr->perr_dests[i].dest_flags; - IEEE80211_ADDR_COPY(frm, perr->perr_dests[i].dest_addr); + *frm++ = PERR_DFLAGS(i); + IEEE80211_ADDR_COPY(frm, PERR_DADDR(i)); frm += 6; - ADDWORD(frm, perr->perr_dests[i].dest_seq); - ADDSHORT(frm, perr->perr_dests[i].dest_rcode); + ADDWORD(frm, PERR_DSEQ(i)); + if (PERR_DFLAGS(i) & IEEE80211_MESHPERR_FLAGS_AE) { + IEEE80211_ADDR_COPY(frm, PERR_EXTADDR(i)); + frm += 6; + } + ADDSHORT(frm, PERR_DRCODE(i)); } return frm; } +#undef PERR_DFLAGS +#undef PERR_DADDR +#undef PERR_DSEQ +#undef PERR_EXTADDR +#undef PERR_DRCODE /* * Add a Root Annoucement IE to a frame. @@ -568,12 +757,13 @@ 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_len; *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_interval); ADDWORD(frm, rann->rann_metric); return frm; } @@ -980,8 +1170,10 @@ hwmp_send_preq(struct ieee80211_node *ni * [tlv] mesh path request */ preq->preq_ie = IEEE80211_ELEMID_MESHPREQ; - return hwmp_send_action(ni, sa, da, (uint8_t *)preq, - sizeof(struct ieee80211_meshpreq_ie)); + preq->preq_len = (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE ? + IEEE80211_MESHPREQ_BASE_SZ_AE : IEEE80211_MESHPREQ_BASE_SZ) + + preq->preq_tcount * IEEE80211_MESHPREQ_TRGT_SZ; + return hwmp_send_action(ni, sa, da, (uint8_t *)preq, preq->preq_len+2); } static void @@ -1162,8 +1354,10 @@ hwmp_send_prep(struct ieee80211_node *ni * [tlv] mesh path reply */ prep->prep_ie = IEEE80211_ELEMID_MESHPREP; + prep->prep_len = prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE ? + IEEE80211_MESHPREP_BASE_SZ_AE : IEEE80211_MESHPREP_BASE_SZ; return hwmp_send_action(ni, sa, da, (uint8_t *)prep, - sizeof(struct ieee80211_meshprep_ie)); + prep->prep_len + 2); } #define PERR_DFLAGS(n) perr.perr_dests[n].dest_flags @@ -1254,8 +1448,10 @@ hwmp_recv_perr(struct ieee80211vap *vap, &pperr); } } +#undef PERR_DFLAGS #undef PEER_DADDR #undef PERR_DSEQ +#undef PERR_DRCODE static int hwmp_send_perr(struct ieee80211_node *ni, @@ -1264,6 +1460,8 @@ hwmp_send_perr(struct ieee80211_node *ni struct ieee80211_meshperr_ie *perr) { struct ieee80211_hwmp_state *hs = ni->ni_vap->iv_hwmp; + int i; + uint8_t length = 0; /* * Enforce PERR interval. @@ -1282,8 +1480,17 @@ hwmp_send_perr(struct ieee80211_node *ni * [tlv] mesh path error */ perr->perr_ie = IEEE80211_ELEMID_MESHPERR; - return hwmp_send_action(ni, sa, da, (uint8_t *)perr, - sizeof(struct ieee80211_meshperr_ie)); + length = IEEE80211_MESHPERR_BASE_SZ; + for (i = 0; i<perr->perr_ndests; i++) { + if (perr->perr_dests[i].dest_flags & + IEEE80211_MESHPERR_FLAGS_AE) { + length += IEEE80211_MESHPERR_DEST_SZ_AE; + continue ; + } + length += IEEE80211_MESHPERR_DEST_SZ; + } + perr->perr_len =length; + return hwmp_send_action(ni, sa, da, (uint8_t *)perr, perr->perr_len+2); } static void @@ -1342,8 +1549,9 @@ hwmp_send_rann(struct ieee80211_node *ni * [tlv] root annoucement */ rann->rann_ie = IEEE80211_ELEMID_MESHRANN; + rann->rann_len = IEEE80211_MESHRANN_BASE_SZ; return hwmp_send_action(ni, sa, da, (uint8_t *)rann, - sizeof(struct ieee80211_meshrann_ie)); + rann->rann_len + 2); } #define PREQ_TFLAGS(n) preq.preq_targets[n].target_flags Modified: head/sys/net80211/ieee80211_mesh.c ============================================================================== --- head/sys/net80211/ieee80211_mesh.c Tue Mar 6 21:13:12 2012 (r232624) +++ head/sys/net80211/ieee80211_mesh.c Tue Mar 6 21:20:16 2012 (r232625) @@ -142,6 +142,10 @@ static struct ieee80211_mesh_proto_metri #define MESH_RT_LOCK_ASSERT(ms) mtx_assert(&(ms)->ms_rt_lock, MA_OWNED) #define MESH_RT_UNLOCK(ms) mtx_unlock(&(ms)->ms_rt_lock) +MALLOC_DEFINE(M_80211_MESH_PREQ, "80211preq", "802.11 MESH Path Request frame"); +MALLOC_DEFINE(M_80211_MESH_PREP, "80211prep", "802.11 MESH Path Reply frame"); +MALLOC_DEFINE(M_80211_MESH_PERR, "80211perr", "802.11 MESH Path Error frame"); + MALLOC_DEFINE(M_80211_MESH_RT, "80211mesh", "802.11s routing table"); /* Modified: head/sys/net80211/ieee80211_mesh.h ============================================================================== --- head/sys/net80211/ieee80211_mesh.h Tue Mar 6 21:13:12 2012 (r232624) +++ head/sys/net80211/ieee80211_mesh.h Tue Mar 6 21:20:16 2012 (r232625) @@ -212,6 +212,7 @@ struct ieee80211_meshpann_ie { } __packed; /* Root (MP) Annoucement */ +#define IEEE80211_MESHRANN_BASE_SZ (21) struct ieee80211_meshrann_ie { uint8_t rann_ie; /* IEEE80211_ELEMID_MESHRANN */ uint8_t rann_len; @@ -221,10 +222,16 @@ struct ieee80211_meshrann_ie { uint8_t rann_ttl; uint8_t rann_addr[IEEE80211_ADDR_LEN]; uint32_t rann_seq; /* HWMP Sequence Number */ + uint32_t rann_interval; uint32_t rann_metric; } __packed; /* Mesh Path Request */ +#define IEEE80211_MESHPREQ_BASE_SZ (26) +#define IEEE80211_MESHPREQ_BASE_SZ_AE (32) +#define IEEE80211_MESHPREQ_TRGT_SZ (11) +#define IEEE80211_MESHPREQ_TCNT_OFFSET (27) +#define IEEE80211_MESHPREQ_TCNT_OFFSET_AE (33) struct ieee80211_meshpreq_ie { uint8_t preq_ie; /* IEEE80211_ELEMID_MESHPREQ */ uint8_t preq_len; @@ -238,7 +245,8 @@ struct ieee80211_meshpreq_ie { uint32_t preq_id; uint8_t preq_origaddr[IEEE80211_ADDR_LEN]; uint32_t preq_origseq; /* HWMP Sequence Number */ - /* NB: may have Originator Proxied Address */ + /* NB: may have Originator External Address */ + uint8_t preq_orig_ext_addr[IEEE80211_ADDR_LEN]; uint32_t preq_lifetime; uint32_t preq_metric; uint8_t preq_tcount; /* target count */ @@ -253,15 +261,19 @@ struct ieee80211_meshpreq_ie { } __packed; /* Mesh Path Reply */ +#define IEEE80211_MESHPREP_BASE_SZ (31) +#define IEEE80211_MESHPREP_BASE_SZ_AE (37) struct ieee80211_meshprep_ie { uint8_t prep_ie; /* IEEE80211_ELEMID_MESHPREP */ uint8_t prep_len; uint8_t prep_flags; +#define IEEE80211_MESHPREP_FLAGS_AE 0x40 /* Address Extension */ uint8_t prep_hopcount; uint8_t prep_ttl; uint8_t prep_targetaddr[IEEE80211_ADDR_LEN]; uint32_t prep_targetseq; - /* NB: May have Target Proxied Address */ + /* NB: May have Target External Address */ + uint8_t prep_target_ext_addr[IEEE80211_ADDR_LEN]; uint32_t prep_lifetime; uint32_t prep_metric; uint8_t prep_origaddr[IEEE80211_ADDR_LEN]; @@ -269,6 +281,11 @@ struct ieee80211_meshprep_ie { } __packed; /* Mesh Path Error */ +#define IEEE80211_MESHPERR_MAXDEST (19) +#define IEEE80211_MESHPERR_NDEST_OFFSET (3) +#define IEEE80211_MESHPERR_BASE_SZ (2) +#define IEEE80211_MESHPERR_DEST_SZ (13) +#define IEEE80211_MESHPERR_DEST_SZ_AE (19) struct ieee80211_meshperr_ie { uint8_t perr_ie; /* IEEE80211_ELEMID_MESHPERR */ uint8_t perr_len; @@ -276,10 +293,13 @@ struct ieee80211_meshperr_ie { uint8_t perr_ndests; /* Number of Destinations */ struct { uint8_t dest_flags; -#define IEEE80211_MESHPERR_DFLAGS_USN 0x01 -#define IEEE80211_MESHPERR_DFLAGS_RC 0x02 +#define IEEE80211_MESHPERR_DFLAGS_USN 0x01 /* XXX: not part of standard */ +#define IEEE80211_MESHPERR_DFLAGS_RC 0x02 /* XXX: not part of standard */ +#define IEEE80211_MESHPERR_FLAGS_AE 0x40 /* Address Extension */ uint8_t dest_addr[IEEE80211_ADDR_LEN]; uint32_t dest_seq; /* HWMP Sequence Number */ + /* NB: May have Destination External Address */ + uint8_t dest_ext_addr[IEEE80211_ADDR_LEN]; uint16_t dest_rcode; } __packed perr_dests[1]; /* NB: variable size */ } __packed; @@ -390,6 +410,10 @@ struct ieee80211_meshcntl_ae11 { } __packed; #ifdef _KERNEL +MALLOC_DECLARE(M_80211_MESH_PREQ); +MALLOC_DECLARE(M_80211_MESH_PREP); +MALLOC_DECLARE(M_80211_MESH_PERR); + MALLOC_DECLARE(M_80211_MESH_RT); struct ieee80211_mesh_route { TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203062120.q26LKGUr058096>