summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_mesh.c
diff options
context:
space:
mode:
authoradrian <adrian@FreeBSD.org>2012-03-04 05:49:39 +0000
committeradrian <adrian@FreeBSD.org>2012-03-04 05:49:39 +0000
commit8d7335fa92b63c3acd810fb4432ac1d312739f25 (patch)
treea5fc6ce807c0d87dbd87d4f0b33c75c01fdb8b0d /sys/net80211/ieee80211_mesh.c
parent77002eeb6cfd162e6ae4999ec8029a1079f7344f (diff)
downloadFreeBSD-src-8d7335fa92b63c3acd810fb4432ac1d312739f25.zip
FreeBSD-src-8d7335fa92b63c3acd810fb4432ac1d312739f25.tar.gz
* Added IEEE80211_ACTION_CAT_MESH in ieee80211.h as specified amendment spec;
* Moved old categories as specified by D4.0 to be action fields of MESH category as specified in amendment spec; * Modified functions to use MESH category and its action fields: + ieee80211_send_action_register + ieee80211_send_action + ieee80211_recv_action_register +ieee80211_recv_action; * Modified ieee80211_hwmp_init and hwmp_send_action so they uses correct action fields as specified in amendment spec; * Modified ieee80211_parse_action so that it verifies MESH frames. * Change Mesh Link Metric to use one information element as amendment spec. Draft 4.0 defined two different information elements for request and response. Submitted by: monthadar@gmail.com
Diffstat (limited to 'sys/net80211/ieee80211_mesh.c')
-rw-r--r--sys/net80211/ieee80211_mesh.c115
1 files changed, 38 insertions, 77 deletions
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index 1f8518c..b812ca4 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -122,14 +122,12 @@ static const uint8_t broadcastaddr[IEEE80211_ADDR_LEN] =
static ieee80211_recv_action_func mesh_recv_action_meshpeering_open;
static ieee80211_recv_action_func mesh_recv_action_meshpeering_confirm;
static ieee80211_recv_action_func mesh_recv_action_meshpeering_close;
-static ieee80211_recv_action_func mesh_recv_action_meshlmetric_req;
-static ieee80211_recv_action_func mesh_recv_action_meshlmetric_rep;
+static ieee80211_recv_action_func mesh_recv_action_meshlmetric;
static ieee80211_send_action_func mesh_send_action_meshpeering_open;
static ieee80211_send_action_func mesh_send_action_meshpeering_confirm;
static ieee80211_send_action_func mesh_send_action_meshpeering_close;
-static ieee80211_send_action_func mesh_send_action_meshlink_request;
-static ieee80211_send_action_func mesh_send_action_meshlink_reply;
+static ieee80211_send_action_func mesh_send_action_meshlmetric;
static const struct ieee80211_mesh_proto_metric mesh_metric_airtime = {
.mpm_descr = "AIRTIME",
@@ -437,10 +435,8 @@ ieee80211_mesh_init(void)
ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPEERING,
IEEE80211_ACTION_MESHPEERING_CLOSE,
mesh_recv_action_meshpeering_close);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
- IEEE80211_ACTION_MESHLMETRIC_REQ, mesh_recv_action_meshlmetric_req);
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
- IEEE80211_ACTION_MESHLMETRIC_REP, mesh_recv_action_meshlmetric_rep);
+ 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_ACTION_MESHPEERING_OPEN,
@@ -451,12 +447,9 @@ ieee80211_mesh_init(void)
ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHPEERING,
IEEE80211_ACTION_MESHPEERING_CLOSE,
mesh_send_action_meshpeering_close);
- ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
- IEEE80211_ACTION_MESHLMETRIC_REQ,
- mesh_send_action_meshlink_request);
- ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESHLMETRIC,
- IEEE80211_ACTION_MESHLMETRIC_REP,
- mesh_send_action_meshlink_reply);
+ ieee80211_send_action_register(IEEE80211_ACTION_CAT_MESH,
+ IEEE80211_ACTION_MESH_LMETRIC,
+ mesh_send_action_meshlmetric);
/*
* Register Airtime Link Metric.
@@ -1861,25 +1854,24 @@ mesh_recv_action_meshpeering_close(struct ieee80211_node *ni,
* Link Metric handling.
*/
static int
-mesh_recv_action_meshlmetric_req(struct ieee80211_node *ni,
- const struct ieee80211_frame *wh,
- const uint8_t *frm, const uint8_t *efrm)
-{
- uint32_t metric;
-
- metric = mesh_airtime_calc(ni);
- ieee80211_send_action(ni,
- IEEE80211_ACTION_CAT_MESHLMETRIC,
- IEEE80211_ACTION_MESHLMETRIC_REP,
- &metric);
- return 0;
-}
-
-static int
-mesh_recv_action_meshlmetric_rep(struct ieee80211_node *ni,
+mesh_recv_action_meshlmetric(struct ieee80211_node *ni,
const struct ieee80211_frame *wh,
const uint8_t *frm, const uint8_t *efrm)
{
+ const struct ieee80211_meshlmetric_ie *ie =
+ (const struct ieee80211_meshlmetric_ie *)
+ (frm+2); /* action + code */
+ struct ieee80211_meshlmetric_ie lm_rep;
+
+ if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
+ lm_rep.lm_flags = 0;
+ lm_rep.lm_metric = mesh_airtime_calc(ni);
+ ieee80211_send_action(ni,
+ IEEE80211_ACTION_CAT_MESH,
+ IEEE80211_ACTION_MESH_LMETRIC,
+ &lm_rep);
+ }
+ /* XXX: else do nothing for now */
return 0;
}
@@ -2091,56 +2083,23 @@ mesh_send_action_meshpeering_close(struct ieee80211_node *ni,
}
static int
-mesh_send_action_meshlink_request(struct ieee80211_node *ni,
+mesh_send_action_meshlmetric(struct ieee80211_node *ni,
int category, int action, void *arg0)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_meshlmetric_ie *ie = arg0;
struct mbuf *m;
uint8_t *frm;
- IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
- "%s", "send LINK METRIC REQUEST action");
-
- IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
- "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
- ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
- ieee80211_ref_node(ni);
-
- m = ieee80211_getmgtframe(&frm,
- ic->ic_headroom + sizeof(struct ieee80211_frame),
- sizeof(uint16_t) /* action+category */
- );
- if (m != NULL) {
- /*
- * mesh link metric request
- * [1] category
- * [1] action
- */
- *frm++ = category;
- *frm++ = action;
- m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
- return mesh_send_action(ni, m);
+ if (ie->lm_flags & IEEE80211_MESH_LMETRIC_FLAGS_REQ) {
+ IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+ ni, "%s", "send LINK METRIC REQUEST action");
} else {
- vap->iv_stats.is_tx_nobuf++;
- ieee80211_free_node(ni);
- return ENOMEM;
+ IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+ ni, "send LINK METRIC REPLY action: metric 0x%x",
+ ie->lm_metric);
}
-}
-
-static int
-mesh_send_action_meshlink_reply(struct ieee80211_node *ni,
- int category, int action, void *args0)
-{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- uint32_t *metric = args0;
- struct mbuf *m;
- uint8_t *frm;
-
- IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
- "send LINK METRIC REPLY action: metric 0x%x", *metric);
-
IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
"ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", __func__, __LINE__,
ni, ether_sprintf(ni->ni_macaddr), ieee80211_node_refcnt(ni)+1);
@@ -2148,19 +2107,20 @@ mesh_send_action_meshlink_reply(struct ieee80211_node *ni,
m = ieee80211_getmgtframe(&frm,
ic->ic_headroom + sizeof(struct ieee80211_frame),
- sizeof(uint16_t) /* action+category */
- + sizeof(struct ieee80211_meshlmetric_ie)
+ sizeof(uint16_t) + /* action+category */
+ sizeof(struct ieee80211_meshlmetric_ie)
);
if (m != NULL) {
/*
- * mesh link metric reply
+ * mesh link metric
* [1] category
* [1] action
* [tlv] mesh link metric
*/
*frm++ = category;
*frm++ = action;
- frm = ieee80211_add_meshlmetric(frm, *metric);
+ frm = ieee80211_add_meshlmetric(frm,
+ ie->lm_flags, ie->lm_metric);
m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
return mesh_send_action(ni, m);
} else {
@@ -2505,10 +2465,11 @@ mesh_airtime_calc(struct ieee80211_node *ni)
* Add a Mesh Link Metric report IE to a frame.
*/
uint8_t *
-ieee80211_add_meshlmetric(uint8_t *frm, uint32_t metric)
+ieee80211_add_meshlmetric(uint8_t *frm, uint8_t flags, uint32_t metric)
{
*frm++ = IEEE80211_ELEMID_MESHLINK;
- *frm++ = 4;
+ *frm++ = 5;
+ *frm++ = flags;
ADDWORD(frm, metric);
return frm;
}
OpenPOWER on IntegriCloud