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:
parent
ebeaa1ade5
commit
c2042c359f
@ -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
|
||||
* important bits are returned in the supplied structure.
|
||||
* Parse meshpeering action ie's for open+confirm frames
|
||||
*/
|
||||
static const struct ieee80211_meshpeer_ie *
|
||||
mesh_parse_meshpeering_action(struct ieee80211_node *ni,
|
||||
@ -1600,15 +1599,27 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni,
|
||||
meshpeer = frm;
|
||||
mpie = (const struct ieee80211_meshpeer_ie *) frm;
|
||||
memset(mp, 0, sizeof(*mp));
|
||||
mp->peer_proto = LE_READ_2(&mpie->peer_proto);
|
||||
mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid);
|
||||
/* NB: peer link ID is optional on these frames */
|
||||
if (subtype == IEEE80211_ACTION_MESHPEERING_CLOSE &&
|
||||
mpie->peer_len == 8) {
|
||||
switch (subtype) {
|
||||
case IEEE80211_ACTION_MESHPEERING_CONFIRM:
|
||||
mp->peer_linkid =
|
||||
LE_READ_2(&mpie->peer_linkid);
|
||||
break;
|
||||
case IEEE80211_ACTION_MESHPEERING_CLOSE:
|
||||
/* NB: peer link ID is optional */
|
||||
if (mpie->peer_len ==
|
||||
(IEEE80211_MPM_BASE_SZ + 2)) {
|
||||
mp->peer_linkid = 0;
|
||||
mp->peer_rcode = LE_READ_2(&mpie->peer_linkid);
|
||||
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);
|
||||
mp->peer_linkid =
|
||||
LE_READ_2(&mpie->peer_linkid);
|
||||
mp->peer_rcode =
|
||||
LE_READ_2(&mpie->peer_rcode);
|
||||
}
|
||||
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 *) ie;
|
||||
|
||||
if (meshpeer == NULL || meshpeer->peer_len < 6 ||
|
||||
meshpeer->peer_len > 10)
|
||||
if (meshpeer == NULL ||
|
||||
meshpeer->peer_len < IEEE80211_MPM_BASE_SZ ||
|
||||
meshpeer->peer_len > IEEE80211_MPM_MAX_SZ)
|
||||
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) {
|
||||
case IEEE80211_ACTION_MESHPEERING_OPEN:
|
||||
if (meshpeer->peer_len != 6)
|
||||
if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ)
|
||||
return 1;
|
||||
break;
|
||||
case IEEE80211_ACTION_MESHPEERING_CONFIRM:
|
||||
if (meshpeer->peer_len != 8)
|
||||
if (meshpeer->peer_len != IEEE80211_MPM_BASE_SZ + 2)
|
||||
return 1;
|
||||
break;
|
||||
case IEEE80211_ACTION_MESHPEERING_CLOSE:
|
||||
if (meshpeer->peer_len < 8)
|
||||
if (meshpeer->peer_len < IEEE80211_MPM_BASE_SZ + 2)
|
||||
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;
|
||||
if (meshpeer->peer_rcode == 0)
|
||||
return 1;
|
||||
@ -2418,34 +2438,29 @@ 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_ACTION_MESHPEERING_OPEN:
|
||||
*frm++ = 6; /* length */
|
||||
memcpy(frm, meshpeerproto, 4);
|
||||
frm += 4;
|
||||
*frm++ = IEEE80211_MPM_BASE_SZ; /* length */
|
||||
ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
|
||||
ADDSHORT(frm, localid); /* local ID */
|
||||
break;
|
||||
case IEEE80211_ACTION_MESHPEERING_CONFIRM:
|
||||
KASSERT(peerid != 0, ("sending peer confirm without peer id"));
|
||||
*frm++ = 8; /* length */
|
||||
memcpy(frm, meshpeerproto, 4);
|
||||
frm += 4;
|
||||
*frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
|
||||
ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
|
||||
ADDSHORT(frm, localid); /* local ID */
|
||||
ADDSHORT(frm, peerid); /* peer ID */
|
||||
break;
|
||||
case IEEE80211_ACTION_MESHPEERING_CLOSE:
|
||||
if (peerid)
|
||||
*frm++ = 10; /* length */
|
||||
*frm++ = IEEE80211_MPM_MAX_SZ; /* length */
|
||||
else
|
||||
*frm++ = 8; /* length */
|
||||
memcpy(frm, meshpeerproto, 4);
|
||||
frm += 4;
|
||||
*frm++ = IEEE80211_MPM_BASE_SZ + 2; /* length */
|
||||
ADDSHORT(frm, IEEE80211_MPPID_MPM); /* proto */
|
||||
ADDSHORT(frm, localid); /* local ID */
|
||||
if (peerid)
|
||||
ADDSHORT(frm, peerid); /* peer ID */
|
||||
|
@ -140,25 +140,24 @@ struct ieee80211_meshcngst_ie {
|
||||
} __packed;
|
||||
|
||||
/* Peer Link Management */
|
||||
#define IEEE80211_MPM_BASE_SZ (4)
|
||||
#define IEEE80211_MPM_MAX_SZ (8)
|
||||
struct ieee80211_meshpeer_ie {
|
||||
uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */
|
||||
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_linkid; /* Peer Link ID */
|
||||
uint16_t peer_rcode;
|
||||
} __packed;
|
||||
|
||||
/* 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 }
|
||||
/* Mesh Peering Protocol Identifier field value */
|
||||
enum {
|
||||
IEEE80211_MPPID_MPM = 0, /* Mesh peering management */
|
||||
IEEE80211_MPPID_AUTH_MPM = 1, /* Auth. mesh peering exchange */
|
||||
/* 2-65535 reserved */
|
||||
};
|
||||
|
||||
#ifdef notyet
|
||||
/* Mesh Channel Switch Annoucement */
|
||||
struct ieee80211_meshcsa_ie {
|
||||
|
Loading…
Reference in New Issue
Block a user