Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 29 May 2009 00:14:59 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r193009 - projects/mesh11s/sys/net80211
Message-ID:  <200905290014.n4T0ExQl054307@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Fri May 29 00:14:59 2009
New Revision: 193009
URL: http://svn.freebsd.org/changeset/base/193009

Log:
  * add hwmp_send_action() function that will handle all mesh path action
  frames
  * add place holders for preq, prep, perr and rann action frames
  * make ieee80211_send_setup() global
  * use ieee80211_send_setup() in hwmp_send_action() thereby reducing code
  size
  * inline functions that just call hwmp_send_action()
  * don't use zerobssid. The standard says bssid = addr2 (sa) for non
  multhop action frames
  * add IEEE80211_IOC_HWMP_TABLE to fetch/set the HWMP forwarding table
  (not yet handled)
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/mesh11s/sys/net80211/ieee80211_hwmp.c
  projects/mesh11s/sys/net80211/ieee80211_ioctl.h
  projects/mesh11s/sys/net80211/ieee80211_mesh.h
  projects/mesh11s/sys/net80211/ieee80211_output.c
  projects/mesh11s/sys/net80211/ieee80211_proto.h

Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c	Thu May 28 23:23:49 2009	(r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c	Fri May 29 00:14:59 2009	(r193009)
@@ -78,16 +78,31 @@ struct ieee80211_hwmp_fi {
 };
 TAILQ_HEAD(, ieee80211_hwmp_fi)	ieee80211_hwmp_ft;
 
+static int	ieee80211_hwmp_send_action(struct ieee80211_node *,
+	const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+	const uint8_t *, size_t);
 static void	hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *,
     const struct ieee80211_meshpreq_ie *);
+static int	hwmp_send_preq(struct ieee80211_node *,
+    const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+    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 uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
     const struct ieee80211_meshprep_ie *);
 static void	hwmp_recv_perr(struct ieee80211vap *, struct ieee80211_node *,
     const struct ieee80211_meshperr_ie *);
+static int	hwmp_send_perr(struct ieee80211_node *,
+    const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+    const struct ieee80211_meshperr_ie *);
+static void	hwmp_recv_rann(struct ieee80211vap *, struct ieee80211_node *,
+    const struct ieee80211_meshrann_ie *);
+#ifdef notyet
+static int	hwmp_send_rann(struct ieee80211_node *,
+    const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+    const struct ieee80211_meshrann_ie *);
+#endif
 
 static int	ieee80211_hwmp_maxhops = 31;	
 #ifdef notyet
@@ -142,6 +157,7 @@ ieee80211_hwmp_recv_action(struct ieee80
 	struct ieee80211_meshpreq_ie *meshpreq = NULL;
 	struct ieee80211_meshprep_ie *meshprep = NULL;
 	struct ieee80211_meshperr_ie *meshperr = NULL;
+	struct ieee80211_meshrann_ie *meshrann = NULL;
 
 	wh = mtod(m0, struct ieee80211_frame *);
 	ia = (struct ieee80211_action *) &wh[1];
@@ -178,6 +194,12 @@ ieee80211_hwmp_recv_action(struct ieee80
 		case IEEE80211_ELEMID_MESHPERR:
 			meshperr = (struct ieee80211_meshperr_ie *) frm;
 			break;
+		case IEEE80211_ELEMID_MESHRANN:
+			meshrann = (struct ieee80211_meshrann_ie *) frm;
+			meshrann->rann_seq = LE_READ_4(&meshrann->rann_seq);
+			meshrann->rann_metric =
+			    LE_READ_4(&meshrann->rann_metric);
+			break;
 		}
 		frm += frm[1] + 2;
 	}
@@ -213,6 +235,16 @@ ieee80211_hwmp_recv_action(struct ieee80
 		}
 		hwmp_recv_perr(vap, ni, meshperr);
 		break;
+	case IEEE80211_ACTION_MESHPATH_RANN:
+		if (meshrann == NULL) {
+			IEEE80211_DISCARD(vap,
+			    IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+			    wh, NULL, "%s", "RANN without IE");
+			vap->iv_stats.is_rx_mgtdiscard++;
+			return;
+		}
+		hwmp_recv_rann(vap, ni, meshrann);
+		break;
 	default:
 		IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
 		    ni->ni_macaddr, NULL,
@@ -221,6 +253,88 @@ ieee80211_hwmp_recv_action(struct ieee80
 
 }
 
+static int
+ieee80211_hwmp_send_action(struct ieee80211_node *ni,
+    const uint8_t addr1[IEEE80211_ADDR_LEN],
+    const uint8_t addr2[IEEE80211_ADDR_LEN],
+    const uint8_t *ie, size_t len)
+{
+	struct ieee80211vap *vap = ni->ni_vap;
+	struct ieee80211com *ic = ni->ni_ic;
+	struct ieee80211_bpf_params params;
+	struct mbuf *m;
+	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);
+
+	m = ieee80211_getmgtframe(&frm,
+	    ic->ic_headroom + sizeof(struct ieee80211_frame),
+	    sizeof(struct ieee80211_action) + len
+	);
+	if (m == NULL) {
+		ieee80211_free_node(ni);
+		vap->iv_stats.is_tx_nobuf++;
+		return ENOMEM;
+	}
+	*frm++ = IEEE80211_ACTION_CAT_MESHPATH;
+	switch (*ie) {
+	case IEEE80211_ELEMID_MESHPREQ:
+		*frm++ = IEEE80211_ACTION_MESHPATH_REQ;
+		break;
+	case IEEE80211_ELEMID_MESHPREP:
+		*frm++ = IEEE80211_ACTION_MESHPATH_REP;
+		frm = ieee80211_add_meshprep(frm,
+		    (struct ieee80211_meshprep_ie *)&ie);
+		break;
+	case IEEE80211_ELEMID_MESHPERR:
+		*frm++ = IEEE80211_ACTION_MESHPATH_ERR;
+		break;
+	case IEEE80211_ELEMID_MESHRANN:
+		*frm++ = IEEE80211_ACTION_MESHPATH_RANN;
+		break;
+	}
+
+	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;
+	}
+	ieee80211_send_setup(ni, m,
+	    IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION,
+	    IEEE80211_NONQOS_TID, addr1, addr2, addr2);
+
+	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);
+}
 
 #define ADDWORD(frm, v) do {		\
 	frm[0] = (v) & 0xff;		\
@@ -334,6 +448,25 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 #undef PREQ_TADDR
 #undef PREQ_TSEQ
 
+static inline int
+hwmp_send_preq(struct ieee80211_node *ni,
+    const uint8_t addr1[IEEE80211_ADDR_LEN],
+    const uint8_t addr2[IEEE80211_ADDR_LEN],
+    const struct ieee80211_meshpreq_ie *preq)
+{
+	/*
+	 * mesh preq action frame format
+	 *     [6] addr1
+	 *     [6] addr2
+	 *     [6] addr3 = addr2
+	 *     [1] action
+	 *     [1] category
+	 *     [tlv] mesh path request
+	 */
+	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&preq,
+	    sizeof(*preq));
+}
+
 static void
 hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
     const struct ieee80211_meshprep_ie *prep)
@@ -389,104 +522,81 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 
 
 }
-static int
+
+static inline 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
+	 *     [6] addr3 = 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;
+	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&prep,
+	    sizeof(*prep));
+}
 
-	m->m_flags |= M_ENCAP;		/* mark encapsulated */
-	IEEE80211_NODE_STAT(ni, tx_mgmt);
+static void
+hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
+    const struct ieee80211_meshperr_ie *perr)
+{
 
-	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 inline int
+hwmp_send_perr(struct ieee80211_node *ni,
+    const uint8_t addr1[IEEE80211_ADDR_LEN],
+    const uint8_t addr2[IEEE80211_ADDR_LEN],
+    const struct ieee80211_meshperr_ie *perr)
+{
+	/*
+	 * mesh perr action frame format
+	 *     [6] addr1
+	 *     [6] addr2
+	 *     [6] addr3 = addr2
+	 *     [1] action
+	 *     [1] category
+	 *     [tlv] mesh path error
+	 */
+	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&perr,
+	    sizeof(*perr));
 }
 
 static void
-hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
-    const struct ieee80211_meshperr_ie *perr)
+hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni,
+    const struct ieee80211_meshrann_ie *rann)
 {
 
 }
 
+#ifdef notyet
+static int
+hwmp_send_rann(struct ieee80211_node *ni,
+    const uint8_t addr1[IEEE80211_ADDR_LEN],
+    const uint8_t addr2[IEEE80211_ADDR_LEN],
+    const struct ieee80211_meshrann_ie *rann)
+{
+	/*
+	 * mesh rann action frame format
+	 *     [6] addr1
+	 *     [6] addr2
+	 *     [6] addr3 = addr2
+	 *     [1] action
+	 *     [1] category
+	 *     [tlv] root annoucement
+	 */
+	return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&rann,
+	    sizeof(*rann));
+}
+#endif
+
 static int
 hwmp_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
 {
@@ -494,11 +604,9 @@ hwmp_ioctl_get80211(struct ieee80211vap 
 
 	error = 0;
 	switch (ireq->i_type) {
-#ifdef notyet
-	case IEEE80211_IOC_HWMPFI:
+	case IEEE80211_IOC_HWMP_TABLE:
 		if (vap->iv_opmode != IEEE80211_M_MBSS)
 			return EINVAL;
-#endif
 	default:
 		return ENOSYS;
 	}
@@ -514,9 +622,9 @@ hwmp_ioctl_set80211(struct ieee80211vap 
 
 	error = 0;
 	switch (ireq->i_type) {
-#ifdef notyet
-	case IEEE80211_IOC_HWMPFI:
-#endif
+	case IEEE80211_IOC_HWMP_TABLE:
+		if (vap->iv_opmode != IEEE80211_M_MBSS)
+			return EINVAL;
 	default:
 		return ENOSYS;
 	}

Modified: projects/mesh11s/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ioctl.h	Thu May 28 23:23:49 2009	(r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_ioctl.h	Fri May 29 00:14:59 2009	(r193009)
@@ -634,6 +634,7 @@ struct ieee80211req {
 #define	IEEE80211_IOC_RIFS		111	/* RIFS config (on, off) */
 
 #define	IEEE80211_IOC_MESH_ID		190	/* Mesh identifier */
+#define	IEEE80211_IOC_HWMP_TABLE	195	/* HWMP Forwarding Table */
 
 #define	IEEE80211_IOC_TDMA_SLOT		201	/* TDMA: assigned slot */
 #define	IEEE80211_IOC_TDMA_SLOTCNT	202	/* TDMA: slots in bss */

Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.h	Thu May 28 23:23:49 2009	(r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.h	Fri May 29 00:14:59 2009	(r193009)
@@ -217,6 +217,7 @@ struct ieee80211_meshrann_ie {
 	uint8_t		rann_ie;		/* IEEE80211_ELEMID_MESHRANN */
 	uint8_t		rann_len;
 	uint8_t		rann_flags;
+#define	IEEE80211_MESHRANN_FLAGS_PR	0x01	/* Portal Role */
 	uint8_t		rann_hopcount;
 	uint8_t		rann_ttl;
 	uint8_t		rann_addr[IEEE80211_ADDR_LEN];
@@ -324,7 +325,8 @@ enum {
 	IEEE80211_ACTION_MESHPATH_REQ	= 0,
 	IEEE80211_ACTION_MESHPATH_REP	= 1,
 	IEEE80211_ACTION_MESHPATH_ERR	= 2,
-	/* 3-255 reserved */
+	IEEE80211_ACTION_MESHPATH_RANN	= 3,
+	/* 4-255 reserved */
 };
 
 /*

Modified: projects/mesh11s/sys/net80211/ieee80211_output.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_output.c	Thu May 28 23:23:49 2009	(r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_output.c	Fri May 29 00:14:59 2009	(r193009)
@@ -457,7 +457,7 @@ bad:
  * frame.  Note this should be called early on in constructing
  * a frame as it sets i_fc[1]; other bits can then be or'd in.
  */
-static void
+void
 ieee80211_send_setup(
 	struct ieee80211_node *ni,
 	struct mbuf *m,
@@ -467,7 +467,6 @@ ieee80211_send_setup(
 	const uint8_t bssid[IEEE80211_ADDR_LEN])
 {
 #define	WH4(wh)	((struct ieee80211_frame_addr4 *)wh)
-	static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
 	struct ieee80211vap *vap = ni->ni_vap;
 	struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
 	ieee80211_seq seqno;
@@ -510,7 +509,7 @@ ieee80211_send_setup(
 		IEEE80211_ADDR_COPY(wh->i_addr1, da);
 		IEEE80211_ADDR_COPY(wh->i_addr2, sa);
 		if (vap->iv_opmode == IEEE80211_M_MBSS)
-			IEEE80211_ADDR_COPY(wh->i_addr3, zerobssid);
+			IEEE80211_ADDR_COPY(wh->i_addr3, sa);
 		else
 			IEEE80211_ADDR_COPY(wh->i_addr3, bssid);
 	}

Modified: projects/mesh11s/sys/net80211/ieee80211_proto.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_proto.h	Thu May 28 23:23:49 2009	(r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_proto.h	Fri May 29 00:14:59 2009	(r193009)
@@ -76,6 +76,9 @@ int	ieee80211_raw_xmit(struct ieee80211_
 		const struct ieee80211_bpf_params *);
 int	ieee80211_output(struct ifnet *, struct mbuf *,
                struct sockaddr *, struct route *ro);
+void	ieee80211_send_setup(struct ieee80211_node *, struct mbuf *, int, int,
+        const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+        const uint8_t [IEEE80211_ADDR_LEN]);
 void	ieee80211_start(struct ifnet *);
 int	ieee80211_send_nulldata(struct ieee80211_node *);
 int	ieee80211_classify(struct ieee80211_node *, struct mbuf *m);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905290014.n4T0ExQl054307>