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(&params, 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, &params);
+}
 
 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