summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_output.c
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2009-07-20 19:12:08 +0000
committerrpaulo <rpaulo@FreeBSD.org>2009-07-20 19:12:08 +0000
commit0dabd4da957e96805f21216cc44bc94439647949 (patch)
treea3c1502dbf378e42dd0c635145f69ddd644fcb2b /sys/net80211/ieee80211_output.c
parentd32e9e9901044568408ca4ef06315cfca9176870 (diff)
downloadFreeBSD-src-0dabd4da957e96805f21216cc44bc94439647949.zip
FreeBSD-src-0dabd4da957e96805f21216cc44bc94439647949.tar.gz
More mesh bits, namely:
* bridge support (sam) * handling of errors (sam) * deletion of inactive routing entries * more debug msgs (sam) * fixed some inconsistencies with the spec. * decap is now specific to mesh (sam) * print mesh seq. no. on ifconfig list mesh * small perf. improvements Reviewed by: sam Approved by: re (kib)
Diffstat (limited to 'sys/net80211/ieee80211_output.c')
-rw-r--r--sys/net80211/ieee80211_output.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c
index 96b2d45..061a63d 100644
--- a/sys/net80211/ieee80211_output.c
+++ b/sys/net80211/ieee80211_output.c
@@ -242,19 +242,34 @@ ieee80211_start(struct ifnet *ifp)
}
#ifdef IEEE80211_SUPPORT_MESH
} else {
+ if (!IEEE80211_ADDR_EQ(eh->ether_shost, vap->iv_myaddr)) {
+ /*
+ * Proxy station only if configured.
+ */
+ if (!ieee80211_mesh_isproxyena(vap)) {
+ IEEE80211_DISCARD_MAC(vap,
+ IEEE80211_MSG_OUTPUT |
+ IEEE80211_MSG_MESH,
+ eh->ether_dhost, NULL,
+ "%s", "proxy not enabled");
+ vap->iv_stats.is_mesh_notproxy++;
+ ifp->if_oerrors++;
+ m_freem(m);
+ continue;
+ }
+ ieee80211_mesh_proxy_check(vap, eh->ether_shost);
+ }
ni = ieee80211_mesh_discover(vap, eh->ether_dhost, m);
if (ni == NULL) {
/*
- * NB: ieee80211_mesh_discover function
- * holds/disposes frame
- * (e.g. queueing on path discovery).
+ * NB: ieee80211_mesh_discover holds/disposes
+ * frame (e.g. queueing on path discovery).
*/
ifp->if_oerrors++;
continue;
}
}
#endif
-
if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
(m->m_flags & M_PWR_SAV) == 0) {
/*
@@ -987,7 +1002,7 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni,
struct ieee80211com *ic = ni->ni_ic;
#ifdef IEEE80211_SUPPORT_MESH
struct ieee80211_mesh_state *ms = vap->iv_mesh;
- struct ieee80211_meshcntl_ae11 *mc;
+ struct ieee80211_meshcntl_ae10 *mc;
#endif
struct ether_header eh;
struct ieee80211_frame *wh;
@@ -1066,21 +1081,21 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni,
* w/ 4-address format and address extension mode 10
*/
is4addr = 0; /* NB: don't use, disable */
+ if (!IEEE80211_IS_MULTICAST(eh.ether_dhost))
+ hdrsize += IEEE80211_ADDR_LEN; /* unicast are 4-addr */
meshhdrsize = sizeof(struct ieee80211_meshcntl);
/* XXX defines for AE modes */
- /* XXX not right, need to check if from non-mesh-sta */
if (IEEE80211_ADDR_EQ(eh.ether_shost, vap->iv_myaddr)) {
- if (!IEEE80211_IS_MULTICAST(eh.ether_dhost)) {
- hdrsize += IEEE80211_ADDR_LEN;
+ if (!IEEE80211_IS_MULTICAST(eh.ether_dhost))
meshae = 0;
- } else
+ else
meshae = 4; /* NB: pseudo */
} else if (IEEE80211_IS_MULTICAST(eh.ether_dhost)) {
meshae = 1;
- meshhdrsize += 2*IEEE80211_ADDR_LEN;
+ meshhdrsize += 1*IEEE80211_ADDR_LEN;
} else {
meshae = 2;
- meshhdrsize += 3*IEEE80211_ADDR_LEN;
+ meshhdrsize += 2*IEEE80211_ADDR_LEN;
}
} else {
#endif
@@ -1179,7 +1194,7 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni,
#ifdef IEEE80211_SUPPORT_MESH
case IEEE80211_M_MBSS:
/* NB: offset by hdrspace to deal with DATAPAD */
- mc = (struct ieee80211_meshcntl_ae11 *)
+ mc = (struct ieee80211_meshcntl_ae10 *)
(mtod(m, uint8_t *) + hdrspace);
switch (meshae) {
case 0: /* ucast, no proxy */
@@ -1203,8 +1218,7 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni,
wh->i_fc[1] = IEEE80211_FC1_DIR_FROMDS;
IEEE80211_ADDR_COPY(wh->i_addr1, eh.ether_dhost);
IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
- /* XXX not right, need MeshSA */
- IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_shost);
+ IEEE80211_ADDR_COPY(wh->i_addr3, vap->iv_myaddr);
mc->mc_flags = 1;
IEEE80211_ADDR_COPY(mc->mc_addr4, eh.ether_shost);
qos = ((struct ieee80211_qosframe *) wh)->i_qos;
@@ -1213,12 +1227,13 @@ ieee80211_encap(struct ieee80211vap *vap, struct ieee80211_node *ni,
wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS;
IEEE80211_ADDR_COPY(wh->i_addr1, ni->ni_macaddr);
IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
- /* XXX not right, need MeshDA+MeshSA */
+ /* XXX not right, need MeshDA */
IEEE80211_ADDR_COPY(wh->i_addr3, eh.ether_dhost);
- IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, eh.ether_shost);
+ /* XXX assume are MeshSA */
+ IEEE80211_ADDR_COPY(WH4(wh)->i_addr4, vap->iv_myaddr);
mc->mc_flags = 2;
+ IEEE80211_ADDR_COPY(mc->mc_addr4, eh.ether_dhost);
IEEE80211_ADDR_COPY(mc->mc_addr5, eh.ether_shost);
- IEEE80211_ADDR_COPY(mc->mc_addr6, eh.ether_shost);
qos = ((struct ieee80211_qosframe_addr4 *) wh)->i_qos;
break;
default:
OpenPOWER on IntegriCloud