Deleted Added
full compact
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 ---