summaryrefslogtreecommitdiffstats
path: root/sys/net80211
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
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')
-rw-r--r--sys/net80211/ieee80211.h1
-rw-r--r--sys/net80211/ieee80211_action.c84
-rw-r--r--sys/net80211/ieee80211_hwmp.c8
-rw-r--r--sys/net80211/ieee80211_input.c31
-rw-r--r--sys/net80211/ieee80211_mesh.c115
-rw-r--r--sys/net80211/ieee80211_mesh.h38
6 files changed, 146 insertions, 131 deletions
diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h
index 39f6d58..d3425b5 100644
--- a/sys/net80211/ieee80211.h
+++ b/sys/net80211/ieee80211.h
@@ -325,6 +325,7 @@ struct ieee80211_action {
#define IEEE80211_ACTION_CAT_DLS 2 /* DLS */
#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_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 8c11471..aa2d9bd 100644
--- a/sys/net80211/ieee80211_action.c
+++ b/sys/net80211/ieee80211_action.c
@@ -99,16 +99,20 @@ ieee80211_send_action_register(int cat, int act, ieee80211_send_action_func *f)
break;
meshpl_send_action[act] = f;
return 0;
- case IEEE80211_ACTION_CAT_MESHLMETRIC:
- if (act >= N(meshlm_send_action))
- break;
- meshlm_send_action[act] = f;
- return 0;
- case IEEE80211_ACTION_CAT_MESHPATH:
- if (act >= N(hwmp_send_action))
- break;
- hwmp_send_action[act] = f;
- return 0;
+ case IEEE80211_ACTION_CAT_MESH:
+ switch (act) {
+ case IEEE80211_ACTION_MESH_LMETRIC:
+ if (act >= N(meshlm_send_action))
+ break;
+ meshlm_send_action[act] = f;
+ return 0;
+ case IEEE80211_ACTION_MESH_HWMP:
+ if (act >= N(hwmp_send_action))
+ break;
+ hwmp_send_action[act] = f;
+ return 0;
+ }
+ break;
case IEEE80211_ACTION_CAT_VENDOR:
if (act >= N(vendor_send_action))
break;
@@ -144,13 +148,17 @@ ieee80211_send_action(struct ieee80211_node *ni, int cat, int act, void *sa)
if (act < N(meshpl_send_action))
f = meshpl_send_action[act];
break;
- case IEEE80211_ACTION_CAT_MESHLMETRIC:
- if (act < N(meshlm_send_action))
- f = meshlm_send_action[act];
- break;
- case IEEE80211_ACTION_CAT_MESHPATH:
- if (act < N(hwmp_send_action))
- f = hwmp_send_action[act];
+ case IEEE80211_ACTION_CAT_MESH:
+ switch (act) {
+ case IEEE80211_ACTION_MESH_LMETRIC:
+ if (act < N(meshlm_send_action))
+ f = meshlm_send_action[act];
+ break;
+ case IEEE80211_ACTION_MESH_HWMP:
+ if (act < N(hwmp_send_action))
+ f = hwmp_send_action[act];
+ break;
+ }
break;
case IEEE80211_ACTION_CAT_VENDOR:
if (act < N(vendor_send_action))
@@ -212,16 +220,20 @@ ieee80211_recv_action_register(int cat, int act, ieee80211_recv_action_func *f)
break;
meshpl_recv_action[act] = f;
return 0;
- case IEEE80211_ACTION_CAT_MESHLMETRIC:
- if (act >= N(meshlm_recv_action))
- break;
- meshlm_recv_action[act] = f;
- return 0;
- case IEEE80211_ACTION_CAT_MESHPATH:
- if (act >= N(hwmp_recv_action))
- break;
- hwmp_recv_action[act] = f;
- return 0;
+ case IEEE80211_ACTION_CAT_MESH:
+ switch (act) {
+ case IEEE80211_ACTION_MESH_LMETRIC:
+ if (act >= N(meshlm_recv_action))
+ break;
+ meshlm_recv_action[act] = f;
+ return 0;
+ case IEEE80211_ACTION_MESH_HWMP:
+ if (act >= N(hwmp_recv_action))
+ break;
+ hwmp_recv_action[act] = f;
+ return 0;
+ }
+ break;
case IEEE80211_ACTION_CAT_VENDOR:
if (act >= N(vendor_recv_action))
break;
@@ -261,13 +273,17 @@ ieee80211_recv_action(struct ieee80211_node *ni,
if (ia->ia_action < N(meshpl_recv_action))
f = meshpl_recv_action[ia->ia_action];
break;
- case IEEE80211_ACTION_CAT_MESHLMETRIC:
- if (ia->ia_action < N(meshlm_recv_action))
- f = meshlm_recv_action[ia->ia_action];
- break;
- case IEEE80211_ACTION_CAT_MESHPATH:
- if (ia->ia_action < N(hwmp_recv_action))
- f = hwmp_recv_action[ia->ia_action];
+ case IEEE80211_ACTION_CAT_MESH:
+ switch (ia->ia_action) {
+ case IEEE80211_ACTION_MESH_LMETRIC:
+ if (ia->ia_action < N(meshlm_recv_action))
+ f = meshlm_recv_action[ia->ia_action];
+ break;
+ case IEEE80211_ACTION_MESH_HWMP:
+ if (ia->ia_action < N(hwmp_recv_action))
+ f = hwmp_recv_action[ia->ia_action];
+ break;
+ }
break;
case IEEE80211_ACTION_CAT_VENDOR:
if (ia->ia_action < N(vendor_recv_action))
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 319c862..d084c5f 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -220,8 +220,8 @@ ieee80211_hwmp_init(void)
/*
* Register action frame handler.
*/
- ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_SEL, hwmp_recv_action_meshpath);
+ ieee80211_recv_action_register(IEEE80211_ACTION_CAT_MESH,
+ IEEE80211_ACTION_MESH_HWMP, hwmp_recv_action_meshpath);
/* NB: default is 5 secs per spec */
mesh_proto_hwmp.mpp_inact = msecs_to_ticks(5*1000);
@@ -434,8 +434,8 @@ hwmp_send_action(struct ieee80211_node *ni,
vap->iv_stats.is_tx_nobuf++;
return ENOMEM;
}
- *frm++ = IEEE80211_ACTION_CAT_MESHPATH;
- *frm++ = IEEE80211_ACTION_MESHPATH_SEL;
+ *frm++ = IEEE80211_ACTION_CAT_MESH;
+ *frm++ = IEEE80211_ACTION_MESH_HWMP;
switch (*ie) {
case IEEE80211_ELEMID_MESHPREQ:
frm = hwmp_add_meshpreq(frm,
diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c
index d54051e..e40a713 100644
--- a/sys/net80211/ieee80211_input.c
+++ b/sys/net80211/ieee80211_input.c
@@ -760,6 +760,37 @@ ieee80211_parse_action(struct ieee80211_node *ni, struct mbuf *m)
break;
}
break;
+ case IEEE80211_ACTION_CAT_MESH:
+ switch (ia->ia_action) {
+ case IEEE80211_ACTION_MESH_LMETRIC:
+ /*
+ * XXX: verification is true only if we are using
+ * Airtime link metric (default)
+ */
+ IEEE80211_VERIFY_LENGTH(efrm - frm,
+ sizeof(struct ieee80211_meshlmetric_ie),
+ return EINVAL);
+ break;
+ case IEEE80211_ACTION_MESH_HWMP:
+ /* verify something */
+ break;
+ case IEEE80211_ACTION_MESH_GANN:
+ case IEEE80211_ACTION_MESH_CC:
+ case IEEE80211_ACTION_MESH_MCCA_SREQ:
+ case IEEE80211_ACTION_MESH_MCCA_SREP:
+ case IEEE80211_ACTION_MESH_MCCA_AREQ:
+ case IEEE80211_ACTION_MESH_MCCA_ADVER:
+ case IEEE80211_ACTION_MESH_MCCA_TRDOWN:
+ case IEEE80211_ACTION_MESH_TBTT_REQ:
+ case IEEE80211_ACTION_MESH_TBTT_RES:
+ /* reject these early on, not implemented */
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ELEMID | IEEE80211_MSG_INPUT,
+ wh, NULL, "not implemented yet, act=0x%02X",
+ ia->ia_action);
+ return EINVAL;
+ }
+ break;
}
return 0;
}
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;
}
diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h
index 85ee6a7..fde8859 100644
--- a/sys/net80211/ieee80211_mesh.h
+++ b/sys/net80211/ieee80211_mesh.h
@@ -119,8 +119,14 @@ struct ieee80211_meshid_ie {
/* Link Metric Report */
struct ieee80211_meshlmetric_ie {
- uint8_t lm_ie; /* IEEE80211_ELEMID_MESHLINK */
+ uint8_t lm_ie; /* IEEE80211_ACTION_MESH_LMETRIC */
uint8_t lm_len;
+ uint8_t lm_flags;
+#define IEEE80211_MESH_LMETRIC_FLAGS_REQ 0x01 /* Request */
+ /*
+ * XXX: this field should be variable in size and depend on
+ * the active active path selection metric identifier
+ */
uint32_t lm_metric;
#define IEEE80211_MESHLMETRIC_INITIALVAL 0
} __packed;
@@ -307,8 +313,7 @@ struct ieee80211_meshpuc_ie {
* 802.11s Action Frames
*/
#define IEEE80211_ACTION_CAT_MESHPEERING 30 /* XXX Linux */
-#define IEEE80211_ACTION_CAT_MESHLMETRIC 13
-#define IEEE80211_ACTION_CAT_MESHPATH 32 /* 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
@@ -324,20 +329,21 @@ enum {
};
/*
- * Mesh Path Selection Action code.
+ * Mesh Action code.
*/
enum {
- IEEE80211_ACTION_MESHPATH_SEL = 0,
- /* 1-255 reserved */
-};
-
-/*
- * Mesh Link Metric Action codes.
- */
-enum {
- IEEE80211_ACTION_MESHLMETRIC_REQ = 0, /* Link Metric Request */
- IEEE80211_ACTION_MESHLMETRIC_REP = 1, /* Link Metric Report */
- /* 2-255 reserved */
+ IEEE80211_ACTION_MESH_LMETRIC = 0, /* Mesh Link Metric Report */
+ IEEE80211_ACTION_MESH_HWMP = 1, /* HWMP Mesh Path Selection */
+ IEEE80211_ACTION_MESH_GANN = 2, /* Gate Announcement */
+ IEEE80211_ACTION_MESH_CC = 3, /* Congestion Control */
+ IEEE80211_ACTION_MESH_MCCA_SREQ = 4, /* MCCA Setup Request */
+ IEEE80211_ACTION_MESH_MCCA_SREP = 5, /* MCCA Setup Reply */
+ IEEE80211_ACTION_MESH_MCCA_AREQ = 6, /* MCCA Advertisement Req. */
+ IEEE80211_ACTION_MESH_MCCA_ADVER =7, /* MCCA Advertisement */
+ IEEE80211_ACTION_MESH_MCCA_TRDOWN = 8, /* MCCA Teardown */
+ IEEE80211_ACTION_MESH_TBTT_REQ = 9, /* TBTT Adjustment Request */
+ IEEE80211_ACTION_MESH_TBTT_RES = 10, /* TBTT Adjustment Response */
+ /* 11-255 reserved */
};
/*
@@ -496,7 +502,7 @@ uint8_t * ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
uint8_t * ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
uint8_t * ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
uint16_t);
-uint8_t * ieee80211_add_meshlmetric(uint8_t *, uint32_t);
+uint8_t * ieee80211_add_meshlmetric(uint8_t *, uint8_t, uint32_t);
void ieee80211_mesh_node_init(struct ieee80211vap *,
struct ieee80211_node *);
OpenPOWER on IntegriCloud