ieee80211_mesh.c (232479) | ieee80211_mesh.c (232480) |
---|---|
1/*- 2 * Copyright (c) 2009 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Rui Paulo under sponsorship from the 6 * FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29#include <sys/cdefs.h> 30#ifdef __FreeBSD__ | 1/*- 2 * Copyright (c) 2009 The FreeBSD Foundation 3 * All rights reserved. 4 * 5 * This software was developed by Rui Paulo under sponsorship from the 6 * FreeBSD Foundation. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 14 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29#include <sys/cdefs.h> 30#ifdef __FreeBSD__ |
31__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_mesh.c 232479 2012-03-04 05:49:39Z adrian $"); | 31__FBSDID("$FreeBSD: head/sys/net80211/ieee80211_mesh.c 232480 2012-03-04 05:52:26Z adrian $"); |
32#endif 33 34/* 35 * IEEE 802.11s Mesh Point (MBSS) support. 36 * 37 * Based on March 2009, D3.0 802.11s draft spec. 38 */ 39#include "opt_inet.h" --- 995 unchanged lines hidden (view full) --- 1035{ 1036#define HAS_SEQ(type) ((type & 0x4) == 0) 1037 struct ieee80211vap *vap = ni->ni_vap; 1038 struct ieee80211com *ic = ni->ni_ic; 1039 struct ifnet *ifp = vap->iv_ifp; 1040 struct ieee80211_frame *wh; 1041 const struct ieee80211_meshcntl *mc; 1042 int hdrspace, meshdrlen, need_tap; | 32#endif 33 34/* 35 * IEEE 802.11s Mesh Point (MBSS) support. 36 * 37 * Based on March 2009, D3.0 802.11s draft spec. 38 */ 39#include "opt_inet.h" --- 995 unchanged lines hidden (view full) --- 1035{ 1036#define HAS_SEQ(type) ((type & 0x4) == 0) 1037 struct ieee80211vap *vap = ni->ni_vap; 1038 struct ieee80211com *ic = ni->ni_ic; 1039 struct ifnet *ifp = vap->iv_ifp; 1040 struct ieee80211_frame *wh; 1041 const struct ieee80211_meshcntl *mc; 1042 int hdrspace, meshdrlen, need_tap; |
1043 uint8_t dir, type, subtype, qos; | 1043 uint8_t dir, type, subtype; |
1044 uint32_t seq; | 1044 uint32_t seq; |
1045 uint8_t *addr; | 1045 uint8_t *addr, qos[2]; |
1046 ieee80211_seq rxseq; 1047 1048 KASSERT(ni != NULL, ("null node")); 1049 ni->ni_inact = ni->ni_inact_reload; 1050 1051 need_tap = 1; /* mbuf need to be tapped. */ 1052 type = -1; /* undefined */ 1053 --- 80 unchanged lines hidden (view full) --- 1134 } 1135 if (dir != IEEE80211_FC1_DIR_FROMDS && 1136 dir != IEEE80211_FC1_DIR_DSTODS) { 1137 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 1138 wh, "data", "incorrect dir 0x%x", dir); 1139 vap->iv_stats.is_rx_wrongdir++; 1140 goto err; 1141 } | 1046 ieee80211_seq rxseq; 1047 1048 KASSERT(ni != NULL, ("null node")); 1049 ni->ni_inact = ni->ni_inact_reload; 1050 1051 need_tap = 1; /* mbuf need to be tapped. */ 1052 type = -1; /* undefined */ 1053 --- 80 unchanged lines hidden (view full) --- 1134 } 1135 if (dir != IEEE80211_FC1_DIR_FROMDS && 1136 dir != IEEE80211_FC1_DIR_DSTODS) { 1137 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 1138 wh, "data", "incorrect dir 0x%x", dir); 1139 vap->iv_stats.is_rx_wrongdir++; 1140 goto err; 1141 } |
1142 /* pull up enough to get to the mesh control */ | 1142 1143 /* All Mesh data frames are QoS subtype */ 1144 if (!HAS_SEQ(type)) { 1145 IEEE80211_DISCARD(vap, IEEE80211_MSG_INPUT, 1146 wh, "data", "incorrect subtype 0x%x", subtype); 1147 vap->iv_stats.is_rx_badsubtype++; 1148 goto err; 1149 } 1150 1151 /* 1152 * Next up, any fragmentation. 1153 * XXX: we defrag before we even try to forward, 1154 * Mesh Control field is not present in sub-sequent 1155 * fragmented frames. This is in contrast to Draft 4.0. 1156 */ |
1143 hdrspace = ieee80211_hdrspace(ic, wh); | 1157 hdrspace = ieee80211_hdrspace(ic, wh); |
1158 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1159 m = ieee80211_defrag(ni, m, hdrspace); 1160 if (m == NULL) { 1161 /* Fragment dropped or frame not complete yet */ 1162 goto out; 1163 } 1164 } 1165 wh = mtod(m, struct ieee80211_frame *); /* NB: after defrag */ 1166 1167 /* 1168 * Now we have a complete Mesh Data frame. 1169 */ 1170 1171 /* 1172 * Only fromDStoDS data frames use 4 address qos frames 1173 * as specified in amendment. Otherwise addr4 is located 1174 * in the Mesh Control field and a 3 address qos frame 1175 * is used. 1176 */ 1177 if (IEEE80211_IS_DSTODS(wh)) 1178 *(uint16_t *)qos = *(uint16_t *) 1179 ((struct ieee80211_qosframe_addr4 *)wh)->i_qos; 1180 else 1181 *(uint16_t *)qos = *(uint16_t *) 1182 ((struct ieee80211_qosframe *)wh)->i_qos; 1183 1184 /* 1185 * NB: The mesh STA sets the Mesh Control Present 1186 * subfield to 1 in the Mesh Data frame containing 1187 * an unfragmented MSDU, an A-MSDU, or the first 1188 * fragment of an MSDU. 1189 * After defrag it should always be present. 1190 */ 1191 if (!(qos[1] & IEEE80211_QOS_MC)) { 1192 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH, 1193 ni->ni_macaddr, NULL, 1194 "%s", "Mesh control field not present"); 1195 vap->iv_stats.is_rx_elem_missing++; /* XXX: kinda */ 1196 goto err; 1197 } 1198 1199 /* pull up enough to get to the mesh control */ |
|
1144 if (m->m_len < hdrspace + sizeof(struct ieee80211_meshcntl) && 1145 (m = m_pullup(m, hdrspace + 1146 sizeof(struct ieee80211_meshcntl))) == NULL) { 1147 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 1148 ni->ni_macaddr, NULL, 1149 "data too short: expecting %u", hdrspace); 1150 vap->iv_stats.is_rx_tooshort++; 1151 goto out; /* XXX */ --- 31 unchanged lines hidden (view full) --- 1183 if (dir == IEEE80211_FC1_DIR_FROMDS || 1184 !mesh_isucastforme(vap, wh, mc)) { 1185 mesh_forward(vap, m, mc); 1186 if (dir == IEEE80211_FC1_DIR_DSTODS) 1187 goto out; 1188 /* NB: fall thru to deliver mcast frames locally */ 1189 } 1190 | 1200 if (m->m_len < hdrspace + sizeof(struct ieee80211_meshcntl) && 1201 (m = m_pullup(m, hdrspace + 1202 sizeof(struct ieee80211_meshcntl))) == NULL) { 1203 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_ANY, 1204 ni->ni_macaddr, NULL, 1205 "data too short: expecting %u", hdrspace); 1206 vap->iv_stats.is_rx_tooshort++; 1207 goto out; /* XXX */ --- 31 unchanged lines hidden (view full) --- 1239 if (dir == IEEE80211_FC1_DIR_FROMDS || 1240 !mesh_isucastforme(vap, wh, mc)) { 1241 mesh_forward(vap, m, mc); 1242 if (dir == IEEE80211_FC1_DIR_DSTODS) 1243 goto out; 1244 /* NB: fall thru to deliver mcast frames locally */ 1245 } 1246 |
1191 /* 1192 * Save QoS bits for use below--before we strip the header. 1193 */ 1194 if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { 1195 qos = (dir == IEEE80211_FC1_DIR_DSTODS) ? 1196 ((struct ieee80211_qosframe_addr4 *)wh)->i_qos[0] : 1197 ((struct ieee80211_qosframe *)wh)->i_qos[0]; 1198 } else 1199 qos = 0; 1200 /* 1201 * Next up, any fragmentation. 1202 */ 1203 if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { 1204 m = ieee80211_defrag(ni, m, hdrspace); 1205 if (m == NULL) { 1206 /* Fragment dropped or frame not complete yet */ 1207 goto out; 1208 } 1209 } 1210 wh = NULL; /* no longer valid, catch any uses */ 1211 | |
1212 if (ieee80211_radiotap_active_vap(vap)) 1213 ieee80211_radiotap_rx(vap, m); 1214 need_tap = 0; 1215 1216 /* 1217 * Finally, strip the 802.11 header. 1218 */ 1219 m = mesh_decap(vap, m, hdrspace, meshdrlen); --- 4 unchanged lines hidden (view full) --- 1224 subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) 1225 goto out; 1226 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 1227 ni->ni_macaddr, "data", "%s", "decap error"); 1228 vap->iv_stats.is_rx_decap++; 1229 IEEE80211_NODE_STAT(ni, rx_decap); 1230 goto err; 1231 } | 1247 if (ieee80211_radiotap_active_vap(vap)) 1248 ieee80211_radiotap_rx(vap, m); 1249 need_tap = 0; 1250 1251 /* 1252 * Finally, strip the 802.11 header. 1253 */ 1254 m = mesh_decap(vap, m, hdrspace, meshdrlen); --- 4 unchanged lines hidden (view full) --- 1259 subtype == IEEE80211_FC0_SUBTYPE_QOS_NULL) 1260 goto out; 1261 IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_INPUT, 1262 ni->ni_macaddr, "data", "%s", "decap error"); 1263 vap->iv_stats.is_rx_decap++; 1264 IEEE80211_NODE_STAT(ni, rx_decap); 1265 goto err; 1266 } |
1232 if (qos & IEEE80211_QOS_AMSDU) { | 1267 if (qos[0] & IEEE80211_QOS_AMSDU) { |
1233 m = ieee80211_decap_amsdu(ni, m); 1234 if (m == NULL) 1235 return IEEE80211_FC0_TYPE_DATA; 1236 } 1237 ieee80211_deliver_data(vap, ni, m); 1238 return type; 1239 case IEEE80211_FC0_TYPE_MGT: 1240 vap->iv_stats.is_rx_mgmt++; --- 1482 unchanged lines hidden --- | 1268 m = ieee80211_decap_amsdu(ni, m); 1269 if (m == NULL) 1270 return IEEE80211_FC0_TYPE_DATA; 1271 } 1272 ieee80211_deliver_data(vap, ni, m); 1273 return type; 1274 case IEEE80211_FC0_TYPE_MGT: 1275 vap->iv_stats.is_rx_mgmt++; --- 1482 unchanged lines hidden --- |