Date: Thu, 14 May 2009 17:04:01 +0000 (UTC) From: Rui Paulo <rpaulo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r192111 - projects/mesh11s/sys/net80211 Message-ID: <200905141704.n4EH41Oj097125@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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 *);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905141704.n4EH41Oj097125>