Date: Mon, 27 Apr 2009 18:15:41 +0000 (UTC) From: Rui Paulo <rpaulo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r191574 - projects/mesh11s/sys/net80211 Message-ID: <200904271815.n3RIFfVK022268@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200904271815.n3RIFfVK022268>