svn commit: r191982 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Sun May 10 21:01:34 UTC 2009
Author: rpaulo
Date: Sun May 10 21:01:33 2009
New Revision: 191982
URL: http://svn.freebsd.org/changeset/base/191982
Log:
Initial take on handling data frames.
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_mesh.c
projects/mesh11s/sys/net80211/ieee80211_output.c
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c Sun May 10 20:41:52 2009 (r191981)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c Sun May 10 21:01:33 2009 (r191982)
@@ -224,8 +224,8 @@ mesh_input(struct ieee80211_node *ni, st
struct ieee80211com *ic = ni->ni_ic;
struct ifnet *ifp = vap->iv_ifp;
struct ieee80211_frame *wh;
- int need_tap;
- uint8_t dir, type, subtype;
+ int hdrspace, need_tap;
+ uint8_t dir, type, subtype, qos;
KASSERT(ni != NULL, ("null node"));
ni->ni_inact = ni->ni_inact_reload;
@@ -264,12 +264,71 @@ mesh_input(struct ieee80211_node *ni, st
switch (type) {
case IEEE80211_FC0_TYPE_DATA:
+ hdrspace = ieee80211_hdrspace(ic, wh);
+ if (m->m_len < hdrspace &&
+ (m = m_pullup(m, hdrspace)) == NULL) {
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY,
+ ni->ni_macaddr, NULL,
+ "data too short: expecting %u", hdrspace);
+ vap->iv_stats.is_rx_tooshort++;
+ goto out; /* XXX */
+ }
+ if (dir != IEEE80211_FC1_DIR_DSTODS) {
+ IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
+ wh, "data", "incorrect dir 0x%x", dir);
+ vap->iv_stats.is_rx_wrongdir++;
+ goto err;
+ }
+ /*
+ * Save QoS bits for use below--before we strip the header.
+ */
+ if (subtype == IEEE80211_FC0_SUBTYPE_QOS) {
+ qos = (dir == IEEE80211_FC1_DIR_DSTODS) ?
+ ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] :
+ ((struct ieee80211_qosframe *)wh)->i_qos[0];
+ } else
+ qos = 0;
+ /*
+ * Next up, any fragmentation.
+ */
+#if 0
+ if (!IEEE80211_IS_MULTICAST(wh->i_addr3)) {
+ m = ieee80211_defrag(ni, m, hdrspace);
+ if (m == NULL) {
+ /* Fragment dropped or frame not complete yet */
+ goto out;
+ }
+ }
+#endif
+ wh = NULL; /* no longer valid, catch any uses */
+ if (bpf_peers_present(vap->iv_rawbpf))
+ bpf_mtap(vap->iv_rawbpf, m);
+ need_tap = 0;
+ /*
+ * Finally, strip the 802.11 header.
+ */
+ m = ieee80211_decap(vap, m, hdrspace);
+ if (m == NULL) {
+ /* XXX mask bit to check for both */
+ /* don't count Null data frames as errors */
+ if (subtype == IEEE80211_FC0_SUBTYPE_NODATA ||
+ subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL)
+ goto out;
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
+ ni->ni_macaddr, "data", "%s", "decap error");
+ vap->iv_stats.is_rx_decap++;
+ IEEE80211_NODE_STAT(ni, rx_decap);
+ goto err;
+ }
+ /* XXX SuperG/HT */
+ ieee80211_deliver_data(vap, ni, m);
+ return type;
case IEEE80211_FC0_TYPE_MGT:
vap->iv_stats.is_rx_mgmt++;
IEEE80211_NODE_STAT(ni, rx_mgmt);
- if (dir != IEEE80211_FC1_DIR_DSTODS) {
+ if (dir != IEEE80211_FC1_DIR_NODS) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
- wh, "data", "incorrect dir 0x%x", dir);
+ wh, "mgt", "incorrect dir 0x%x", dir);
vap->iv_stats.is_rx_wrongdir++;
goto err;
}
@@ -298,9 +357,7 @@ mesh_input(struct ieee80211_node *ni, st
if (bpf_peers_present(vap->iv_rawbpf))
bpf_mtap(vap->iv_rawbpf, m);
vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp);
- m_freem(m);
- return IEEE80211_FC0_TYPE_MGT;
-
+ goto out;
case IEEE80211_FC0_TYPE_CTL:
vap->iv_stats.is_rx_ctl++;
IEEE80211_NODE_STAT(ni, rx_ctrl);
Modified: projects/mesh11s/sys/net80211/ieee80211_output.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_output.c Sun May 10 20:41:52 2009 (r191981)
+++ projects/mesh11s/sys/net80211/ieee80211_output.c Sun May 10 21:01:33 2009 (r191982)
@@ -202,6 +202,8 @@ ieee80211_start(struct ifnet *ifp)
*/
/* XXX only if dwds in use? */
ieee80211_dwds_mcast(vap, m);
+ } else if (vap->iv_opmode == IEEE80211_M_MBSS) {
+
}
}
ni = ieee80211_find_txnode(vap, eh->ether_dhost);
@@ -499,6 +501,7 @@ ieee80211_send_setup(
IEEE80211_ADDR_COPY(wh->i_addr3, sa);
break;
case IEEE80211_M_WDS:
+ case IEEE80211_M_MBSS: /* XXX confirm */
wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS;
IEEE80211_ADDR_COPY(wh->i_addr1, da);
IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
@@ -507,9 +510,6 @@ ieee80211_send_setup(
break;
case IEEE80211_M_MONITOR: /* NB: to quiet compiler */
break;
- case IEEE80211_M_MBSS:
- /* XXXRP TBD */
- break;
}
} else {
wh->i_fc[1] = IEEE80211_FC1_DIR_NODS;
More information about the svn-src-projects
mailing list