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
|
* 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 */
|
||||||
|
@ -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 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user