svn commit: r192111 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Thu May 14 17:04:01 UTC 2009
Author: rpaulo
Date: Thu May 14 17:04:00 2009
New Revision: 192111
URL: http://svn.freebsd.org/changeset/base/192111
Log:
* Change the send action API while keeping ABI to support passing a fixed
list of arguments or a pointer.
* Ignore action frames for peers without an established link
* s/ieee80211_meshcontrol/ieee80211_meshcntl/
* Parse mesh path request frames and send a path reply if it's destined
to us.
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_ht.c
projects/mesh11s/sys/net80211/ieee80211_mesh.c
projects/mesh11s/sys/net80211/ieee80211_mesh.h
projects/mesh11s/sys/net80211/ieee80211_output.c
projects/mesh11s/sys/net80211/ieee80211_proto.h
projects/mesh11s/sys/net80211/ieee80211_var.h
Modified: projects/mesh11s/sys/net80211/ieee80211_ht.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ht.c Thu May 14 16:56:56 2009 (r192110)
+++ projects/mesh11s/sys/net80211/ieee80211_ht.c Thu May 14 17:04:00 2009 (r192111)
@@ -1577,7 +1577,7 @@ ieee80211_aggr_recv_action(struct ieee80
struct ieee80211_tx_ampdu *tap;
uint8_t dialogtoken, policy;
uint16_t baparamset, batimeout, baseqctl, code;
- uint16_t args[4];
+ union ieee80211_send_action_args vargs;
int tid, ac, bufsiz;
ia = (const struct ieee80211_action *) frm;
@@ -1606,7 +1606,7 @@ ieee80211_aggr_recv_action(struct ieee80
rap = &ni->ni_rx_ampdu[tid];
/* Send ADDBA response */
- args[0] = dialogtoken;
+ vargs.fixedarg[0] = dialogtoken;
/*
* NB: We ack only if the sta associated with HT and
* the ap is configured to do AMPDU rx (the latter
@@ -1618,7 +1618,7 @@ ieee80211_aggr_recv_action(struct ieee80
ic->ic_ampdu_rx_start(ni, rap,
baparamset, batimeout, baseqctl);
- args[1] = IEEE80211_STATUS_SUCCESS;
+ vargs.fixedarg[1] = IEEE80211_STATUS_SUCCESS;
} else {
IEEE80211_NOTE(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
@@ -1627,16 +1627,18 @@ ieee80211_aggr_recv_action(struct ieee80
"administratively disabled" :
"not negotiated for station");
vap->iv_stats.is_addba_reject++;
- args[1] = IEEE80211_STATUS_UNSPECIFIED;
+ vargs.fixedarg[1] =
+ IEEE80211_STATUS_UNSPECIFIED;
}
/* XXX honor rap flags? */
- args[2] = IEEE80211_BAPS_POLICY_IMMEDIATE
+ vargs.fixedarg[2] =
+ IEEE80211_BAPS_POLICY_IMMEDIATE
| SM(tid, IEEE80211_BAPS_TID)
| SM(rap->rxa_wnd, IEEE80211_BAPS_BUFSIZ)
;
- args[3] = 0;
+ vargs.fixedarg[3] = 0;
ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
- IEEE80211_ACTION_BA_ADDBA_RESPONSE, args);
+ IEEE80211_ACTION_BA_ADDBA_RESPONSE, vargs);
return;
case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
@@ -1777,9 +1779,9 @@ ieee80211_ampdu_request(struct ieee80211
struct ieee80211_tx_ampdu *tap)
{
struct ieee80211com *ic = ni->ni_ic;
- uint16_t args[4];
int tid, dialogtoken;
static int tokens = 0; /* XXX */
+ union ieee80211_send_action_args vargs;
/* XXX locking */
if ((tap->txa_flags & IEEE80211_AGGR_SETUP) == 0) {
@@ -1793,14 +1795,15 @@ ieee80211_ampdu_request(struct ieee80211
tid = WME_AC_TO_TID(tap->txa_ac);
tap->txa_start = ni->ni_txseqs[tid];
- args[0] = dialogtoken;
- args[1] = IEEE80211_BAPS_POLICY_IMMEDIATE
+ vargs.fixedarg[0] = dialogtoken;
+ vargs.fixedarg[1] = IEEE80211_BAPS_POLICY_IMMEDIATE
| SM(tid, IEEE80211_BAPS_TID)
| SM(IEEE80211_AGGR_BAWMAX, IEEE80211_BAPS_BUFSIZ)
;
- args[2] = 0; /* batimeout */
+ vargs.fixedarg[2] = 0; /* batimeout */
/* NB: do first so there's no race against reply */
- if (!ic->ic_addba_request(ni, tap, dialogtoken, args[1], args[2])) {
+ if (!ic->ic_addba_request(ni, tap, dialogtoken, vargs.fixedarg[1],
+ vargs.fixedarg[2])) {
/* unable to setup state, don't make request */
IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_11N,
ni, "%s: could not setup BA stream for AC %d",
@@ -1814,11 +1817,11 @@ ieee80211_ampdu_request(struct ieee80211
}
tokens = dialogtoken; /* allocate token */
/* NB: after calling ic_addba_request so driver can set txa_start */
- args[3] = SM(tap->txa_start, IEEE80211_BASEQ_START)
+ vargs.fixedarg[3] = SM(tap->txa_start, IEEE80211_BASEQ_START)
| SM(0, IEEE80211_BASEQ_FRAG)
;
return ic->ic_send_action(ni, IEEE80211_ACTION_CAT_BA,
- IEEE80211_ACTION_BA_ADDBA_REQUEST, args);
+ IEEE80211_ACTION_BA_ADDBA_REQUEST, vargs);
}
/*
@@ -1831,7 +1834,7 @@ ieee80211_ampdu_stop(struct ieee80211_no
{
struct ieee80211com *ic = ni->ni_ic;
struct ieee80211vap *vap = ni->ni_vap;
- uint16_t args[4];
+ union ieee80211_send_action_args vargs;
/* XXX locking */
tap->txa_flags &= ~IEEE80211_AGGR_BARPEND;
@@ -1842,11 +1845,11 @@ ieee80211_ampdu_stop(struct ieee80211_no
vap->iv_stats.is_ampdu_stop++;
ic->ic_addba_stop(ni, tap);
- args[0] = WME_AC_TO_TID(tap->txa_ac);
- args[1] = IEEE80211_DELBAPS_INIT;
- args[2] = reason; /* XXX reason code */
+ vargs.fixedarg[0] = WME_AC_TO_TID(tap->txa_ac);
+ vargs.fixedarg[1] = IEEE80211_DELBAPS_INIT;
+ vargs.fixedarg[2] = reason; /* XXX reason code */
ieee80211_send_action(ni, IEEE80211_ACTION_CAT_BA,
- IEEE80211_ACTION_BA_DELBA, args);
+ IEEE80211_ACTION_BA_DELBA, vargs);
} else {
IEEE80211_NOTE(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_11N,
ni, "%s: BA stream for AC %d not running (reason %d)",
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c Thu May 14 16:56:56 2009 (r192110)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c Thu May 14 17:04:00 2009 (r192111)
@@ -89,13 +89,6 @@ static const int ieee80211_mesh_maxretri
/* non static for sysctl hookup */
int ieee80211_mesh_ttl = 31;
-/* unalligned little endian access */
-#define LE_READ_2(p) \
- ((uint16_t) \
- ((((const uint8_t *)(p))[0] ) | \
- (((const uint8_t *)(p))[1] << 8)))
-
-
static const char *nodemeshstates[] = {
"IDLE",
"OPEN SENT",
@@ -273,9 +266,14 @@ mesh_input(struct ieee80211_node *ni, st
case IEEE80211_FC0_TYPE_DATA:
IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, ni,
"%s", "received data frame");
- /* XXX: make sure we already peered with this node */
+ if (ni->ni_peerstate != IEEE80211_NODE_MESH_ESTABLISHED) {
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
+ ni->ni_macaddr, NULL,
+ "peer link not yet established (%s)",
+ nodemeshstates[ni->ni_peerstate]);
+ }
hdrspace = ieee80211_hdrspace(ic, wh)
- + sizeof(struct ieee80211_meshcontrol);
+ + sizeof(struct ieee80211_meshcntl);
if (m->m_len < hdrspace &&
(m = m_pullup(m, hdrspace)) == NULL) {
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
@@ -489,7 +487,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
if ((scan.capinfo & (IEEE80211_CAPINFO_ESS|IEEE80211_CAPINFO_IBSS)) == 0 &&
!IEEE80211_ADDR_EQ(wh->i_addr2, ni->ni_macaddr) &&
IEEE80211_ADDR_EQ(wh->i_addr3, zerobssid)) {
- uint16_t args[4];
+ union ieee80211_send_action_args vargs;
/*
* Create a new entry in the neighbor table.
*/
@@ -507,10 +505,10 @@ mesh_recv_mgmt(struct ieee80211_node *ni
IEEE80211_MSG_MESH,
ni, "peer link: switching to state %s",
nodemeshstates[ni->ni_peerstate]);
- args[0] = ni->ni_plid;
+ vargs.fixedarg[0] = ni->ni_plid;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_OPEN, args);
+ IEEE80211_ACTION_MESHPEERING_OPEN, vargs);
ni->ni_mrcount = 0;
mesh_peer_timeout_setup(ni);
}
@@ -631,8 +629,9 @@ mesh_recv_action(struct ieee80211_node *
struct ieee80211_meshid_ie *meshid;
struct ieee80211_meshconf_ie *meshconf;
struct ieee80211_meshpeer_ie *meshpeer;
+ struct ieee80211_meshpreq_ie *meshpreq;
uint8_t *frm, *efrm;
- uint16_t args[4];
+ union ieee80211_send_action_args vargs;
wh = mtod(m0, struct ieee80211_frame *);
ia = (struct ieee80211_action *) &wh[1];
@@ -652,6 +651,7 @@ mesh_recv_action(struct ieee80211_node *
meshid = NULL;
meshpeer = NULL;
meshconf = NULL;
+ meshpreq = NULL;
while (efrm - frm > 1) {
IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
switch (*frm) {
@@ -663,32 +663,44 @@ mesh_recv_action(struct ieee80211_node *
break;
case IEEE80211_ELEMID_MESHPEER:
meshpeer = (struct ieee80211_meshpeer_ie *) frm;
- meshpeer->peer_llinkid = LE_READ_2(&meshpeer->peer_llinkid);
- meshpeer->peer_linkid = LE_READ_2(&meshpeer->peer_linkid);
- meshpeer->peer_rcode = LE_READ_2(&meshpeer->peer_rcode);
+ meshpeer->peer_llinkid =
+ LE_READ_2(&meshpeer->peer_llinkid);
+ meshpeer->peer_linkid =
+ LE_READ_2(&meshpeer->peer_linkid);
+ meshpeer->peer_rcode =
+ LE_READ_2(&meshpeer->peer_rcode);
+ break;
+ case IEEE80211_ELEMID_MESHPREQ:
+ meshpreq = (struct ieee80211_meshpreq_ie *) frm;
+ meshpreq->preq_id = LE_READ_4(&meshpreq->preq_id);
+ meshpreq->preq_origseq =
+ LE_READ_4(&meshpreq->preq_origseq);
+ meshpreq->preq_lifetime =
+ LE_READ_4(&meshpreq->preq_lifetime);
+ meshpreq->preq_metric =
+ LE_READ_4(&meshpreq->preq_metric);
break;
}
frm += frm[1] + 2;
}
- /*
- * Check if we agree on Mesh ID and Configuration.
- * XXX: TBD
- */
- if (mesh_verify_meshid(vap, meshid) ||
- mesh_verify_meshconf(vap, meshconf) ||
- !meshpeer) {
- IEEE80211_DISCARD(vap,
- IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
- wh, NULL, "%s", "action frame not for our mesh");
- vap->iv_stats.is_rx_mgtdiscard++;
- return;
- }
/*
* Mesh Peer Link Management Finite State Machine handling.
*/
switch (ia->ia_category) {
case IEEE80211_ACTION_CAT_MESHPEERING:
+ /*
+ * Check if we agree on the required fields.
+ */
+ if (mesh_verify_meshid(vap, meshid) ||
+ mesh_verify_meshconf(vap, meshconf) ||
+ !meshpeer) {
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+ wh, NULL, "%s", "action frame not for our mesh");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ return;
+ }
switch (ia->ia_action) {
case IEEE80211_ACTION_MESHPEERING_OPEN:
IEEE80211_NOTE(vap,
@@ -703,27 +715,29 @@ mesh_recv_action(struct ieee80211_node *
nodemeshstates[ni->ni_peerstate]);
ni->ni_llid = meshpeer->peer_llinkid;
get_random_bytes(&ni->ni_plid, 2);
- args[0] = ni->ni_plid;
+ vargs.fixedarg[0] = ni->ni_plid;
/* Announce we're open too... */
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_OPEN, args);
+ IEEE80211_ACTION_MESHPEERING_OPEN, vargs);
/* ...and confirm the link. */
- args[0] = ni->ni_plid;
- args[1] = ni->ni_llid;
+ vargs.fixedarg[0] = ni->ni_plid;
+ vargs.fixedarg[1] = ni->ni_llid;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CONFIRM, args);
+ IEEE80211_ACTION_MESHPEERING_CONFIRM,
+ vargs);
mesh_peer_timeout_setup(ni);
break;
case IEEE80211_NODE_MESH_OPENRCV:
- /* We received a duplicate open, confirm again. */
+ /* Duplicate open, confirm again. */
ni->ni_llid = meshpeer->peer_llinkid;
- args[0] = ni->ni_plid;
- args[1] = ni->ni_llid;
+ vargs.fixedarg[0] = ni->ni_plid;
+ vargs.fixedarg[1] = ni->ni_llid;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CONFIRM, args);
+ IEEE80211_ACTION_MESHPEERING_CONFIRM,
+ vargs);
break;
case IEEE80211_NODE_MESH_OPENSNT:
ni->ni_peerstate = IEEE80211_NODE_MESH_OPENRCV;
@@ -732,41 +746,47 @@ mesh_recv_action(struct ieee80211_node *
IEEE80211_MSG_MESH,
ni, "peer link: switching to state %s",
nodemeshstates[ni->ni_peerstate]);
- args[0] = ni->ni_plid;
- args[1] = ni->ni_llid;
+ vargs.fixedarg[0] = ni->ni_plid;
+ vargs.fixedarg[1] = ni->ni_llid;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CONFIRM, args);
+ IEEE80211_ACTION_MESHPEERING_CONFIRM,
+ vargs);
/* NB: don't setup/clear any timeout */
break;
case IEEE80211_NODE_MESH_CONFIRMRECV:
- ni->ni_peerstate = IEEE80211_NODE_MESH_ESTABLISHED;
+ ni->ni_peerstate =
+ IEEE80211_NODE_MESH_ESTABLISHED;
IEEE80211_NOTE(vap,
IEEE80211_MSG_MESH,
ni, "peer link: switching to state %s",
nodemeshstates[ni->ni_peerstate]);
ni->ni_llid = meshpeer->peer_llinkid;
- args[0] = ni->ni_plid;
- args[1] = ni->ni_llid;
+ vargs.fixedarg[0] = ni->ni_plid;
+ vargs.fixedarg[1] = ni->ni_llid;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CONFIRM, args);
+ IEEE80211_ACTION_MESHPEERING_CONFIRM,
+ vargs);
mesh_peer_timeout_stop(ni);
break;
case IEEE80211_NODE_MESH_ESTABLISHED:
- args[0] = ni->ni_plid;
- args[1] = ni->ni_llid;
+ vargs.fixedarg[0] = ni->ni_plid;
+ vargs.fixedarg[1] = ni->ni_llid;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CONFIRM, args);
+ IEEE80211_ACTION_MESHPEERING_CONFIRM,
+ vargs);
break;
case IEEE80211_NODE_MESH_HOLDING:
- args[0] = ni->ni_llid;
- args[1] = ni->ni_plid;
- args[2] = IEEE80211_REASON_MESH_MAX_RETRIES;
+ vargs.fixedarg[0] = ni->ni_llid;
+ vargs.fixedarg[1] = ni->ni_plid;
+ vargs.fixedarg[2] =
+ IEEE80211_REASON_MESH_MAX_RETRIES;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CLOSE, args);
+ IEEE80211_ACTION_MESHPEERING_CLOSE,
+ vargs);
break;
}
break;
@@ -777,7 +797,8 @@ mesh_recv_action(struct ieee80211_node *
meshpeer->peer_llinkid, meshpeer->peer_linkid);
switch (ni->ni_peerstate) {
case IEEE80211_NODE_MESH_OPENRCV:
- ni->ni_peerstate = IEEE80211_NODE_MESH_ESTABLISHED;
+ ni->ni_peerstate =
+ IEEE80211_NODE_MESH_ESTABLISHED;
IEEE80211_NOTE(vap,
IEEE80211_MSG_MESH,
ni, "peer link: switching to state %s",
@@ -785,19 +806,21 @@ mesh_recv_action(struct ieee80211_node *
mesh_peer_timeout_stop(ni);
break;
case IEEE80211_NODE_MESH_OPENSNT:
- ni->ni_peerstate = IEEE80211_NODE_MESH_CONFIRMRECV;
+ ni->ni_peerstate =
+ IEEE80211_NODE_MESH_CONFIRMRECV;
IEEE80211_NOTE(vap,
IEEE80211_MSG_MESH,
ni, "peer link: switching to state %s",
nodemeshstates[ni->ni_peerstate]);
break;
case IEEE80211_NODE_MESH_HOLDING:
- args[0] = ni->ni_llid;
- args[1] = ni->ni_plid;
- args[2] = IEEE80211_REASON_MESH_MAX_RETRIES;
+ vargs.fixedarg[0] = ni->ni_llid;
+ vargs.fixedarg[1] = ni->ni_plid;
+ vargs.fixedarg[2] = IEEE80211_REASON_MESH_MAX_RETRIES;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CLOSE, args);
+ IEEE80211_ACTION_MESHPEERING_CLOSE,
+ vargs);
break;
default:
IEEE80211_DISCARD(vap,
@@ -824,8 +847,49 @@ mesh_recv_action(struct ieee80211_node *
break;
}
break;
+ case IEEE80211_ACTION_CAT_MESHPATH:
+ switch (ia->ia_action) {
+ case IEEE80211_ACTION_MESHPATH_REQ:
+ if (meshpreq == NULL) {
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+ wh, NULL, "%s", "preq without IE");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ return;
+ }
+ /*
+ * Is the peer trying to find us?
+ */
+ if (IEEE80211_ADDR_EQ(vap->iv_myaddr,
+ meshpreq->preq_targets[0].target_addr)) {
+ struct ieee80211_meshprep_ie prep;
+ /*
+ * Build and send a path reply frame.
+ */
+ prep.prep_flags = 0;
+ prep.prep_hopcount = 0;
+ prep.prep_ttl = ieee80211_mesh_ttl;
+ IEEE80211_ADDR_COPY(prep.prep_targetaddr,
+ meshpreq->preq_targets[0].target_addr);
+ prep.prep_targetseq = meshpreq->preq_origseq;
+ prep.prep_lifetime = 5000;
+ prep.prep_metric = 0;
+ IEEE80211_ADDR_COPY(prep.prep_origaddr,
+ vap->iv_myaddr);
+ prep.prep_origseq = 1;
+
+ vargs.ptrarg = &prep;
+ ieee80211_send_action(ni,
+ IEEE80211_ACTION_CAT_MESHPATH,
+ IEEE80211_ACTION_MESHPATH_REP,
+ vargs);
+ }
+ break;
+ }
+ break;
default:
- IEEE80211_DISCARD(vap, IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
wh, NULL, "%s", "not handled");
vap->iv_stats.is_rx_mgtdiscard++;
}
@@ -876,7 +940,7 @@ mesh_peer_timeout_cb(void *arg)
{
struct ieee80211_node *ni = (struct ieee80211_node *)arg;
struct ieee80211vap *vap = ni->ni_vap;
- uint16_t args[4];
+ union ieee80211_send_action_args vargs;
IEEE80211_NOTE(vap,
IEEE80211_MSG_MESH,
@@ -887,11 +951,11 @@ mesh_peer_timeout_cb(void *arg)
case IEEE80211_NODE_MESH_OPENSNT:
case IEEE80211_NODE_MESH_OPENRCV:
if (ni->ni_mrcount == ieee80211_mesh_maxretries) {
- args[0] = ni->ni_plid;
- args[2] = IEEE80211_REASON_MESH_MAX_RETRIES;
+ vargs.fixedarg[0] = ni->ni_plid;
+ vargs.fixedarg[2] = IEEE80211_REASON_MESH_MAX_RETRIES;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CLOSE, args);
+ IEEE80211_ACTION_MESHPEERING_CLOSE, vargs);
ni->ni_mrcount = 0;
ni->ni_peerstate = IEEE80211_NODE_MESH_HOLDING;
IEEE80211_NOTE(vap,
@@ -900,21 +964,22 @@ mesh_peer_timeout_cb(void *arg)
nodemeshstates[ni->ni_peerstate]);
mesh_peer_timeout_setup(ni);
} else {
- args[0] = ni->ni_plid;
+ vargs.fixedarg[0] = ni->ni_plid;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_OPEN, args);
+ IEEE80211_ACTION_MESHPEERING_OPEN, vargs);
ni->ni_mrcount++;
mesh_peer_timeout_backoff(ni);
}
break;
case IEEE80211_NODE_MESH_CONFIRMRECV:
if (ni->ni_mrcount == ieee80211_mesh_maxretries) {
- args[0] = ni->ni_plid;
- args[2] = IEEE80211_REASON_MESH_CONFIRM_TIMEOUT;
+ vargs.fixedarg[0] = ni->ni_plid;
+ vargs.fixedarg[2] =
+ IEEE80211_REASON_MESH_CONFIRM_TIMEOUT;
ieee80211_send_action(ni,
IEEE80211_ACTION_CAT_MESHPEERING,
- IEEE80211_ACTION_MESHPEERING_CLOSE, args);
+ IEEE80211_ACTION_MESHPEERING_CLOSE, vargs);
ni->ni_mrcount = 0;
ni->ni_peerstate = IEEE80211_NODE_MESH_HOLDING;
IEEE80211_NOTE(vap,
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.h Thu May 14 16:56:56 2009 (r192110)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.h Thu May 14 17:04:00 2009 (r192111)
@@ -215,7 +215,7 @@ struct ieee80211_meshpreq_ie {
uint8_t preq_flags;
uint8_t preq_hopcount;
uint8_t preq_ttl;
- uint8_t preq_id;
+ uint32_t preq_id;
uint8_t preq_origaddr[IEEE80211_ADDR_LEN];
uint32_t preq_origseq; /* HWMP Sequence Number */
/* NB: may have Originator Proxied Address */
@@ -226,7 +226,7 @@ struct ieee80211_meshpreq_ie {
uint8_t target_flags;
uint8_t target_addr[IEEE80211_ADDR_LEN];
uint32_t target_seq; /* HWMP Sequence Number */
- } targets[1] __packed; /* NB: variable size */
+ } preq_targets[1] __packed; /* NB: variable size */
} __packed;
/* Mesh Path Reply */
@@ -254,7 +254,7 @@ struct ieee80211_meshperr_ie {
struct {
uint8_t dest_addr[IEEE80211_ADDR_LEN];
uint32_t dest_seq; /* HWMP Sequence Number */
- } dests[1] __packed; /* NB: variable size */
+ } perr_dests[1] __packed; /* NB: variable size */
} __packed;
/* Mesh Proxy Update */
@@ -278,18 +278,30 @@ struct ieee80211_meshpuc_ie {
*/
#define IEEE80211_ACTION_CAT_MESHPEERING 30 /* XXX Linux */
#define IEEE80211_ACTION_CAT_MESHLINK 13
-#define IEEE80211_ACTION_CAT_PATHSEL 14
+#define IEEE80211_ACTION_CAT_MESHPATH 32 /* XXX Linux */
#define IEEE80211_ACTION_CAT_INTERWORK 15
#define IEEE80211_ACTION_CAT_RESOURCE 16
#define IEEE80211_ACTION_CAT_PROXY 17
+/*
+ * Mesh Peering Action codes.
+ */
enum {
IEEE80211_ACTION_MESHPEERING_OPEN = 0,
IEEE80211_ACTION_MESHPEERING_CONFIRM = 1,
IEEE80211_ACTION_MESHPEERING_CLOSE = 2,
};
-struct ieee80211_meshcontrol {
+/*
+ * Mesh Path Selection Action codes.
+ */
+enum {
+ IEEE80211_ACTION_MESHPATH_REQ = 0,
+ IEEE80211_ACTION_MESHPATH_REP = 1,
+ IEEE80211_ACTION_MESHPATH_ERR = 2,
+};
+
+struct ieee80211_meshcntl {
uint8_t mc_flags;
uint8_t mc_ttl;
uint32_t mc_seq;
Modified: projects/mesh11s/sys/net80211/ieee80211_output.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_output.c Thu May 14 16:56:56 2009 (r192110)
+++ projects/mesh11s/sys/net80211/ieee80211_output.c Thu May 14 17:04:00 2009 (r192111)
@@ -538,7 +538,7 @@ ieee80211_send_setup(
*/
int
ieee80211_send_action(struct ieee80211_node *ni,
- int category, int action, uint16_t args[4])
+ int category, int action, union ieee80211_send_action_args vargs)
{
#define senderr(_x, _v) do { vap->iv_stats._v++; ret = _x; goto bad; } while (0)
#define ADDSHORT(frm, v) do { \
@@ -555,7 +555,7 @@ ieee80211_send_action(struct ieee80211_n
struct mbuf *m;
uint8_t *frm;
uint16_t baparamset;
- int ret, addsize;
+ int ret, addsize = 0;
KASSERT(ni != NULL, ("null node"));
@@ -571,19 +571,32 @@ ieee80211_send_action(struct ieee80211_n
ieee80211_node_refcnt(ni)+1);
ieee80211_ref_node(ni);
- addsize = 0;
switch (category) {
case IEEE80211_ACTION_CAT_BA:
case IEEE80211_ACTION_CAT_HT:
- addsize += sizeof(struct ieee80211_action_ba_addbaresponse);
+ addsize = sizeof(struct ieee80211_action_ba_addbaresponse);
break;
case IEEE80211_ACTION_CAT_MESHPEERING:
- addsize += sizeof(uint16_t); /* capabilities */
- addsize += 2 + IEEE80211_RATE_SIZE;
- addsize += 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE);
- addsize += 2 + vap->iv_meshidlen; /* Mesh ID */
- addsize += sizeof(struct ieee80211_meshconf_ie);
- addsize += sizeof(struct ieee80211_meshpeer_ie);
+ addsize = sizeof(uint16_t) /* capabilities */
+ + 2 + IEEE80211_RATE_SIZE
+ + 2 + (IEEE80211_RATE_MAXSIZE - IEEE80211_RATE_SIZE)
+ + 2 + vap->iv_meshidlen /* Mesh ID */
+ + sizeof(struct ieee80211_meshconf_ie)
+ + sizeof(struct ieee80211_meshpeer_ie);
+ break;
+ case IEEE80211_ACTION_CAT_MESHPATH:
+ switch (action) {
+ case IEEE80211_ACTION_MESHPATH_REQ:
+ /* XXX more than one destination */
+ addsize = sizeof(struct ieee80211_meshpreq_ie);
+ break;
+ case IEEE80211_ACTION_MESHPATH_REP:
+ addsize = sizeof(struct ieee80211_meshprep_ie);
+ break;
+ case IEEE80211_ACTION_MESHPATH_ERR:
+ addsize = sizeof(struct ieee80211_meshperr_ie);
+ break;
+ }
break;
}
m = ieee80211_getmgtframe(&frm,
@@ -606,39 +619,43 @@ ieee80211_send_action(struct ieee80211_n
IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
"send ADDBA request: dialogtoken %d "
"baparamset 0x%x (tid %d) batimeout 0x%x baseqctl 0x%x",
- args[0], args[1], MS(args[1], IEEE80211_BAPS_TID),
- args[2], args[3]);
-
- *frm++ = args[0]; /* dialog token */
- ADDSHORT(frm, args[1]); /* baparamset */
- ADDSHORT(frm, args[2]); /* batimeout */
- ADDSHORT(frm, args[3]); /* baseqctl */
+ vargs.fixedarg[0], vargs.fixedarg[1],
+ MS(vargs.fixedarg[1], IEEE80211_BAPS_TID),
+ vargs.fixedarg[2], vargs.fixedarg[3]);
+
+ *frm++ = vargs.fixedarg[0]; /* dialog token */
+ ADDSHORT(frm, vargs.fixedarg[1]); /* baparamset */
+ ADDSHORT(frm, vargs.fixedarg[2]); /* batimeout */
+ ADDSHORT(frm, vargs.fixedarg[3]); /* baseqctl */
break;
case IEEE80211_ACTION_BA_ADDBA_RESPONSE:
IEEE80211_NOTE(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
"send ADDBA response: dialogtoken %d status %d "
"baparamset 0x%x (tid %d) batimeout %d",
- args[0], args[1], args[2],
- MS(args[2], IEEE80211_BAPS_TID), args[3]);
-
- *frm++ = args[0]; /* dialog token */
- ADDSHORT(frm, args[1]); /* statuscode */
- ADDSHORT(frm, args[2]); /* baparamset */
- ADDSHORT(frm, args[3]); /* batimeout */
+ vargs.fixedarg[0], vargs.fixedarg[1],
+ vargs.fixedarg[2], MS(vargs.fixedarg[2],
+ IEEE80211_BAPS_TID), vargs.fixedarg[3]);
+
+ *frm++ = vargs.fixedarg[0]; /* dialog token */
+ ADDSHORT(frm, vargs.fixedarg[1]); /* statuscode */
+ ADDSHORT(frm, vargs.fixedarg[2]); /* baparamset */
+ ADDSHORT(frm, vargs.fixedarg[3]); /* batimeout */
break;
case IEEE80211_ACTION_BA_DELBA:
/* XXX */
- baparamset = SM(args[0], IEEE80211_DELBAPS_TID)
- | args[1]
+ baparamset = SM(vargs.fixedarg[0],
+ IEEE80211_DELBAPS_TID)
+ | vargs.fixedarg[1]
;
ADDSHORT(frm, baparamset);
- ADDSHORT(frm, args[2]); /* reason code */
+ ADDSHORT(frm, vargs.fixedarg[2]); /* reason code */
IEEE80211_NOTE(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_11N, ni,
"send DELBA action: tid %d, initiator %d reason %d",
- args[0], args[1], args[2]);
+ vargs.fixedarg[0], vargs.fixedarg[1],
+ vargs.fixedarg[2]);
break;
default:
goto badaction;
@@ -677,14 +694,16 @@ ieee80211_send_action(struct ieee80211_n
case IEEE80211_ACTION_MESHPEERING_OPEN:
IEEE80211_NOTE(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
- "send PEER OPEN action: localid 0x%x", args[0]);
+ "send PEER OPEN action: localid 0x%x",
+ vargs.fixedarg[0]);
ADDSHORT(frm, getcapinfo(vap, ni->ni_chan));
frm = ieee80211_add_rates(frm, rs);
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, args[0], 0, 0);
+ IEEE80211_MESH_PEER_LINK_OPEN,
+ vargs.fixedarg[0], 0, 0);
break;
/*
* mesh peer confirm action frame format:
@@ -703,7 +722,8 @@ ieee80211_send_action(struct ieee80211_n
IEEE80211_NOTE(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
"send PEER CONFIRM action: localid 0x%x, "
- "peerid 0x%x", args[0], args[1]);
+ "peerid 0x%x", vargs.fixedarg[0],
+ vargs.fixedarg[1]);
ADDSHORT(frm, getcapinfo(vap, ni->ni_chan));
ADDSHORT(frm, 0); /* status code */
ADDSHORT(frm, 0); /* AID */
@@ -712,7 +732,8 @@ ieee80211_send_action(struct ieee80211_n
frm = ieee80211_add_meshid(frm, vap);
frm = ieee80211_add_meshconf(frm, vap);
frm = ieee80211_add_meshpeer(frm,
- IEEE80211_MESH_PEER_LINK_CONFIRM, args[0], args[1],
+ IEEE80211_MESH_PEER_LINK_CONFIRM,
+ vargs.fixedarg[0], vargs.fixedarg[1],
0);
break;
/*
@@ -727,15 +748,43 @@ ieee80211_send_action(struct ieee80211_n
IEEE80211_NOTE(vap,
IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
"sending PEER CLOSE action: localid 0x%x, "
- "peerid 0x%x reason %d", args[0], args[1], args[2]);
- ADDSHORT(frm, args[2]); /* reason code */
+ "peerid 0x%x reason %d", vargs.fixedarg[0],
+ vargs.fixedarg[1], vargs.fixedarg[2]);
+ ADDSHORT(frm, vargs.fixedarg[2]); /* reason code */
frm = ieee80211_add_meshid(frm, vap);
frm = ieee80211_add_meshpeer(frm,
- IEEE80211_MESH_PEER_LINK_CLOSE, args[0], args[1],
- args[2]);
+ IEEE80211_MESH_PEER_LINK_CLOSE,
+ vargs.fixedarg[0], vargs.fixedarg[1],
+ vargs.fixedarg[2]);
break;
}
break;
+ case IEEE80211_ACTION_CAT_MESHPATH:
+ switch (action) {
+ /*
+ * mesh path request action frame format:
+ * [1] action
+ * [1] category
+ * [tlv] mesh preq
+ */
+ case IEEE80211_ACTION_MESHPATH_REQ:
+ break;
+ /*
+ * mesh path request action frame format:
+ * [1] action
+ * [1] category
+ * [tlv] mesh preq
+ */
+ case IEEE80211_ACTION_MESHPATH_REP:
+ IEEE80211_NOTE(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH, ni,
+ "send PATH REPLY action: flags 0x%x, "
+ "hopcount 0x%x", vargs.fixedarg[0],
+ vargs.fixedarg[1]);
+
+ break;
+ }
+ break;
default:
badaction:
IEEE80211_NOTE(vap,
@@ -1237,7 +1286,7 @@ ieee80211_encap(struct ieee80211vap *vap
* All Mesh data frames have a Mesh Control field.
*/
if (vap->iv_opmode == IEEE80211_M_MBSS)
- hdrsize += sizeof(struct ieee80211_meshcontrol);
+ hdrsize += sizeof(struct ieee80211_meshcntl);
/*
* Honor driver DATAPAD requirement.
*/
Modified: projects/mesh11s/sys/net80211/ieee80211_proto.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_proto.h Thu May 14 16:56:56 2009 (r192110)
+++ projects/mesh11s/sys/net80211/ieee80211_proto.h Thu May 14 17:04:00 2009 (r192111)
@@ -65,7 +65,12 @@ void ieee80211_syncflag_ext(struct ieee8
int ieee80211_input_all(struct ieee80211com *, struct mbuf *,
int, int, uint32_t);
struct ieee80211_bpf_params;
-int ieee80211_send_action(struct ieee80211_node *, int, int, uint16_t [4]);
+union ieee80211_send_action_args {
+ uint16_t fixedarg[4];
+ void * ptrarg;
+};
+int ieee80211_send_action(struct ieee80211_node *, int, int,
+ union ieee80211_send_action_args);
int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int,
struct ieee80211_bpf_params *);
int ieee80211_raw_xmit(struct ieee80211_node *, struct mbuf *,
Modified: projects/mesh11s/sys/net80211/ieee80211_var.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_var.h Thu May 14 16:56:56 2009 (r192110)
+++ projects/mesh11s/sys/net80211/ieee80211_var.h Thu May 14 17:04:00 2009 (r192111)
@@ -276,7 +276,7 @@ struct ieee80211com {
const uint8_t *frm, const uint8_t *efrm);
int (*ic_send_action)(struct ieee80211_node *,
int category, int action,
- uint16_t args[4]);
+ union ieee80211_send_action_args);
/* check if A-MPDU should be enabled this station+ac */
int (*ic_ampdu_enable)(struct ieee80211_node *,
struct ieee80211_tx_ampdu *);
More information about the svn-src-projects
mailing list