svn commit: r195260 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Wed Jul 1 22:06:13 UTC 2009
Author: rpaulo
Date: Wed Jul 1 22:06:12 2009
New Revision: 195260
URL: http://svn.freebsd.org/changeset/base/195260
Log:
* add more stats
* check for 802.11 seq no.
* fix forwarding direction check (by sam)
* move RSSI/noise setup below
* fix a case of peer localid == 0
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_ioctl.h
projects/mesh11s/sys/net80211/ieee80211_mesh.c
Modified: projects/mesh11s/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ioctl.h Wed Jul 1 20:43:46 2009 (r195259)
+++ projects/mesh11s/sys/net80211/ieee80211_ioctl.h Wed Jul 1 22:06:12 2009 (r195260)
@@ -224,6 +224,8 @@ struct ieee80211_stats {
uint32_t is_ampdu_rexmt; /* A-MPDU frames rexmt ok */
uint32_t is_ampdu_rexmt_fail; /* A-MPDU frames rexmt fail */
+ uint32_t is_mesh_wrongmesh; /* dropped 'cuz not mesh sta*/
+ uint32_t is_mesh_nolink; /* dropped 'cuz link not estab*/
uint32_t is_mesh_fwd_ttl; /* mesh not fwd'd 'cuz ttl 0 */
uint32_t is_mesh_fwd_nobuf; /* mesh not fwd'd 'cuz no mbuf*/
uint32_t is_mesh_fwd_tooshort; /* mesh not fwd'd 'cuz no hdr */
@@ -232,7 +234,7 @@ struct ieee80211_stats {
uint32_t is_hwmp_wrongseq; /* wrong hwmp seq no. */
- uint32_t is_spare[10];
+ uint32_t is_spare[8];
};
/*
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.c Wed Jul 1 20:43:46 2009 (r195259)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.c Wed Jul 1 22:06:12 2009 (r195260)
@@ -421,8 +421,10 @@ mesh_forward(struct ieee80211vap *vap, s
}
static int
-mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int noise)
+mesh_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf)
{
+#define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0)
+#define HAS_SEQ(type) ((type & 0x4) == 0)
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211com *ic = ni->ni_ic;
struct ifnet *ifp = vap->iv_ifp;
@@ -432,6 +434,7 @@ mesh_input(struct ieee80211_node *ni, st
uint8_t dir, type, subtype, qos;
uint32_t seq;
uint8_t *addr;
+ ieee80211_seq rxseq;
KASSERT(ni != NULL, ("null node"));
ni->ni_inact = ni->ni_inact_reload;
@@ -465,8 +468,36 @@ mesh_input(struct ieee80211_node *ni, st
type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK;
subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK;
if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) {
+ IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
+ ni->ni_noise = nf;
+ if (HAS_SEQ(type)) {
+ uint8_t tid = ieee80211_gettid(wh);
+
+ if (IEEE80211_QOS_HAS_SEQ(wh) &&
+ TID_TO_WME_AC(tid) >= WME_AC_VI)
+ ic->ic_wme.wme_hipri_traffic++;
+ rxseq = le16toh(*(uint16_t *)wh->i_seq);
+ if ((ni->ni_flags & IEEE80211_NODE_HT) == 0 &&
+ (wh->i_fc[1] & IEEE80211_FC1_RETRY) &&
+ SEQ_LEQ(rxseq, ni->ni_rxseqs[tid])) {
+ /* duplicate, discard */
+ IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT,
+ wh->i_addr1, "duplicate",
+ "seqno <%u,%u> fragno <%u,%u> tid %u",
+ rxseq >> IEEE80211_SEQ_SEQ_SHIFT,
+ ni->ni_rxseqs[tid] >>
+ IEEE80211_SEQ_SEQ_SHIFT,
+ rxseq & IEEE80211_SEQ_FRAG_MASK,
+ ni->ni_rxseqs[tid] &
+ IEEE80211_SEQ_FRAG_MASK,
+ tid);
+ vap->iv_stats.is_rx_dup++;
+ IEEE80211_NODE_STAT(ni, rx_dup);
+ goto out;
+ }
+ ni->ni_rxseqs[tid] = rxseq;
+ }
}
-
#ifdef IEEE80211_DEBUG
/*
* It's easier, but too expensive, to simulate different mesh
@@ -486,15 +517,12 @@ mesh_input(struct ieee80211_node *ni, st
case IEEE80211_FC0_TYPE_DATA:
if (ni == vap->iv_bss)
goto out;
-#if 0
- IEEE80211_NOTE(vap, IEEE80211_MSG_MESH, ni,
- "received data frame, dir 0x%x", dir);
-#endif
if (ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
ni->ni_macaddr, NULL,
"peer link not yet established (%d)",
ni->ni_mlstate);
+ vap->iv_stats.is_mesh_nolink++;
goto out;
}
if (dir != IEEE80211_FC1_DIR_FROMDS &&
@@ -547,24 +575,19 @@ mesh_input(struct ieee80211_node *ni, st
vap->iv_stats.is_rx_dup++;
goto out;
}
+
/*
- * Forward and deliver multicast packets
- * XXX tap fwd'd packets not for us?
- */
- if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
- mesh_forward(vap, m, mc);
- goto deliver;
- }
- /*
- * Forward packets if their final destination is not us.
+ * Potentially forward packet. See table s36 (p140)
+ * for the rules. XXX tap fwd'd packets not for us?
*/
- if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr3) &&
- IEEE80211_ADDR_EQ(vap->iv_myaddr, wh->i_addr1)) {
+ if (dir == IEEE80211_FC1_DIR_FROMDS ||
+ !IEEE80211_ADDR_EQ(wh->i_addr3, vap->iv_myaddr)) {
mesh_forward(vap, m, mc);
- /* NB: don't deliver */
- goto out;
+ if (dir == IEEE80211_FC1_DIR_DSTODS)
+ goto out;
+ /* NB: fall thru to deliver mcast frames locally */
}
-deliver:
+
/*
* Save QoS bits for use below--before we strip the header.
*/
@@ -650,7 +673,7 @@ deliver:
vap->iv_stats.is_rx_mgtdiscard++; /* XXX */
goto out;
}
- vap->iv_recv_mgmt(ni, m, subtype, rssi, noise);
+ vap->iv_recv_mgmt(ni, m, subtype, rssi, nf);
goto out;
case IEEE80211_FC0_TYPE_CTL:
vap->iv_stats.is_rx_ctl++;
@@ -692,7 +715,7 @@ is11bclient(const uint8_t *rates, const
static void
mesh_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, int subtype,
- int rssi, int noise)
+ int rssi, int nf)
{
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_mesh_state *ms = vap->iv_mesh;
@@ -739,7 +762,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN;
}
ieee80211_add_scan(vap, &scan, wh,
- subtype, rssi, noise);
+ subtype, rssi, nf);
return;
}
@@ -754,6 +777,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
scan.meshid == NULL || scan.meshconf == NULL) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, "beacon", "%s", "not a mesh sta");
+ vap->iv_stats.is_mesh_wrongmesh++;
return;
}
/*
@@ -764,6 +788,7 @@ mesh_recv_mgmt(struct ieee80211_node *ni
(struct ieee80211_meshconf_ie *)scan.meshconf)) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT,
wh, "beacon", "%s", "not for our mesh");
+ vap->iv_stats.is_mesh_wrongmesh++;
return;
}
/*
@@ -809,8 +834,6 @@ mesh_recv_mgmt(struct ieee80211_node *ni
ni->ni_mlrcnt = 0;
mesh_peer_timeout_setup(ni);
}
- IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi);
- ni->ni_noise = noise;
break;
}
case IEEE80211_FC0_SUBTYPE_PROBE_REQ:
@@ -939,6 +962,7 @@ mesh_recv_action(struct ieee80211_node *
if (ni == vap->iv_bss) {
IEEE80211_DISCARD(vap, IEEE80211_MSG_MESH,
wh, NULL, "%s", "unknown node");
+ vap->iv_stats.is_tx_nonode++;
return;
}
@@ -1184,8 +1208,8 @@ mesh_recv_action(struct ieee80211_node *
IEEE80211_NODE_MESH_CONFIRMRCV);
break;
case IEEE80211_NODE_MESH_HOLDING:
- sargs.arg[0] = ni->ni_mllid;
- sargs.arg[1] = ni->ni_mlpid;
+ sargs.arg[0] = ni->ni_mlpid;
+ sargs.arg[1] = meshpeer->peer_llinkid;
sargs.arg[2] =
IEEE80211_REASON_MESH_MAX_RETRIES;
ieee80211_send_action(ni,
More information about the svn-src-projects
mailing list