svn commit: r191574 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Mon Apr 27 18:15:42 UTC 2009
Author: rpaulo
Date: Mon Apr 27 18:15:41 2009
New Revision: 191574
URL: http://svn.freebsd.org/changeset/base/191574
Log:
* Simplify and fix add_meshid function()
* Implement code to deal with probe request frames (similar to other
operating modes)
* Setup the bss id (technically there's no BSS ID in mesh, so I must
revisit this in the future).
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_mesh.c
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Apr 27 18:10:42 2009 (r191573)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c Mon Apr 27 18:15:41 2009 (r191574)
@@ -293,6 +293,22 @@ out:
return type;
}
+static int
+is11bclient(const uint8_t *rates, const uint8_t *xrates)
+{
+ static const uint32_t brates = (1<<2*1)|(1<<2*2)|(1<<11)|(1<<2*11);
+ int i;
+
+ /* NB: the 11b clients we care about will not have xrates */
+ if (xrates != NULL || rates == NULL)
+ return 0;
+ for (i = 0; i < rates[1]; i++) {
+ int r = rates[2+i] & IEEE80211_RATE_VAL;
+ if (r > 2*11 || ((1<<r) & brates) == 0)
+ return 0;
+ }
+ return 1;
+}
static void
mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
@@ -349,7 +365,76 @@ mesh_recv_mgmt(struct ieee80211_node *ni
break;
}
case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
+ {
+ uint8_t *ssid, *meshid, *rates, *xrates;
+ uint8_t *sfrm;
+
+ if (vap->iv_state != IEEE80211_S_RUN) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "wrong state %s",
+ ieee80211_state_name[vap->iv_state]);
+ vap->iv_stats.is_rx_mgtdiscard++;
+ return;
+ }
+ if (IEEE80211_IS_MULTICAST(wh->i_addr2)) {
+ /* frame must be directed */
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, NULL, "%s", "not unicast");
+ vap->iv_stats.is_rx_mgtdiscard++; /* XXX stat */
+ return;
+ }
+
+ /*
+ * prreq frame format
+ * [tlv] ssid
+ * [tlv] supported rates
+ * [tlv] extended supported rates
+ * [tlv] Mesh ID
+ */
+ ssid = meshid = rates = xrates = NULL;
+ sfrm = frm;
+ while (efrm - frm > 1) {
+ IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1] + 2, return);
+ switch (*frm) {
+ case IEEE80211_ELEMID_SSID:
+ ssid = frm;
+ break;
+ case IEEE80211_ELEMID_RATES:
+ rates = frm;
+ break;
+ case IEEE80211_ELEMID_XRATES:
+ xrates = frm;
+ break;
+ case IEEE80211_ELEMID_MESHID:
+ meshid = frm;
+ break;
+ }
+ frm += frm[2] + 2;
+ }
+ IEEE80211_VERIFY_ELEMENT(ssid, IEEE80211_NWID_LEN, return);
+ IEEE80211_VERIFY_ELEMENT(rates, IEEE80211_RATE_MAXSIZE, return);
+ if (xrates != NULL)
+ IEEE80211_VERIFY_ELEMENT(xrates,
+ IEEE80211_RATE_MAXSIZE - rates[1], return);
+ if (meshid != NULL)
+ IEEE80211_VERIFY_ELEMENT(meshid,
+ IEEE80211_MESHID_LEN, return);
+ IEEE80211_VERIFY_SSID(vap->iv_bss, ssid, return);
+ /* XXX add verify meshid ? */
+
+ /* XXX find a better class or define it's own */
+ IEEE80211_NOTE_MAC(vap, IEEE80211_MSG_INPUT, wh->i_addr2,
+ "%s", "recv probe req");
+ /*
+ * Some legacy 11b clients cannot hack a complete
+ * probe response frame. When the request includes
+ * only a bare-bones rate set, communicate this to
+ * the transmit side.
+ */
+ ieee80211_send_proberesp(vap, wh->i_addr2,
+ is11bclient(rates, xrates) ? IEEE80211_SEND_LEGACY_11B : 0);
break;
+ }
case IEEE80211_FC0_SUBTYPE_ACTION:
break;
case IEEE80211_FC0_SUBTYPE_AUTH:
@@ -399,11 +484,10 @@ ieee80211_add_meshid(uint8_t *frm, struc
KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a mbss vap"));
*frm++ = IEEE80211_ELEMID_MESHID;
- *frm++ = sizeof(struct ieee80211_meshid_ie) + vap->iv_meshidlen;
+ *frm++ = vap->iv_meshidlen;
memcpy(frm, vap->iv_meshid, vap->iv_meshidlen);
- frm += vap->iv_meshidlen;
-
- return frm;
+
+ return frm + vap->iv_meshidlen;
}
void
@@ -421,12 +505,20 @@ ieee80211_create_mbss(struct ieee80211va
/* XXX recovery? */
return;
}
+ IEEE80211_ADDR_COPY(ni->ni_bssid, vap->iv_myaddr);
ni->ni_meshidlen = vap->iv_meshidlen;
memcpy(ni->ni_meshid, vap->iv_meshid, ni->ni_meshidlen);
ni->ni_intval = ic->ic_bintval;
+ /*
+ * Fix the channel and related attributes.
+ */
+ /* clear DFS CAC state on previous channel */
+ if (ic->ic_bsschan != IEEE80211_CHAN_ANYC &&
+ ic->ic_bsschan->ic_freq != chan->ic_freq &&
+ IEEE80211_IS_CHAN_CACDONE(ic->ic_bsschan))
+ ieee80211_dfs_cac_clear(ic, ic->ic_bsschan);
ic->ic_bsschan = chan;
ieee80211_node_set_chan(ni, chan);
- ieee80211_setcurchan(ic, ni->ni_chan);
ic->ic_curmode = ieee80211_chan2mode(chan);
/*
* Do mode-specific setup.
@@ -454,6 +546,9 @@ ieee80211_create_mbss(struct ieee80211va
IEEE80211_MODE_11B);
}
}
+ ieee80211_ref_node(ni);
+ vap->iv_bss = ni;
+ ieee80211_setcurchan(ic, ni->ni_chan);
/*
* Set the erp state (mostly the slot time) to deal with
* the auto-select case; this should be redundant if the
More information about the svn-src-projects
mailing list