From 3b1abc639022bf902ec77bd4657fd906ef5264c0 Mon Sep 17 00:00:00 2001 From: monthadar Date: Tue, 1 May 2012 15:35:10 +0000 Subject: [PATCH] Added Self-protected action category (including MPM). * Added new action category IEEE80211_ACTION_CAT_SELF_PROT which is used by 11s for Mesh Peering Management; * Updated Self protected enum Action codes to start from 1 instead of 0 according to the standard spec; * Removed old and wrong action categories IEEE80211_ACTION_CAT_MESHPEERING; * Modified ieee80211_mesh.c and ieee80211_action.c to use the new action category code; * Added earlier verification code in ieee80211_input; Approved by: adrian --- sys/net80211/ieee80211.h | 2 + sys/net80211/ieee80211_action.c | 8 ++-- sys/net80211/ieee80211_input.c | 18 +++++++++ sys/net80211/ieee80211_mesh.c | 70 ++++++++++++++++----------------- sys/net80211/ieee80211_mesh.h | 20 ++++------ 5 files changed, 66 insertions(+), 52 deletions(-) diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index c43c71b35738..72b1312cda59 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -333,6 +333,8 @@ struct ieee80211_action { #define IEEE80211_ACTION_CAT_BA 3 /* BA */ #define IEEE80211_ACTION_CAT_HT 7 /* HT */ #define IEEE80211_ACTION_CAT_MESH 13 /* Mesh */ +#define IEEE80211_ACTION_CAT_SELF_PROT 15 /* Self-protected */ +/* 16 - 125 reserved */ #define IEEE80211_ACTION_CAT_VENDOR 127 /* Vendor Specific */ #define IEEE80211_ACTION_HT_TXCHWIDTH 0 /* recommended xmit chan width*/ diff --git a/sys/net80211/ieee80211_action.c b/sys/net80211/ieee80211_action.c index aa2d9bd96cf7..44543b69b6a1 100644 --- a/sys/net80211/ieee80211_action.c +++ b/sys/net80211/ieee80211_action.c @@ -94,7 +94,7 @@ ieee80211_send_action_register(int cat, int act, ieee80211_send_action_func *f) break; ht_send_action[act] = f; return 0; - case IEEE80211_ACTION_CAT_MESHPEERING: + case IEEE80211_ACTION_CAT_SELF_PROT: if (act >= N(meshpl_send_action)) break; meshpl_send_action[act] = f; @@ -144,7 +144,7 @@ ieee80211_send_action(struct ieee80211_node *ni, int cat, int act, void *sa) if (act < N(ht_send_action)) f = ht_send_action[act]; break; - case IEEE80211_ACTION_CAT_MESHPEERING: + case IEEE80211_ACTION_CAT_SELF_PROT: if (act < N(meshpl_send_action)) f = meshpl_send_action[act]; break; @@ -215,7 +215,7 @@ ieee80211_recv_action_register(int cat, int act, ieee80211_recv_action_func *f) break; ht_recv_action[act] = f; return 0; - case IEEE80211_ACTION_CAT_MESHPEERING: + case IEEE80211_ACTION_CAT_SELF_PROT: if (act >= N(meshpl_recv_action)) break; meshpl_recv_action[act] = f; @@ -269,7 +269,7 @@ ieee80211_recv_action(struct ieee80211_node *ni, if (ia->ia_action < N(ht_recv_action)) f = ht_recv_action[ia->ia_action]; break; - case IEEE80211_ACTION_CAT_MESHPEERING: + case IEEE80211_ACTION_CAT_SELF_PROT: if (ia->ia_action < N(meshpl_recv_action)) f = meshpl_recv_action[ia->ia_action]; break; diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index b4c4e75a0fad..76b3bedf12b1 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -792,6 +792,24 @@ ieee80211_parse_action(struct ieee80211_node *ni, struct mbuf *m) return EINVAL; } break; + case IEEE80211_ACTION_CAT_SELF_PROT: + /* If TA or RA group address discard silently */ + if (IEEE80211_IS_MULTICAST(wh->i_addr1) || + IEEE80211_IS_MULTICAST(wh->i_addr2)) + return EINVAL; + /* + * XXX: Should we verify complete length now or it is + * to varying in sizes? + */ + switch (ia->ia_action) { + case IEEE80211_ACTION_MESHPEERING_CONFIRM: + case IEEE80211_ACTION_MESHPEERING_CLOSE: + /* is not a peering candidate (yet) */ + if (ni == vap->iv_bss) + return EINVAL; + break; + } + break; #endif } return 0; diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c index 53addfbd74c2..0a664916fa1a 100644 --- a/sys/net80211/ieee80211_mesh.c +++ b/sys/net80211/ieee80211_mesh.c @@ -430,25 +430,25 @@ ieee80211_mesh_init(void) /* * Register action frame handlers. */ - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING, + ieee80211_recv_action_register(IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_OPEN, mesh_recv_action_meshpeering_open); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING, + ieee80211_recv_action_register(IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CONFIRM, mesh_recv_action_meshpeering_confirm); - ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING, + ieee80211_recv_action_register(IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, mesh_recv_action_meshpeering_close); ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESH, IEEE80211_ACTION_MESH_LMETRIC, mesh_recv_action_meshlmetric); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING, + ieee80211_send_action_register(IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_OPEN, mesh_send_action_meshpeering_open); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING, + ieee80211_send_action_register(IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CONFIRM, mesh_send_action_meshpeering_confirm); - ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING, + ieee80211_send_action_register(IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, mesh_send_action_meshpeering_close); ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESH, @@ -485,7 +485,7 @@ mesh_vdetach_peers(void *arg, struct ieee80211_node *ni) args[1] = ni->ni_mllid; args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); } @@ -1440,7 +1440,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype, mesh_linkchange(ni, IEEE80211_NODE_MESH_OPENSNT); args[0] = ni->ni_mlpid; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_OPEN, args); ni->ni_mlrcnt = 0; mesh_peer_timeout_setup(ni); @@ -1602,7 +1602,7 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni, memset(mp, 0, sizeof(*mp)); mp->peer_llinkid = LE_READ_2(&mpie->peer_llinkid); /* NB: peer link ID is optional on these frames */ - if (subtype == IEEE80211_MESH_PEER_LINK_CLOSE && + if (subtype == IEEE80211_ACTION_MESHPEERING_CLOSE && mpie->peer_len == 8) { mp->peer_linkid = 0; mp->peer_rcode = LE_READ_2(&mpie->peer_linkid); @@ -1646,7 +1646,7 @@ mesh_parse_meshpeering_action(struct ieee80211_node *ni, args[1] = ni->ni_mllid; args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); @@ -1689,13 +1689,13 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[0] = ni->ni_mlpid; /* Announce we're open too... */ ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_OPEN, args); /* ...and confirm the link. */ args[0] = ni->ni_mlpid; args[1] = ni->ni_mllid; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CONFIRM, args); mesh_peer_timeout_setup(ni); @@ -1707,7 +1707,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[1] = ni->ni_mlpid; args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); @@ -1718,7 +1718,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[0] = ni->ni_mlpid; args[1] = ni->ni_mllid; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CONFIRM, args); break; @@ -1728,7 +1728,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[0] = ni->ni_mlpid; args[1] = ni->ni_mllid; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CONFIRM, args); /* NB: don't setup/clear any timeout */ @@ -1740,7 +1740,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[1] = ni->ni_mllid; args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); mesh_linkchange(ni, @@ -1753,7 +1753,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[0] = ni->ni_mlpid; args[1] = ni->ni_mllid; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CONFIRM, args); mesh_peer_timeout_stop(ni); @@ -1764,7 +1764,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[1] = ni->ni_mlpid; args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); @@ -1774,7 +1774,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[0] = ni->ni_mlpid; args[1] = ni->ni_mllid; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CONFIRM, args); break; @@ -1783,7 +1783,7 @@ mesh_recv_action_meshpeering_open(struct ieee80211_node *ni, args[1] = meshpeer->peer_llinkid; args[2] = IEEE80211_REASON_MESH_MAX_RETRIES; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); break; @@ -1825,7 +1825,7 @@ mesh_recv_action_meshpeering_confirm(struct ieee80211_node *ni, args[1] = meshpeer->peer_llinkid; args[2] = IEEE80211_REASON_MESH_MAX_RETRIES; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); break; @@ -1835,7 +1835,7 @@ mesh_recv_action_meshpeering_confirm(struct ieee80211_node *ni, args[1] = ni->ni_mllid; args[2] = IEEE80211_REASON_PEER_LINK_CANCELED; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); @@ -1875,7 +1875,7 @@ mesh_recv_action_meshpeering_close(struct ieee80211_node *ni, args[1] = ni->ni_mllid; args[2] = IEEE80211_REASON_MESH_CLOSE_RCVD; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); @@ -1991,7 +1991,7 @@ mesh_send_action_meshpeering_open(struct ieee80211_node *ni, frm = ieee80211_add_xrates(frm, rs); frm = ieee80211_add_meshid(frm, vap); frm = ieee80211_add_meshconf(frm, vap); - frm = ieee80211_add_meshpeer(frm, IEEE80211_MESH_PEER_LINK_OPEN, + frm = ieee80211_add_meshpeer(frm, IEEE80211_ACTION_MESHPEERING_OPEN, args[0], 0, 0); m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); return mesh_send_action(ni, m); @@ -2059,7 +2059,7 @@ mesh_send_action_meshpeering_confirm(struct ieee80211_node *ni, frm = ieee80211_add_meshid(frm, vap); frm = ieee80211_add_meshconf(frm, vap); frm = ieee80211_add_meshpeer(frm, - IEEE80211_MESH_PEER_LINK_CONFIRM, + IEEE80211_ACTION_MESHPEERING_CONFIRM, args[0], args[1], 0); m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); return mesh_send_action(ni, m); @@ -2110,7 +2110,7 @@ mesh_send_action_meshpeering_close(struct ieee80211_node *ni, ADDSHORT(frm, args[2]); /* reason code */ frm = ieee80211_add_meshid(frm, vap); frm = ieee80211_add_meshpeer(frm, - IEEE80211_MESH_PEER_LINK_CLOSE, + IEEE80211_ACTION_MESHPEERING_CLOSE, args[0], args[1], args[2]); m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *); return mesh_send_action(ni, m); @@ -2234,7 +2234,7 @@ mesh_peer_timeout_cb(void *arg) args[0] = ni->ni_mlpid; args[2] = IEEE80211_REASON_MESH_MAX_RETRIES; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); ni->ni_mlrcnt = 0; mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); @@ -2242,7 +2242,7 @@ mesh_peer_timeout_cb(void *arg) } else { args[0] = ni->ni_mlpid; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_OPEN, args); ni->ni_mlrcnt++; mesh_peer_timeout_backoff(ni); @@ -2253,7 +2253,7 @@ mesh_peer_timeout_cb(void *arg) args[0] = ni->ni_mlpid; args[2] = IEEE80211_REASON_MESH_CONFIRM_TIMEOUT; ieee80211_send_action(ni, - IEEE80211_ACTION_CAT_MESHPEERING, + IEEE80211_ACTION_CAT_SELF_PROT, IEEE80211_ACTION_MESHPEERING_CLOSE, args); ni->ni_mlrcnt = 0; mesh_linkchange(ni, IEEE80211_NODE_MESH_HOLDING); @@ -2341,15 +2341,15 @@ mesh_verify_meshpeer(struct ieee80211vap *vap, uint8_t subtype, meshpeer->peer_len > 10) return 1; switch (subtype) { - case IEEE80211_MESH_PEER_LINK_OPEN: + case IEEE80211_ACTION_MESHPEERING_OPEN: if (meshpeer->peer_len != 6) return 1; break; - case IEEE80211_MESH_PEER_LINK_CONFIRM: + case IEEE80211_ACTION_MESHPEERING_CONFIRM: if (meshpeer->peer_len != 8) return 1; break; - case IEEE80211_MESH_PEER_LINK_CLOSE: + case IEEE80211_ACTION_MESHPEERING_CLOSE: if (meshpeer->peer_len < 8) return 1; if (meshpeer->peer_len == 8 && meshpeer->peer_linkid != 0) @@ -2425,13 +2425,13 @@ ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid, *frm++ = IEEE80211_ELEMID_MESHPEER; switch (subtype) { - case IEEE80211_MESH_PEER_LINK_OPEN: + case IEEE80211_ACTION_MESHPEERING_OPEN: *frm++ = 6; /* length */ memcpy(frm, meshpeerproto, 4); frm += 4; ADDSHORT(frm, localid); /* local ID */ break; - case IEEE80211_MESH_PEER_LINK_CONFIRM: + case IEEE80211_ACTION_MESHPEERING_CONFIRM: KASSERT(peerid != 0, ("sending peer confirm without peer id")); *frm++ = 8; /* length */ memcpy(frm, meshpeerproto, 4); @@ -2439,7 +2439,7 @@ ieee80211_add_meshpeer(uint8_t *frm, uint8_t subtype, uint16_t localid, ADDSHORT(frm, localid); /* local ID */ ADDSHORT(frm, peerid); /* peer ID */ break; - case IEEE80211_MESH_PEER_LINK_CLOSE: + case IEEE80211_ACTION_MESHPEERING_CLOSE: if (peerid) *frm++ = 10; /* length */ else diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h index 58d7608e8684..56120dfa0bda 100644 --- a/sys/net80211/ieee80211_mesh.h +++ b/sys/net80211/ieee80211_mesh.h @@ -149,13 +149,6 @@ struct ieee80211_meshpeer_ie { uint16_t peer_rcode; } __packed; -enum { - IEEE80211_MESH_PEER_LINK_OPEN = 0, - IEEE80211_MESH_PEER_LINK_CONFIRM = 1, - IEEE80211_MESH_PEER_LINK_CLOSE = 2, - /* 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 @@ -331,9 +324,9 @@ struct ieee80211_meshpuc_ie { /* * 802.11s Action Frames + * XXX: these are wrong, and some of them should be + * under MESH category while PROXY is under MULTIHOP category. */ -#define IEEE80211_ACTION_CAT_MESHPEERING 30 /* XXX Linux */ -/* XXX: these need to be looked into */ #define IEEE80211_ACTION_CAT_INTERWORK 15 #define IEEE80211_ACTION_CAT_RESOURCE 16 #define IEEE80211_ACTION_CAT_PROXY 17 @@ -342,10 +335,11 @@ struct ieee80211_meshpuc_ie { * Mesh Peering Action codes. */ enum { - IEEE80211_ACTION_MESHPEERING_OPEN = 0, - IEEE80211_ACTION_MESHPEERING_CONFIRM = 1, - IEEE80211_ACTION_MESHPEERING_CLOSE = 2, - /* 3-255 reserved */ + /* 0 reserved */ + IEEE80211_ACTION_MESHPEERING_OPEN = 1, + IEEE80211_ACTION_MESHPEERING_CONFIRM = 2, + IEEE80211_ACTION_MESHPEERING_CLOSE = 3, + /* 4-255 reserved */ }; /*