Commit 7be5086d4cb7cceb71d724a9524d5e927785d04f

Authored by Johannes Berg
Committed by John W. Linville
1 parent 271733cf84

mac80211: add probe request filter flag

Using the frame registration notification, we
can see when probe requests are requested and
notify the low-level driver via filtering. The
flag is also set in AP and IBSS modes.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

Showing 5 changed files with 38 additions and 5 deletions Side-by-side Diff

include/net/mac80211.h
... ... @@ -1478,12 +1478,14 @@
1478 1478 * honour this flag if possible.
1479 1479 *
1480 1480 * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
1481   - * is not set then only those addressed to this station.
  1481 + * is not set then only those addressed to this station.
1482 1482 *
1483 1483 * @FIF_OTHER_BSS: pass frames destined to other BSSes
1484 1484 *
1485   - * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
1486   - * those addressed to this station.
  1485 + * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
  1486 + * those addressed to this station.
  1487 + *
  1488 + * @FIF_PROBE_REQ: pass probe request frames
1487 1489 */
1488 1490 enum ieee80211_filter_flags {
1489 1491 FIF_PROMISC_IN_BSS = 1<<0,
... ... @@ -1494,6 +1496,7 @@
1494 1496 FIF_CONTROL = 1<<5,
1495 1497 FIF_OTHER_BSS = 1<<6,
1496 1498 FIF_PSPOLL = 1<<7,
  1499 + FIF_PROBE_REQ = 1<<8,
1497 1500 };
1498 1501  
1499 1502 /**
... ... @@ -1604,6 +1604,23 @@
1604 1604 return 0;
1605 1605 }
1606 1606  
  1607 +static void ieee80211_mgmt_frame_register(struct wiphy *wiphy,
  1608 + struct net_device *dev,
  1609 + u16 frame_type, bool reg)
  1610 +{
  1611 + struct ieee80211_local *local = wiphy_priv(wiphy);
  1612 +
  1613 + if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ))
  1614 + return;
  1615 +
  1616 + if (reg)
  1617 + local->probe_req_reg++;
  1618 + else
  1619 + local->probe_req_reg--;
  1620 +
  1621 + ieee80211_queue_work(&local->hw, &local->reconfig_filter);
  1622 +}
  1623 +
1607 1624 struct cfg80211_ops mac80211_config_ops = {
1608 1625 .add_virtual_intf = ieee80211_add_iface,
1609 1626 .del_virtual_intf = ieee80211_del_iface,
... ... @@ -1655,5 +1672,6 @@
1655 1672 .cancel_remain_on_channel = ieee80211_cancel_remain_on_channel,
1656 1673 .mgmt_tx = ieee80211_mgmt_tx,
1657 1674 .set_cqm_rssi_config = ieee80211_set_cqm_rssi_config,
  1675 + .mgmt_frame_register = ieee80211_mgmt_frame_register,
1658 1676 };
net/mac80211/ieee80211_i.h
... ... @@ -707,7 +707,9 @@
707 707 int open_count;
708 708 int monitors, cooked_mntrs;
709 709 /* number of interfaces with corresponding FIF_ flags */
710   - int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
  710 + int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
  711 + fif_probe_req;
  712 + int probe_req_reg;
711 713 unsigned int filter_flags; /* FIF_* */
712 714  
713 715 bool wiphy_ciphers_allocated;
net/mac80211/iface.c
... ... @@ -280,8 +280,11 @@
280 280 ieee80211_start_mesh(sdata);
281 281 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
282 282 local->fif_pspoll++;
  283 + local->fif_probe_req++;
283 284  
284 285 ieee80211_configure_filter(local);
  286 + } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
  287 + local->fif_probe_req++;
285 288 }
286 289  
287 290 changed |= ieee80211_reset_erp_info(sdata);
288 291  
... ... @@ -428,8 +431,12 @@
428 431 if (sdata->flags & IEEE80211_SDATA_PROMISC)
429 432 atomic_dec(&local->iff_promiscs);
430 433  
431   - if (sdata->vif.type == NL80211_IFTYPE_AP)
  434 + if (sdata->vif.type == NL80211_IFTYPE_AP) {
432 435 local->fif_pspoll--;
  436 + local->fif_probe_req--;
  437 + } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) {
  438 + local->fif_probe_req--;
  439 + }
433 440  
434 441 netif_addr_lock_bh(sdata->dev);
435 442 spin_lock_bh(&local->filter_lock);
... ... @@ -54,6 +54,9 @@
54 54 if (local->monitors || local->scanning)
55 55 new_flags |= FIF_BCN_PRBRESP_PROMISC;
56 56  
  57 + if (local->fif_probe_req || local->probe_req_reg)
  58 + new_flags |= FIF_PROBE_REQ;
  59 +
57 60 if (local->fif_fcsfail)
58 61 new_flags |= FIF_FCSFAIL;
59 62