Modified structure and code that handles Mesh peering management.

* Old struct ieee80211_meshpeer_ie had wrong peer_proto field size;
 * Added IEEE80211_MPM_* size macros;
 * Created an enum for the Mesh Peering Protocol Identifier field according
 to the standard spec and removed old defines;
 * Abbreviated Handshake Protocol is not used by the standard anymore;
 * Modified mesh_verify_meshpeer to use IEEE80211_MPM_* macros for verification;
 * Modified mesh_parse_meshpeering_action to parse complete frame, also to parse
 it according to the standard spec;
 * Modified ieee80211_add_meshpeer to construct correct MPM frames according to
 the standard spec;

Approved by: adrian
This commit is contained in:
Monthadar Al Jaberi 2012-05-01 15:39:16 +00:00
parent ebeaa1ade5
commit c2042c359f
2 changed files with 56 additions and 42 deletions

View File

@ -1573,8 +1573,7 @@ mesh_recv_ctl(struct ieee80211_node *ni, struct mbuf *m, int subtype)
} }
/* /*
* Parse meshpeering action ie's for open+confirm frames; the * Parse meshpeering action ie's for open+confirm frames
* important bits are returned in the supplied structure.
*/ */
static const struct ieee80211_meshpeer_ie * static const struct ieee80211_meshpeer_ie *
mesh_parse_meshpeering_action(struct ieee80211_node *ni, mesh_parse_meshpeering_action(struct ieee80211_node *ni,
@ -1600,15 +1599,27 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni,
meshpeer = frm; meshpeer = frm;
mpie = (const struct ieee80211_meshpeer_ie *) frm; mpie = (const struct ieee80211_meshpeer_ie *) frm;
memset(mp, 0, sizeof(*mp)); memset(mp, 0, sizeof(*mp));
mp->peer_proto = LE_READ_2(&mpie->peer_proto);
mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid); mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
/* NB: peer link ID is optional on these frames */ switch (subtype) {
if (subtype == IEEE80211_ACTION_MESHPEERING_CLOSE && case IEEE80211_ACTION_MESHPEERING_CONFIRM:
mpie->peer_len == 8) { mp->peer_linkid =
mp->peer_linkid = 0; LE_READ_2(&mpie->peer_linkid);
mp->peer_rcode = LE_READ_2(&mpie->peer_linkid); break;
} else { case IEEE80211_ACTION_MESHPEERING_CLOSE:
mp->peer_linkid = LE_READ_2(&mpie->peer_linkid); /* NB: peer link ID is optional */
mp->peer_rcode = LE_READ_2(&mpie->peer_rcode); if (mpie->peer_len ==
(IEEE80211_MPM_BASE_SZ + 2)) {
mp->peer_linkid = 0;
mp->peer_rcode =
LE_READ_2(&mpie->peer_linkid);
} else {
mp->peer_linkid =
LE_READ_2(&mpie->peer_linkid);
mp->peer_rcode =
LE_READ_2(&mpie->peer_rcode);
}
break;
} }
break; break;
} }
@ -2337,22 +2348,31 @@ mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype,
const struct ieee80211_meshpeer_ie *meshpeer = const struct ieee80211_meshpeer_ie *meshpeer =
(const struct ieee80211_meshpeer_ie *) ie; (const struct ieee80211_meshpeer_ie *) ie;
if (meshpeer == NULL || meshpeer->peer_len < 6 || if (meshpeer == NULL ||
meshpeer->peer_len > 10) meshpeer->peer_len < IEEE80211_MPM_BASE_SZ ||
meshpeer->peer_len > IEEE80211_MPM_MAX_SZ)
return 1; return 1;
if (meshpeer->peer_proto != IEEE80211_MPPID_MPM) {
IEEE80211_DPRINTF(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
"Only MPM protocol is supported (proto: 0x%02X)",
meshpeer->peer_proto);
return 1;
}
switch (subtype) { switch (subtype) {
case IEEE80211_ACTION_MESHPEERING_OPEN: case IEEE80211_ACTION_MESHPEERING_OPEN:
if (meshpeer->peer_len != 6) if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ)
return 1; return 1;
break; break;
case IEEE80211_ACTION_MESHPEERING_CONFIRM: case IEEE80211_ACTION_MESHPEERING_CONFIRM:
if (meshpeer->peer_len != 8) if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ + 2)
return 1; return 1;
break; break;
case IEEE80211_ACTION_MESHPEERING_CLOSE: case IEEE80211_ACTION_MESHPEERING_CLOSE:
if (meshpeer->peer_len < 8) if (meshpeer->peer_len < IEEE80211_MPM_BASE_SZ + 2)
return 1; return 1;
if (meshpeer->peer_len == 8 && meshpeer->peer_linkid != 0) if (meshpeer->peer_len == (IEEE80211_MPM_BASE_SZ + 2) &&
meshpeer->peer_linkid != 0)
return 1; return 1;
if (meshpeer->peer_rcode == 0) if (meshpeer->peer_rcode == 0)
return 1; return 1;
@ -2418,34 +2438,29 @@ uint8_t *
ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid, ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid,
uint16_t peerid, uint16_t reason) 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")); KASSERT(localid != 0, ("localid == 0"));
*frm++ = IEEE80211_ELEMID_MESHPEER; *frm++ = IEEE80211_ELEMID_MESHPEER;
switch (subtype) { switch (subtype) {
case IEEE80211_ACTION_MESHPEERING_OPEN: case IEEE80211_ACTION_MESHPEERING_OPEN:
*frm++ = 6; /* length */ *frm++ = IEEE80211_MPM_BASE_SZ; /* length */
memcpy(frm, meshpeerproto, 4); ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
frm += 4; ADDSHORT(frm, localid); /* local ID */
ADDSHORT(frm, localid); /* local ID */
break; break;
case IEEE80211_ACTION_MESHPEERING_CONFIRM: case IEEE80211_ACTION_MESHPEERING_CONFIRM:
KASSERT(peerid != 0, ("sending peer confirm without peer id")); KASSERT(peerid != 0, ("sending peer confirm without peer id"));
*frm++ = 8; /* length */ *frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
memcpy(frm, meshpeerproto, 4); ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
frm += 4; ADDSHORT(frm, localid); /* local ID */
ADDSHORT(frm, localid); /* local ID */ ADDSHORT(frm, peerid); /* peer ID */
ADDSHORT(frm, peerid); /* peer ID */
break; break;
case IEEE80211_ACTION_MESHPEERING_CLOSE: case IEEE80211_ACTION_MESHPEERING_CLOSE:
if (peerid) if (peerid)
*frm++ = 10; /* length */ *frm++ = IEEE80211_MPM_MAX_SZ; /* length */
else else
*frm++ = 8; /* length */ *frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
memcpy(frm, meshpeerproto, 4); ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
frm += 4;
ADDSHORT(frm, localid); /* local ID */ ADDSHORT(frm, localid); /* local ID */
if (peerid) if (peerid)
ADDSHORT(frm, peerid); /* peer ID */ ADDSHORT(frm, peerid); /* peer ID */

View File

@ -140,25 +140,24 @@ struct ieee80211_meshcngst_ie {
} __packed; } __packed;
/* Peer Link Management */ /* Peer Link Management */
#define IEEE80211_MPM_BASE_SZ (4)
#define IEEE80211_MPM_MAX_SZ (8)
struct ieee80211_meshpeer_ie { struct ieee80211_meshpeer_ie {
uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */ uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */
uint8_t peer_len; uint8_t peer_len;
uint8_t peer_proto[4]; /* Peer Management Protocol */ uint16_t peer_proto; /* Peer Management Protocol */
uint16_t peer_llinkid; /* Local Link ID */ uint16_t peer_llinkid; /* Local Link ID */
uint16_t peer_linkid; /* Peer Link ID */ uint16_t peer_linkid; /* Peer Link ID */
uint16_t peer_rcode; uint16_t peer_rcode;
} __packed; } __packed;
/* Mesh Peering Management Protocol */ /* Mesh Peering Protocol Identifier field value */
#define IEEE80211_MESH_PEER_PROTO_OUI 0x00, 0x0f, 0xac enum {
#define IEEE80211_MESH_PEER_PROTO_VALUE 0x2a IEEE80211_MPPID_MPM = 0, /* Mesh peering management */
#define IEEE80211_MESH_PEER_PROTO { IEEE80211_MESH_PEER_PROTO_OUI, \ IEEE80211_MPPID_AUTH_MPM = 1, /* Auth. mesh peering exchange */
IEEE80211_MESH_PEER_PROTO_VALUE } /* 2-65535 reserved */
/* 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 #ifdef notyet
/* Mesh Channel Switch Annoucement */ /* Mesh Channel Switch Annoucement */
struct ieee80211_meshcsa_ie { struct ieee80211_meshcsa_ie {