svn commit: r192941 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Thu May 28 00:05:16 UTC 2009
Author: rpaulo
Date: Thu May 28 00:05:16 2009
New Revision: 192941
URL: http://svn.freebsd.org/changeset/base/192941
Log:
Build our own function to send action frames with path replies because
ieee80211_send_action() is only for unicast frames.
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_hwmp.c
projects/mesh11s/sys/net80211/ieee80211_hwmp.h
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c Wed May 27 23:45:39 2009 (r192940)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Thu May 28 00:05:16 2009 (r192941)
@@ -82,6 +82,10 @@ static void hwmp_recv_preq(struct ieee80
const struct ieee80211_meshpreq_ie *);
static void hwmp_recv_prep(struct ieee80211vap *, struct ieee80211_node *,
const struct ieee80211_meshprep_ie *);
+static int hwmp_send_prep(struct ieee80211_node *,
+ const uint8_t addr1[IEEE80211_ADDR_LEN],
+ const uint8_t addr2[IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshprep_ie *);
static void hwmp_recv_perr(struct ieee80211vap *, struct ieee80211_node *,
const struct ieee80211_meshperr_ie *);
@@ -229,7 +233,7 @@ ieee80211_hwmp_recv_action(struct ieee80
* Add a Mesh Path Reply IE to a frame.
*/
uint8_t *
-ieee80211_add_meshprep(uint8_t *frm, struct ieee80211_meshprep_ie *prep)
+ieee80211_add_meshprep(uint8_t *frm, const struct ieee80211_meshprep_ie *prep)
{
*frm++ = IEEE80211_ELEMID_MESHPREP;
@@ -256,8 +260,6 @@ static void
hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
const struct ieee80211_meshpreq_ie *preq)
{
- union ieee80211_send_action_args vargs;
-
/*
* Acceptance criteria: if the PREQ is not for us and
* forwarding is disabled, discard this PREQ.
@@ -294,9 +296,8 @@ hwmp_recv_preq(struct ieee80211vap *vap,
IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr);
/* XXX */
prep.prep_origseq = 1;
- vargs.ptrarg = &prep;
- ieee80211_send_action(ni, IEEE80211_ACTION_CAT_MESHPATH,
- IEEE80211_ACTION_MESHPATH_REP, vargs);
+ /* XXX addr1 = next hop */
+ hwmp_send_prep(ni, preq->preq_origaddr, vap->iv_myaddr, &prep);
return;
}
@@ -388,6 +389,96 @@ hwmp_recv_prep(struct ieee80211vap *vap,
}
+static int
+hwmp_send_prep(struct ieee80211_node *ni,
+ const uint8_t addr1[IEEE80211_ADDR_LEN],
+ const uint8_t addr2[IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshprep_ie *prep)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_frame *wh;
+ struct ieee80211_bpf_params params;
+ struct mbuf *m;
+ ieee80211_seq seqno;
+ uint8_t *frm;
+
+ if (vap->iv_state == IEEE80211_S_CAC) {
+ IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
+ "block %s frame in CAC state", "probe request");
+ vap->iv_stats.is_tx_badstate++;
+ return EIO; /* XXX */
+ }
+
+ KASSERT(ni != NULL, ("null node"));
+ /*
+ * Hold a reference on the node so it doesn't go away until after
+ * the xmit is complete all the way in the driver. On error we
+ * will remove our reference.
+ */
+ 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);
+
+
+ /*
+ * mesh prep action frame format
+ * [6] addr1
+ * [6] addr2
+ * [6] addr2
+ * [1] action
+ * [1] category
+ * [tlv] mesh path reply
+ */
+ m = ieee80211_getmgtframe(&frm,
+ ic->ic_headroom + sizeof(struct ieee80211_frame),
+ sizeof(struct ieee80211_action) +
+ sizeof(struct ieee80211_meshprep_ie)
+ );
+ if (m == NULL) {
+ ieee80211_free_node(ni);
+ vap->iv_stats.is_tx_nobuf++;
+ return ENOMEM;
+ }
+ *frm++ = IEEE80211_ACTION_CAT_MESHPATH;
+ *frm++ = IEEE80211_ACTION_MESHPATH_REP;
+ frm = ieee80211_add_meshprep(frm, prep);
+ m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
+ M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
+ if (m == NULL) {
+ ieee80211_free_node(ni);
+ vap->iv_stats.is_tx_nobuf++;
+ return ENOMEM;
+ }
+ wh = mtod(m, struct ieee80211_frame *);
+ wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
+ IEEE80211_FC0_SUBTYPE_ACTION;
+ wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS;
+ IEEE80211_ADDR_COPY(wh->i_addr1, addr1);
+ IEEE80211_ADDR_COPY(wh->i_addr2, addr2);
+ IEEE80211_ADDR_COPY(wh->i_addr3, addr2);
+ *(uint16_t *)&wh->i_dur[0] = 0;
+ seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
+ *(uint16_t *)&wh->i_seq[0] = htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
+ M_SEQNO_SET(m, seqno);
+ if (IEEE80211_IS_MULTICAST(wh->i_addr1))
+ m->m_flags |= M_MCAST;
+
+ m->m_flags |= M_ENCAP; /* mark encapsulated */
+ IEEE80211_NODE_STAT(ni, tx_mgmt);
+
+ memset(¶ms, 0, sizeof(params));
+ params.ibp_pri = WME_AC_VO;
+ params.ibp_rate0 = ni->ni_txparms->mgmtrate;
+ /* XXX: NB: we know all frames are unicast */
+ params.ibp_try0 = ni->ni_txparms->maxretry;
+ params.ibp_power = ni->ni_txpower;
+
+ return ic->ic_raw_xmit(ni, m, ¶ms);
+}
static void
hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.h Wed May 27 23:45:39 2009 (r192940)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.h Thu May 28 00:05:16 2009 (r192941)
@@ -34,7 +34,7 @@
void ieee80211_hwmp_recv_action(struct ieee80211vap *,
struct ieee80211_node *, struct mbuf *);
uint8_t * ieee80211_add_meshprep(uint8_t *,
- struct ieee80211_meshprep_ie *);
+ const struct ieee80211_meshprep_ie *);
#if 0
uint8_t * ieee80211_add_meshpreq(uint8_t *,
struct ieee80211_meshpreq_ie *);
More information about the svn-src-projects
mailing list