svn commit: r197614 - stable/8/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Tue Sep 29 12:18:24 UTC 2009
Author: rpaulo
Date: Tue Sep 29 12:18:23 2009
New Revision: 197614
URL: http://svn.freebsd.org/changeset/base/197614
Log:
Update 802.11s mesh support to draft 3.03. This includes a revised frame
format for peering and changes to the PERR frames.
Note that this is incompatible with the previous code.
Reviewed by: sam
Approved by: re (kib)
Modified:
stable/8/sys/net80211/ieee80211.h
stable/8/sys/net80211/ieee80211_hwmp.c
stable/8/sys/net80211/ieee80211_mesh.c
stable/8/sys/net80211/ieee80211_mesh.h
Modified: stable/8/sys/net80211/ieee80211.h
==============================================================================
--- stable/8/sys/net80211/ieee80211.h Tue Sep 29 10:53:06 2009 (r197613)
+++ stable/8/sys/net80211/ieee80211.h Tue Sep 29 12:18:23 2009 (r197614)
@@ -708,7 +708,7 @@ enum {
IEEE80211_ELEMID_VENDOR = 221, /* vendor private */
/*
- * 802.11s IEs based on D3.0 spec and were not assigned by
+ * 802.11s IEs based on D3.03 spec and were not assigned by
* ANA. Beware changing them because some of them are being
* kept compatible with Linux.
*/
@@ -726,10 +726,9 @@ enum {
IEEE80211_ELEMID_MESHPREQ = 68,
IEEE80211_ELEMID_MESHPREP = 69,
IEEE80211_ELEMID_MESHPERR = 70,
- IEEE80211_ELEMID_MESHPU = 53,
- IEEE80211_ELEMID_MESHPUC = 54,
+ IEEE80211_ELEMID_MESHPXU = 53,
+ IEEE80211_ELEMID_MESHPXUC = 54,
IEEE80211_ELEMID_MESHAH = 60, /* Abbreviated Handshake */
- IEEE80211_ELEMID_MESHPEERVER = 80, /* Peering Protocol Version */
};
struct ieee80211_tim_ie {
@@ -925,6 +924,9 @@ enum {
IEEE80211_REASON_MESH_INVALID_GTK = 8, /* 11s */
IEEE80211_REASON_MESH_INCONS_PARAMS = 9, /* 11s */
IEEE80211_REASON_MESH_INVALID_SECURITY = 10, /* 11s */
+ IEEE80211_REASON_MESH_PERR_UNSPEC = 11, /* 11s */
+ IEEE80211_REASON_MESH_PERR_NO_FI = 12, /* 11s */
+ IEEE80211_REASON_MESH_PERR_DEST_UNREACH = 13, /* 11s */
IEEE80211_STATUS_SUCCESS = 0,
IEEE80211_STATUS_UNSPECIFIED = 1,
Modified: stable/8/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- stable/8/sys/net80211/ieee80211_hwmp.c Tue Sep 29 10:53:06 2009 (r197613)
+++ stable/8/sys/net80211/ieee80211_hwmp.c Tue Sep 29 12:18:23 2009 (r197614)
@@ -188,10 +188,7 @@ SYSCTL_PROC(_net_wlan_hwmp, OID_AUTO, ra
#define IEEE80211_HWMP_DEFAULT_MAXHOPS 31
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_preq;
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_prep;
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_perr;
-static ieee80211_recv_action_func hwmp_recv_action_meshpath_rann;
+static ieee80211_recv_action_func hwmp_recv_action_meshpath;
static struct ieee80211_mesh_proto_path mesh_proto_hwmp = {
.mpp_descr = "HWMP",
@@ -217,16 +214,10 @@ ieee80211_hwmp_init(void)
ieee80211_hwmp_rannint = msecs_to_ticks(1*1000);
/*
- * Register action frame handlers.
+ * Register action frame handler.
*/
ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_REQ, hwmp_recv_action_meshpath_preq);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_REP, hwmp_recv_action_meshpath_prep);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_ERR, hwmp_recv_action_meshpath_perr);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_RANN, hwmp_recv_action_meshpath_rann);
+ IEEE80211_ACTION_MESHPATH_SEL, hwmp_recv_action_meshpath);
/* NB: default is 5 secs per spec */
mesh_proto_hwmp.mpp_inact = msecs_to_ticks(5*1000);
@@ -285,17 +276,23 @@ hwmp_newstate(struct ieee80211vap *vap,
}
static int
-hwmp_recv_action_meshpath_preq(struct ieee80211_node *ni,
+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_meshrann_ie rann;
const uint8_t *iefrm = frm + 2; /* action + code */
+ int found = 0;
while (efrm - iefrm > 1) {
IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHPREQ) {
+ switch (*iefrm) {
+ case IEEE80211_ELEMID_MESHPREQ:
+ {
const struct ieee80211_meshpreq_ie *mpreq =
(const struct ieee80211_meshpreq_ie *) iefrm;
/* XXX > 1 target */
@@ -305,7 +302,7 @@ hwmp_recv_action_meshpath_preq(struct ie
IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
wh, NULL, "%s", "PREQ with wrong len");
vap->iv_stats.is_rx_mgtdiscard++;
- return 1;
+ break;
}
memcpy(&preq, mpreq, sizeof(preq));
preq.preq_id = LE_READ_4(&mpreq->preq_id);
@@ -315,28 +312,11 @@ hwmp_recv_action_meshpath_preq(struct ie
preq.preq_targets[0].target_seq =
LE_READ_4(&mpreq->preq_targets[0].target_seq);
hwmp_recv_preq(vap, ni, wh, &preq);
- return 0;
+ found++;
+ break;
}
- iefrm += iefrm[1] + 2;
- }
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "PREQ without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
- return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_prep(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_meshprep_ie prep;
- const uint8_t *iefrm = frm + 2; /* action + code */
-
- while (efrm - iefrm > 1) {
- IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHPREP) {
+ case IEEE80211_ELEMID_MESHPREP:
+ {
const struct ieee80211_meshprep_ie *mprep =
(const struct ieee80211_meshprep_ie *) iefrm;
if (mprep->prep_len !=
@@ -345,7 +325,7 @@ hwmp_recv_action_meshpath_prep(struct ie
IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
wh, NULL, "%s", "PREP with wrong len");
vap->iv_stats.is_rx_mgtdiscard++;
- return 1;
+ break;
}
memcpy(&prep, mprep, sizeof(prep));
prep.prep_targetseq = LE_READ_4(&mprep->prep_targetseq);
@@ -353,28 +333,11 @@ hwmp_recv_action_meshpath_prep(struct ie
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);
- return 0;
+ found++;
+ break;
}
- iefrm += iefrm[1] + 2;
- }
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "PREP without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
- return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_perr(struct ieee80211_node *ni,
- const struct ieee80211_frame *wh,
- const uint8_t *frm, const uint8_t *efrm)
-{
- struct ieee80211_meshperr_ie perr;
- struct ieee80211vap *vap = ni->ni_vap;
- const uint8_t *iefrm = frm + 2; /* action + code */
-
- while (efrm - iefrm > 1) {
- IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHPERR) {
+ case IEEE80211_ELEMID_MESHPERR:
+ {
const struct ieee80211_meshperr_ie *mperr =
(const struct ieee80211_meshperr_ie *) iefrm;
/* XXX > 1 target */
@@ -384,34 +347,17 @@ hwmp_recv_action_meshpath_perr(struct ie
IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
wh, NULL, "%s", "PERR with wrong len");
vap->iv_stats.is_rx_mgtdiscard++;
- return 1;
+ 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);
- return 0;
+ found++;
+ break;
}
- iefrm += iefrm[1] + 2;
- }
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "PERR without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
- return 0;
-}
-
-static int
-hwmp_recv_action_meshpath_rann(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_meshrann_ie rann;
- const uint8_t *iefrm = frm + 2; /* action + code */
-
- while (efrm - iefrm > 1) {
- IEEE80211_VERIFY_LENGTH(efrm - iefrm, iefrm[1] + 2, return 0);
- if (*iefrm == IEEE80211_ELEMID_MESHRANN) {
+ case IEEE80211_ELEMID_MESHRANN:
+ {
const struct ieee80211_meshrann_ie *mrann =
(const struct ieee80211_meshrann_ie *) iefrm;
if (mrann->rann_len !=
@@ -426,13 +372,18 @@ hwmp_recv_action_meshpath_rann(struct ie
rann.rann_seq = LE_READ_4(&mrann->rann_seq);
rann.rann_metric = LE_READ_4(&mrann->rann_metric);
hwmp_recv_rann(vap, ni, wh, &rann);
- return 0;
+ found++;
+ break;
+ }
}
iefrm += iefrm[1] + 2;
}
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
- wh, NULL, "%s", "RANN without IE");
- vap->iv_stats.is_rx_mgtdiscard++;
+ if (!found) {
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_HWMP,
+ wh, NULL, "%s", "PATH SEL action without IE");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ }
return 0;
}
@@ -480,24 +431,21 @@ hwmp_send_action(struct ieee80211_node *
return ENOMEM;
}
*frm++ = IEEE80211_ACTION_CAT_MESHPATH;
+ *frm++ = IEEE80211_ACTION_MESHPATH_SEL;
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 = 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;
@@ -528,6 +476,11 @@ hwmp_send_action(struct ieee80211_node *
return ic->ic_raw_xmit(ni, m, ¶ms);
}
+#define ADDSHORT(frm, v) do { \
+ frm[0] = (v) & 0xff; \
+ frm[1] = (v) >> 8; \
+ frm += 2; \
+} while (0)
#define ADDWORD(frm, v) do { \
LE_WRITE_4(frm, v); \
frm += 4; \
@@ -592,12 +545,14 @@ hwmp_add_meshperr(uint8_t *frm, const st
*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_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 += 6;
ADDWORD(frm, perr->perr_dests[i].dest_seq);
+ ADDSHORT(frm, perr->perr_dests[i].dest_rcode);
}
return frm;
}
@@ -1138,12 +1093,15 @@ hwmp_send_prep(struct ieee80211_node *ni
sizeof(struct ieee80211_meshprep_ie));
}
+#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_DRCODE(n) perr.perr_dests[n].dest_rcode
static void
hwmp_peerdown(struct ieee80211_node *ni)
{
struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211_meshperr_ie perr;
struct ieee80211_mesh_route *rt;
struct ieee80211_hwmp_route *hr;
@@ -1154,19 +1112,27 @@ hwmp_peerdown(struct ieee80211_node *ni)
hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"%s", "delete route entry");
- perr.perr_mode = 0;
+ perr.perr_ttl = ms->ms_ttl;
perr.perr_ndests = 1;
+ if (hr->hr_seq == 0)
+ PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN;
+ PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC;
IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest);
PERR_DSEQ(0) = hr->hr_seq;
+ PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH;
/* NB: flush everything passing through peer */
ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr);
hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
}
+#undef PERR_DFLAGS
#undef PERR_DADDR
#undef PERR_DSEQ
+#undef PERR_DRCODE
+#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_DRCODE(n) perr->perr_dests[n].dest_rcode
static void
hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr)
@@ -1192,9 +1158,9 @@ hwmp_recv_perr(struct ieee80211vap *vap,
rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i));
if (rt == NULL)
continue;
- hr = IEEE80211_MESH_ROUTE_PRIV(rt,
- struct ieee80211_hwmp_route);
- if (HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) {
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
+ if (!(PERR_DFLAGS(0) & IEEE80211_MESHPERR_DFLAGS_USN) &&
+ HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) {
ieee80211_mesh_rt_del(vap, rt->rt_dest);
ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest);
rt = NULL;
@@ -1205,10 +1171,11 @@ hwmp_recv_perr(struct ieee80211vap *vap,
* Propagate the PERR if we previously found it on our routing table.
* XXX handle ndest > 1
*/
- if (forward) {
+ if (forward && perr->perr_ttl > 1) {
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"propagate PERR from %s", ether_sprintf(wh->i_addr2));
memcpy(&pperr, perr, sizeof(*perr));
+ pperr.perr_ttl--;
hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr,
&pperr);
}
Modified: stable/8/sys/net80211/ieee80211_mesh.c
==============================================================================
--- stable/8/sys/net80211/ieee80211_mesh.c Tue Sep 29 10:53:06 2009 (r197613)
+++ stable/8/sys/net80211/ieee80211_mesh.c Tue Sep 29 12:18:23 2009 (r197614)
@@ -87,10 +87,10 @@ static void mesh_peer_timeout_backoff(st
static void mesh_peer_timeout_cb(void *);
static __inline void
mesh_peer_timeout_stop(struct ieee80211_node *);
-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 *);
-static int mesh_verify_meshpeer(struct ieee80211vap *, const uint8_t *);
+static int mesh_verify_meshpeer(struct ieee80211vap *, uint8_t,
+ const uint8_t *);
uint32_t mesh_airtime_calc(struct ieee80211_node *);
/*
@@ -1544,19 +1544,16 @@ static const struct ieee80211_meshpeer_i
mesh_parse_meshpeering_action(struct ieee80211_node *ni,
const struct ieee80211_frame *wh, /* XXX for VERIFY_LENGTH */
const uint8_t *frm, const uint8_t *efrm,
- struct ieee80211_meshpeer_ie *mp)
+ struct ieee80211_meshpeer_ie *mp, uint8_t subtype)
{
struct ieee80211vap *vap = ni->ni_vap;
const struct ieee80211_meshpeer_ie *mpie;
- const uint8_t *meshid, *meshconf, *meshpeerver, *meshpeer;
+ const uint8_t *meshid, *meshconf, *meshpeer;
- meshid = meshconf = meshpeerver = meshpeer = NULL;
+ meshid = meshconf = meshpeer = NULL;
while (efrm - frm > 1) {
IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return NULL);
switch (*frm) {
- case IEEE80211_ELEMID_MESHPEERVER:
- meshpeerver = frm;
- break;
case IEEE80211_ELEMID_MESHID:
meshid = frm;
break;
@@ -1567,12 +1564,10 @@ mesh_parse_meshpeering_action(struct iee
meshpeer = frm;
mpie = (const struct ieee80211_meshpeer_ie *) frm;
memset(mp, 0, sizeof(*mp));
- mp->peer_subtype = mpie->peer_subtype;
mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
/* NB: peer link ID is optional on these frames */
- if (mpie->peer_subtype ==
- IEEE80211_MESH_PEER_LINK_CLOSE &&
- mpie->peer_len == 5) {
+ if (subtype == IEEE80211_MESH_PEER_LINK_CLOSE &&
+ mpie->peer_len == 8) {
mp->peer_linkid = 0;
mp->peer_rcode = LE_READ_2(&mpie->peer_linkid);
} else {
@@ -1589,12 +1584,12 @@ mesh_parse_meshpeering_action(struct iee
* close subtype don't have a Mesh Configuration IE.
* If if fails validation, close the peer link.
*/
- KASSERT(meshpeer != NULL && mp->peer_subtype !=
- IEEE80211_ACTION_MESHPEERING_CLOSE, ("parsing close action"));
+ KASSERT(meshpeer != NULL &&
+ subtype != IEEE80211_ACTION_MESHPEERING_CLOSE,
+ ("parsing close action"));
- if (mesh_verify_meshpeerver(vap, meshpeerver) ||
- mesh_verify_meshid(vap, meshid) ||
- mesh_verify_meshpeer(vap, meshpeer) ||
+ if (mesh_verify_meshid(vap, meshid) ||
+ mesh_verify_meshpeer(vap, subtype, meshpeer) ||
mesh_verify_meshconf(vap, meshconf)) {
uint16_t args[3];
@@ -1638,7 +1633,8 @@ mesh_recv_action_meshpeering_open(struct
uint16_t args[3];
/* +2+2 for action + code + capabilites */
- meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie);
+ meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2, efrm, &ie,
+ IEEE80211_ACTION_MESHPEERING_OPEN);
if (meshpeer == NULL) {
return 0;
}
@@ -1770,7 +1766,8 @@ mesh_recv_action_meshpeering_confirm(str
uint16_t args[3];
/* +2+2+2+2 for action + code + capabilites + status code + AID */
- meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie);
+ meshpeer = mesh_parse_meshpeering_action(ni, wh, frm+2+2+2+2, efrm, &ie,
+ IEEE80211_ACTION_MESHPEERING_CONFIRM);
if (meshpeer == NULL) {
return 0;
}
@@ -1933,7 +1930,6 @@ mesh_send_action_meshpeering_open(struct
ic->ic_headroom + sizeof(struct ieee80211_frame),
sizeof(uint16_t) /* action+category */
+ sizeof(uint16_t) /* capabilites */
- + sizeof(struct ieee80211_meshpeerver_ie)
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ 2 + IEEE80211_MESHID_LEN
@@ -1946,7 +1942,6 @@ mesh_send_action_meshpeering_open(struct
* [1] category
* [1] action
* [2] capabilities
- * [tlv] mesh peer protocol version
* [tlv] rates
* [tlv] xrates
* [tlv] mesh id
@@ -1956,7 +1951,6 @@ mesh_send_action_meshpeering_open(struct
*frm++ = category;
*frm++ = action;
ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
- frm = ieee80211_add_meshpeerver(frm, vap);
rs = ieee80211_get_suprates(ic, ic->ic_curchan);
frm = ieee80211_add_rates(frm, rs);
frm = ieee80211_add_xrates(frm, rs);
@@ -1999,7 +1993,6 @@ mesh_send_action_meshpeering_confirm(str
+ sizeof(uint16_t) /* capabilites */
+ sizeof(uint16_t) /* status code */
+ sizeof(uint16_t) /* AID */
- + sizeof(struct ieee80211_meshpeerver_ie)
+ 2 + IEEE80211_RATE_SIZE
+ 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ 2 + IEEE80211_MESHID_LEN
@@ -2014,7 +2007,6 @@ mesh_send_action_meshpeering_confirm(str
* [2] capabilities
* [2] status code
* [2] association id (peer ID)
- * [tlv] mesh peer protocol version
* [tlv] rates
* [tlv] xrates
* [tlv] mesh id
@@ -2026,7 +2018,6 @@ mesh_send_action_meshpeering_confirm(str
ADDSHORT(frm, ieee80211_getcapinfo(vap, ni->ni_chan));
ADDSHORT(frm, 0); /* status code */
ADDSHORT(frm, args[1]); /* AID */
- frm = ieee80211_add_meshpeerver(frm, vap);
rs = ieee80211_get_suprates(ic, ic->ic_curchan);
frm = ieee80211_add_rates(frm, rs);
frm = ieee80211_add_xrates(frm, rs);
@@ -2067,7 +2058,6 @@ mesh_send_action_meshpeering_close(struc
ic->ic_headroom + sizeof(struct ieee80211_frame),
sizeof(uint16_t) /* action+category */
+ sizeof(uint16_t) /* reason code */
- + sizeof(struct ieee80211_meshpeerver_ie)
+ 2 + IEEE80211_MESHID_LEN
+ sizeof(struct ieee80211_meshpeer_ie)
);
@@ -2077,14 +2067,12 @@ mesh_send_action_meshpeering_close(struc
* [1] category
* [1] action
* [2] reason code
- * [tlv] mesh peer protocol version
* [tlv] mesh id
* [tlv] mesh peer link mgmt
*/
*frm++ = category;
*frm++ = action;
ADDSHORT(frm, args[2]); /* reason code */
- frm = ieee80211_add_meshpeerver(frm, vap);
frm = ieee80211_add_meshid(frm, vap);
frm = ieee80211_add_meshpeer(frm,
IEEE80211_MESH_PEER_LINK_CLOSE,
@@ -2279,19 +2267,6 @@ mesh_peer_timeout_cb(void *arg)
}
static int
-mesh_verify_meshpeerver(struct ieee80211vap *vap, const uint8_t *ie)
-{
- static const uint8_t peer[4] = IEEE80211_MESHPEERVER_PEER;
- const struct ieee80211_meshpeerver_ie *meshpeerver =
- (const struct ieee80211_meshpeerver_ie *) ie;
-
- if (meshpeerver->peerver_len !=
- sizeof(struct ieee80211_meshpeerver_ie) - 2)
- return 1;
- return memcmp(meshpeerver->peerver_proto, peer, 4);
-}
-
-static int
mesh_verify_meshid(struct ieee80211vap *vap, const uint8_t *ie)
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
@@ -2364,26 +2339,28 @@ mesh_verify_meshconf(struct ieee80211vap
}
static int
-mesh_verify_meshpeer(struct ieee80211vap *vap, const uint8_t *ie)
+mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype,
+ const uint8_t *ie)
{
const struct ieee80211_meshpeer_ie *meshpeer =
(const struct ieee80211_meshpeer_ie *) ie;
- if (meshpeer == NULL)
+ if (meshpeer == NULL || meshpeer->peer_len < 6 ||
+ meshpeer->peer_len > 10)
return 1;
- switch (meshpeer->peer_subtype) {
+ switch (subtype) {
case IEEE80211_MESH_PEER_LINK_OPEN:
- if (meshpeer->peer_len != 3)
+ if (meshpeer->peer_len != 6)
return 1;
break;
case IEEE80211_MESH_PEER_LINK_CONFIRM:
- if (meshpeer->peer_len != 5)
+ if (meshpeer->peer_len != 8)
return 1;
break;
case IEEE80211_MESH_PEER_LINK_CLOSE:
- if (meshpeer->peer_len < 5)
+ if (meshpeer->peer_len < 8)
return 1;
- if (meshpeer->peer_len == 5 && meshpeer->peer_linkid != 0)
+ if (meshpeer->peer_len == 8 && meshpeer->peer_linkid != 0)
return 1;
if (meshpeer->peer_rcode == 0)
return 1;
@@ -2449,53 +2426,40 @@ ieee80211_add_meshconf(uint8_t *frm, str
}
/*
- * Add a Mesh Peer Protocol IE to a frame.
- * XXX: needs to grow support for Abbreviated Handshake
- */
-uint8_t *
-ieee80211_add_meshpeerver(uint8_t *frm, struct ieee80211vap *vap)
-{
- static struct ieee80211_meshpeerver_ie ie = {
- .peerver_ie = IEEE80211_ELEMID_MESHPEERVER,
- .peerver_len = 4,
- .peerver_proto = IEEE80211_MESHPEERVER_PEER,
- };
-
- KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
-
- memcpy(frm, &ie, sizeof(ie));
- return frm + sizeof(ie);
-}
-
-/*
* Add a Mesh Peer Management IE to a frame.
*/
uint8_t *
ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid,
uint16_t peerid, uint16_t reason)
{
+ /* XXX change for AH */
+ static const uint8_t meshpeerproto[4] = IEEE80211_MESH_PEER_PROTO;
+
KASSERT(localid != 0, ("localid == 0"));
*frm++ = IEEE80211_ELEMID_MESHPEER;
switch (subtype) {
case IEEE80211_MESH_PEER_LINK_OPEN:
- *frm++ = 3; /* length */
- *frm++ = subtype;
+ *frm++ = 6; /* length */
+ memcpy(frm, meshpeerproto, 4);
+ frm += 4;
ADDSHORT(frm, localid); /* local ID */
break;
case IEEE80211_MESH_PEER_LINK_CONFIRM:
KASSERT(peerid != 0, ("sending peer confirm without peer id"));
- *frm++ = 5; /* length */
- *frm++ = subtype;
+ *frm++ = 8; /* length */
+ memcpy(frm, meshpeerproto, 4);
+ frm += 4;
ADDSHORT(frm, localid); /* local ID */
ADDSHORT(frm, peerid); /* peer ID */
break;
case IEEE80211_MESH_PEER_LINK_CLOSE:
if (peerid)
- *frm++ = 7; /* length */
+ *frm++ = 10; /* length */
else
- *frm++ = 5; /* length */
- *frm++ = subtype;
+ *frm++ = 8; /* length */
+ memcpy(frm, meshpeerproto, 4);
+ frm += 4;
ADDSHORT(frm, localid); /* local ID */
if (peerid)
ADDSHORT(frm, peerid); /* peer ID */
Modified: stable/8/sys/net80211/ieee80211_mesh.h
==============================================================================
--- stable/8/sys/net80211/ieee80211_mesh.h Tue Sep 29 10:53:06 2009 (r197613)
+++ stable/8/sys/net80211/ieee80211_mesh.h Tue Sep 29 12:18:23 2009 (r197614)
@@ -34,7 +34,7 @@
#define IEEE80211_MESH_DEFAULT_TTL 31
/*
- * NB: all structures are__packed so sizeof works on arm, et. al.
+ * NB: all structures are __packed so sizeof works on arm, et. al.
*/
/*
* 802.11s Information Elements.
@@ -116,28 +116,11 @@ struct ieee80211_meshcngst_ie {
AC_BE, AC_VI, AC_VO */
} __packed;
-/* Peer Version */
-struct ieee80211_meshpeerver_ie {
- uint8_t peerver_ie; /* IEEE80211_ELEMID_MESHPEERVER */
- uint8_t peerver_len;
- uint8_t peerver_proto[4];
-} __packed;
-/* Mesh Peering Management Protocol */
-#define IEEE80211_MESHPEERVER_PEER_OUI 0x00, 0x0f, 0xac
-#define IEEE80211_MESHPEERVER_PEER_VALUE 0x2a
-#define IEEE80211_MESHPEERVER_PEER { IEEE80211_MESHPEERVER_PEER_OUI, \
- IEEE80211_MESHPEERVER_PEER_VALUE }
-/* Abbreviated Handshake Protocol */
-#define IEEE80211_MESHPEERVER_AH_OUI 0x00, 0x0f, 0xac
-#define IEEE80211_MESHPEERVER_AH_VALUE 0x2b
-#define IEEE80211_MESHPEERVER_AH { IEEE80211_MESHPEERVER_AH_OUI, \
- IEEE80211_MESHPEERVER_AH_VALUE }
-
/* Peer Link Management */
struct ieee80211_meshpeer_ie {
uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */
uint8_t peer_len;
- uint8_t peer_subtype;
+ uint8_t peer_proto[4]; /* Peer Management Protocol */
uint16_t peer_llinkid; /* Local Link ID */
uint16_t peer_linkid; /* Peer Link ID */
uint16_t peer_rcode;
@@ -150,6 +133,16 @@ enum {
/* values 3-255 are reserved */
};
+/* Mesh Peering Management Protocol */
+#define IEEE80211_MESH_PEER_PROTO_OUI 0x00, 0x0f, 0xac
+#define IEEE80211_MESH_PEER_PROTO_VALUE 0x2a
+#define IEEE80211_MESH_PEER_PROTO { IEEE80211_MESH_PEER_PROTO_OUI, \
+ IEEE80211_MESH_PEER_PROTO_VALUE }
+/* Abbreviated Handshake Protocol */
+#define IEEE80211_MESH_PEER_PROTO_AH_OUI 0x00, 0x0f, 0xac
+#define IEEE80211_MESH_PEER_PROTO_AH_VALUE 0x2b
+#define IEEE80211_MESH_PEER_PROTO_AH { IEEE80211_MESH_PEER_PROTO_AH_OUI, \
+ IEEE80211_MESH_PEER_PROTO_AH_VALUE }
#ifdef notyet
/* Mesh Channel Switch Annoucement */
struct ieee80211_meshcsa_ie {
@@ -256,11 +249,15 @@ struct ieee80211_meshprep_ie {
struct ieee80211_meshperr_ie {
uint8_t perr_ie; /* IEEE80211_ELEMID_MESHPERR */
uint8_t perr_len;
- uint8_t perr_mode; /* NB: reserved */
+ uint8_t perr_ttl;
uint8_t perr_ndests; /* Number of Destinations */
struct {
+ uint8_t dest_flags;
+#define IEEE80211_MESHPERR_DFLAGS_USN 0x01
+#define IEEE80211_MESHPERR_DFLAGS_RC 0x02
uint8_t dest_addr[IEEE80211_ADDR_LEN];
uint32_t dest_seq; /* HWMP Sequence Number */
+ uint16_t dest_rcode;
} __packed perr_dests[1]; /* NB: variable size */
} __packed;
@@ -310,14 +307,11 @@ enum {
};
/*
- * Mesh Path Selection Action codes.
+ * Mesh Path Selection Action code.
*/
enum {
- IEEE80211_ACTION_MESHPATH_REQ = 0,
- IEEE80211_ACTION_MESHPATH_REP = 1,
- IEEE80211_ACTION_MESHPATH_ERR = 2,
- IEEE80211_ACTION_MESHPATH_RANN = 3,
- /* 4-255 reserved */
+ IEEE80211_ACTION_MESHPATH_SEL = 0,
+ /* 1-255 reserved */
};
/*
@@ -479,7 +473,6 @@ int ieee80211_mesh_register_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,
More information about the svn-src-stable-8
mailing list