aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/tx.c64
-rw-r--r--net/mac80211/util.c37
2 files changed, 85 insertions, 16 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 698c8233e6b3..c12f361d7185 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -624,7 +624,14 @@ ieee80211_tx_h_sequence(struct ieee80211_tx_data *tx)
624 u8 *qc; 624 u8 *qc;
625 int tid; 625 int tid;
626 626
627 /* only for injected frames */ 627 /*
628 * Packet injection may want to control the sequence
629 * number, if we have no matching interface then we
630 * neither assign one ourselves nor ask the driver to.
631 */
632 if (unlikely(!info->control.vif))
633 return TX_CONTINUE;
634
628 if (unlikely(ieee80211_is_ctl(hdr->frame_control))) 635 if (unlikely(ieee80211_is_ctl(hdr->frame_control)))
629 return TX_CONTINUE; 636 return TX_CONTINUE;
630 637
@@ -849,7 +856,6 @@ __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
849 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 856 sband = tx->local->hw.wiphy->bands[tx->channel->band];
850 857
851 skb->do_not_encrypt = 1; 858 skb->do_not_encrypt = 1;
852 info->flags |= IEEE80211_TX_CTL_INJECTED;
853 tx->flags &= ~IEEE80211_TX_FRAGMENTED; 859 tx->flags &= ~IEEE80211_TX_FRAGMENTED;
854 860
855 /* 861 /*
@@ -981,7 +987,7 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
981 987
982 /* process and remove the injection radiotap header */ 988 /* process and remove the injection radiotap header */
983 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 989 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
984 if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { 990 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
985 if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP) 991 if (__ieee80211_parse_tx_radiotap(tx, skb) == TX_DROP)
986 return TX_DROP; 992 return TX_DROP;
987 993
@@ -1300,6 +1306,11 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1300 struct ieee80211_sub_if_data *osdata; 1306 struct ieee80211_sub_if_data *osdata;
1301 int headroom; 1307 int headroom;
1302 bool may_encrypt; 1308 bool may_encrypt;
1309 enum {
1310 NOT_MONITOR,
1311 FOUND_SDATA,
1312 UNKNOWN_ADDRESS,
1313 } monitor_iface = NOT_MONITOR;
1303 int ret; 1314 int ret;
1304 1315
1305 if (skb->iif) 1316 if (skb->iif)
@@ -1335,6 +1346,50 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1335 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh, 1346 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
1336 fwded_frames); 1347 fwded_frames);
1337 } 1348 }
1349 } else if (unlikely(osdata->vif.type == NL80211_IFTYPE_MONITOR)) {
1350 struct ieee80211_sub_if_data *sdata;
1351 struct ieee80211_local *local = osdata->local;
1352 struct ieee80211_hdr *hdr;
1353 int hdrlen;
1354 u16 len_rthdr;
1355
1356 info->flags |= IEEE80211_TX_CTL_INJECTED;
1357 monitor_iface = UNKNOWN_ADDRESS;
1358
1359 len_rthdr = ieee80211_get_radiotap_len(skb->data);
1360 hdr = (struct ieee80211_hdr *)skb->data + len_rthdr;
1361 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1362
1363 /* check the header is complete in the frame */
1364 if (likely(skb->len >= len_rthdr + hdrlen)) {
1365 /*
1366 * We process outgoing injected frames that have a
1367 * local address we handle as though they are our
1368 * own frames.
1369 * This code here isn't entirely correct, the local
1370 * MAC address is not necessarily enough to find
1371 * the interface to use; for that proper VLAN/WDS
1372 * support we will need a different mechanism.
1373 */
1374
1375 rcu_read_lock();
1376 list_for_each_entry_rcu(sdata, &local->interfaces,
1377 list) {
1378 if (!netif_running(sdata->dev))
1379 continue;
1380 if (compare_ether_addr(sdata->dev->dev_addr,
1381 hdr->addr2)) {
1382 dev_hold(sdata->dev);
1383 dev_put(odev);
1384 osdata = sdata;
1385 odev = osdata->dev;
1386 skb->iif = sdata->dev->ifindex;
1387 monitor_iface = FOUND_SDATA;
1388 break;
1389 }
1390 }
1391 rcu_read_unlock();
1392 }
1338 } 1393 }
1339 1394
1340 may_encrypt = !skb->do_not_encrypt; 1395 may_encrypt = !skb->do_not_encrypt;
@@ -1355,7 +1410,8 @@ int ieee80211_master_start_xmit(struct sk_buff *skb,
1355 osdata = container_of(osdata->bss, 1410 osdata = container_of(osdata->bss,
1356 struct ieee80211_sub_if_data, 1411 struct ieee80211_sub_if_data,
1357 u.ap); 1412 u.ap);
1358 info->control.vif = &osdata->vif; 1413 if (likely(monitor_iface != UNKNOWN_ADDRESS))
1414 info->control.vif = &osdata->vif;
1359 ret = ieee80211_tx(odev, skb); 1415 ret = ieee80211_tx(odev, skb);
1360 dev_put(odev); 1416 dev_put(odev);
1361 1417
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 6eb222369bcb..f32561ec224c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -231,16 +231,21 @@ __le16 ieee80211_generic_frame_duration(struct ieee80211_hw *hw,
231 struct ieee80211_rate *rate) 231 struct ieee80211_rate *rate)
232{ 232{
233 struct ieee80211_local *local = hw_to_local(hw); 233 struct ieee80211_local *local = hw_to_local(hw);
234 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 234 struct ieee80211_sub_if_data *sdata;
235 u16 dur; 235 u16 dur;
236 int erp; 236 int erp;
237 bool short_preamble = false;
237 238
238 erp = 0; 239 erp = 0;
239 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 240 if (vif) {
240 erp = rate->flags & IEEE80211_RATE_ERP_G; 241 sdata = vif_to_sdata(vif);
242 short_preamble = sdata->bss_conf.use_short_preamble;
243 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
244 erp = rate->flags & IEEE80211_RATE_ERP_G;
245 }
241 246
242 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp, 247 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, erp,
243 sdata->bss_conf.use_short_preamble); 248 short_preamble);
244 249
245 return cpu_to_le16(dur); 250 return cpu_to_le16(dur);
246} 251}
@@ -252,7 +257,7 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
252{ 257{
253 struct ieee80211_local *local = hw_to_local(hw); 258 struct ieee80211_local *local = hw_to_local(hw);
254 struct ieee80211_rate *rate; 259 struct ieee80211_rate *rate;
255 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 260 struct ieee80211_sub_if_data *sdata;
256 bool short_preamble; 261 bool short_preamble;
257 int erp; 262 int erp;
258 u16 dur; 263 u16 dur;
@@ -260,13 +265,17 @@ __le16 ieee80211_rts_duration(struct ieee80211_hw *hw,
260 265
261 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 266 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
262 267
263 short_preamble = sdata->bss_conf.use_short_preamble; 268 short_preamble = false;
264 269
265 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 270 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
266 271
267 erp = 0; 272 erp = 0;
268 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 273 if (vif) {
269 erp = rate->flags & IEEE80211_RATE_ERP_G; 274 sdata = vif_to_sdata(vif);
275 short_preamble = sdata->bss_conf.use_short_preamble;
276 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
277 erp = rate->flags & IEEE80211_RATE_ERP_G;
278 }
270 279
271 /* CTS duration */ 280 /* CTS duration */
272 dur = ieee80211_frame_duration(local, 10, rate->bitrate, 281 dur = ieee80211_frame_duration(local, 10, rate->bitrate,
@@ -289,7 +298,7 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
289{ 298{
290 struct ieee80211_local *local = hw_to_local(hw); 299 struct ieee80211_local *local = hw_to_local(hw);
291 struct ieee80211_rate *rate; 300 struct ieee80211_rate *rate;
292 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 301 struct ieee80211_sub_if_data *sdata;
293 bool short_preamble; 302 bool short_preamble;
294 int erp; 303 int erp;
295 u16 dur; 304 u16 dur;
@@ -297,12 +306,16 @@ __le16 ieee80211_ctstoself_duration(struct ieee80211_hw *hw,
297 306
298 sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; 307 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
299 308
300 short_preamble = sdata->bss_conf.use_short_preamble; 309 short_preamble = false;
301 310
302 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx]; 311 rate = &sband->bitrates[frame_txctl->control.rts_cts_rate_idx];
303 erp = 0; 312 erp = 0;
304 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE) 313 if (vif) {
305 erp = rate->flags & IEEE80211_RATE_ERP_G; 314 sdata = vif_to_sdata(vif);
315 short_preamble = sdata->bss_conf.use_short_preamble;
316 if (sdata->flags & IEEE80211_SDATA_OPERATING_GMODE)
317 erp = rate->flags & IEEE80211_RATE_ERP_G;
318 }
306 319
307 /* Data frame duration */ 320 /* Data frame duration */
308 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate, 321 dur = ieee80211_frame_duration(local, frame_len, rate->bitrate,