diff options
author | rpaulo <rpaulo@FreeBSD.org> | 2009-07-20 19:12:08 +0000 |
---|---|---|
committer | rpaulo <rpaulo@FreeBSD.org> | 2009-07-20 19:12:08 +0000 |
commit | 0dabd4da957e96805f21216cc44bc94439647949 (patch) | |
tree | a3c1502dbf378e42dd0c635145f69ddd644fcb2b /sys/net80211/ieee80211_output.c | |
parent | d32e9e9901044568408ca4ef06315cfca9176870 (diff) | |
download | FreeBSD-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.c | 49 |
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: |