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