wifi: mac80211: Drop cooked monitor support
authorAlexander Wetzel <Alexander@wetzel-home.de>
Tue, 4 Feb 2025 11:13:52 +0000 (12:13 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 11 Feb 2025 10:58:17 +0000 (11:58 +0100)
Hostapd switched from cooked monitor interfaces to nl80211 Dec 2011.
Drop support for the outdated cooked monitor interfaces and fix
creating the virtual monitor interfaces in the following cases:

 1) We have one non-monitor and one monitor interface with
    %MONITOR_FLAG_ACTIVE enabled and then delete the non-monitor
    interface.

 2) We only have monitor interfaces enabled on resume while at least one
    has %MONITOR_FLAG_ACTIVE set.

Signed-off-by: Alexander Wetzel <Alexander@wetzel-home.de>
Link: https://patch.msgid.link/20250204111352.7004-2-Alexander@wetzel-home.de
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/dropreason.h
net/mac80211/cfg.c
net/mac80211/drop.h
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/main.c
net/mac80211/rx.c
net/mac80211/status.c
net/mac80211/tx.c

index 56cb7be92244c2459f0a1e374539672e84df7100..7d3b1a2a6feca00ed65c46351e3f7d170cf1c2bb 100644 (file)
@@ -17,12 +17,6 @@ enum skb_drop_reason_subsys {
         */
        SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE,
 
-       /**
-        * @SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR: mac80211 drop reasons
-        * for frames still going to monitor, see net/mac80211/drop.h
-        */
-       SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR,
-
        /**
         * @SKB_DROP_REASON_SUBSYS_OPENVSWITCH: openvswitch drop reasons,
         * see net/openvswitch/drop.h
index 9351c64608a9986d4b6af5a6e5a80122d1393d60..88949b90f117edd9738f88dc953474de35ed2a1d 100644 (file)
@@ -89,15 +89,14 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
 
        /* check flags first */
        if (params->flags && ieee80211_sdata_running(sdata)) {
-               u32 mask = MONITOR_FLAG_COOK_FRAMES | MONITOR_FLAG_ACTIVE;
+               u32 mask = MONITOR_FLAG_ACTIVE;
 
                /*
-                * Prohibit MONITOR_FLAG_COOK_FRAMES and
-                * MONITOR_FLAG_ACTIVE to be changed while the
-                * interface is up.
+                * Prohibit MONITOR_FLAG_ACTIVE to be changed
+                * while the interface is up.
                 * Else we would need to add a lot of cruft
                 * to update everything:
-                *      cooked_mntrs, monitor and all fif_* counters
+                *      monitor and all fif_* counters
                 *      reconfigure hardware
                 */
                if ((params->flags & mask) != (sdata->u.mntr.flags & mask))
index 59e3ec4dc9607cbb3d8b06d31bbbfc2757c59214..eb9ab310f91caae59b8da9149eb6131b0d35c8c1 100644 (file)
 
 typedef unsigned int __bitwise ieee80211_rx_result;
 
-#define MAC80211_DROP_REASONS_MONITOR(R)       \
-       R(RX_DROP_M_UNEXPECTED_4ADDR_FRAME)     \
-       R(RX_DROP_M_BAD_BCN_KEYIDX)             \
-       R(RX_DROP_M_BAD_MGMT_KEYIDX)            \
-/* this line for the trailing \ - add before this */
-
 #define MAC80211_DROP_REASONS_UNUSABLE(R)      \
        /* 0x00 == ___RX_DROP_UNUSABLE */       \
        R(RX_DROP_U_MIC_FAIL)                   \
@@ -66,6 +60,10 @@ typedef unsigned int __bitwise ieee80211_rx_result;
        R(RX_DROP_U_UNEXPECTED_STA_4ADDR)       \
        R(RX_DROP_U_UNEXPECTED_VLAN_MCAST)      \
        R(RX_DROP_U_NOT_PORT_CONTROL)           \
+       R(RX_DROP_U_UNEXPECTED_4ADDR_FRAME)     \
+       R(RX_DROP_U_BAD_BCN_KEYIDX)             \
+       /* 0x30 */                              \
+       R(RX_DROP_U_BAD_MGMT_KEYIDX)            \
        R(RX_DROP_U_UNKNOWN_ACTION_REJECTED)    \
 /* this line for the trailing \ - add before this */
 
@@ -78,10 +76,6 @@ enum ___mac80211_drop_reason {
        ___RX_QUEUED    = SKB_NOT_DROPPED_YET,
 
 #define ENUM(x) ___ ## x,
-       ___RX_DROP_MONITOR = SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR <<
-               SKB_DROP_REASON_SUBSYS_SHIFT,
-       MAC80211_DROP_REASONS_MONITOR(ENUM)
-
        ___RX_DROP_UNUSABLE = SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE <<
                SKB_DROP_REASON_SUBSYS_SHIFT,
        MAC80211_DROP_REASONS_UNUSABLE(ENUM)
@@ -89,11 +83,10 @@ enum ___mac80211_drop_reason {
 };
 
 enum mac80211_drop_reason {
-       RX_CONTINUE      = (__force ieee80211_rx_result)___RX_CONTINUE,
-       RX_QUEUED        = (__force ieee80211_rx_result)___RX_QUEUED,
-       RX_DROP_MONITOR  = (__force ieee80211_rx_result)___RX_DROP_MONITOR,
+       RX_CONTINUE     = (__force ieee80211_rx_result)___RX_CONTINUE,
+       RX_QUEUED       = (__force ieee80211_rx_result)___RX_QUEUED,
+       RX_DROP         = (__force ieee80211_rx_result)___RX_DROP_UNUSABLE,
 #define DEF(x) x = (__force ieee80211_rx_result)___ ## x,
-       MAC80211_DROP_REASONS_MONITOR(DEF)
        MAC80211_DROP_REASONS_UNUSABLE(DEF)
 #undef DEF
 };
index e7dc3f0cfc9a9aa8e5ba228515f13342b8d90118..a90a44aa5758baea26fad83418a4598ebc4d27bb 100644 (file)
@@ -200,7 +200,6 @@ enum ieee80211_packet_rx_flags {
 /**
  * enum ieee80211_rx_flags - RX data flags
  *
- * @IEEE80211_RX_CMNTR: received on cooked monitor already
  * @IEEE80211_RX_BEACON_REPORTED: This frame was already reported
  *     to cfg80211_report_obss_beacon().
  *
@@ -208,8 +207,7 @@ enum ieee80211_packet_rx_flags {
  * for a single frame.
  */
 enum ieee80211_rx_flags {
-       IEEE80211_RX_CMNTR              = BIT(0),
-       IEEE80211_RX_BEACON_REPORTED    = BIT(1),
+       IEEE80211_RX_BEACON_REPORTED    = BIT(0),
 };
 
 struct ieee80211_rx_data {
@@ -1380,7 +1378,7 @@ struct ieee80211_local {
        spinlock_t queue_stop_reason_lock;
 
        int open_count;
-       int monitors, cooked_mntrs, tx_mntrs;
+       int monitors, tx_mntrs;
        /* number of interfaces with corresponding FIF_ flags */
        int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
            fif_probe_req;
@@ -1492,7 +1490,7 @@ struct ieee80211_local {
 
        /* see iface.c */
        struct list_head interfaces;
-       struct list_head mon_list; /* only that are IFF_UP && !cooked */
+       struct list_head mon_list; /* only that are IFF_UP */
        struct mutex iflist_mtx;
 
        /* Scanning and BSS list */
@@ -2090,8 +2088,7 @@ struct sk_buff *
 ieee80211_build_data_template(struct ieee80211_sub_if_data *sdata,
                              struct sk_buff *skb, u32 info_flags);
 void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
-                         int retry_count, bool send_to_cooked,
-                         struct ieee80211_tx_status *status);
+                         int retry_count, struct ieee80211_tx_status *status);
 
 void ieee80211_check_fast_xmit(struct sta_info *sta);
 void ieee80211_check_fast_xmit_all(struct ieee80211_local *local);
index 0ea7e77860b73fc66b3a8b6d90764c5c26af0420..7d3ebfcb8c2b0b3749c3a136d0be647586949b94 100644 (file)
@@ -483,8 +483,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
                ieee80211_ibss_stop(sdata);
                break;
        case NL80211_IFTYPE_MONITOR:
-               if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
-                       break;
                list_del_rcu(&sdata->u.mntr.list);
                break;
        default:
@@ -584,18 +582,17 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
                /* no need to tell driver */
                break;
        case NL80211_IFTYPE_MONITOR:
-               if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
-                       local->cooked_mntrs--;
-                       break;
-               }
+               if (!(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) &&
+                   !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
 
-               local->monitors--;
-               if (local->monitors == 0) {
-                       local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
-                       hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
-               }
+                       local->monitors--;
+                       if (local->monitors == 0) {
+                               local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR;
+                               hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
+                       }
 
-               ieee80211_adjust_monitor_flags(sdata, -1);
+                       ieee80211_adjust_monitor_flags(sdata, -1);
+               }
                break;
        case NL80211_IFTYPE_NAN:
                /* clean all the functions */
@@ -1326,27 +1323,24 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                }
                break;
        case NL80211_IFTYPE_MONITOR:
-               if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) {
-                       local->cooked_mntrs++;
-                       break;
-               }
-
                if ((sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE) ||
                    ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR)) {
                        res = drv_add_interface(local, sdata);
                        if (res)
                                goto err_stop;
-               } else if (local->monitors == 0 && local->open_count == 0) {
-                       res = ieee80211_add_virtual_monitor(local);
-                       if (res)
-                               goto err_stop;
-               }
+               } else {
+                       if (local->monitors == 0 && local->open_count == 0) {
+                               res = ieee80211_add_virtual_monitor(local);
+                               if (res)
+                                       goto err_stop;
+                       }
+                       local->monitors++;
 
-               /* must be before the call to ieee80211_configure_filter */
-               local->monitors++;
-               if (local->monitors == 1) {
-                       local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
-                       hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
+                       /* must be before the call to ieee80211_configure_filter */
+                       if (local->monitors == 1) {
+                               local->hw.conf.flags |= IEEE80211_CONF_MONITOR;
+                               hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR;
+                       }
                }
 
                ieee80211_adjust_monitor_flags(sdata, 1);
@@ -1423,8 +1417,6 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
                rcu_assign_pointer(local->p2p_sdata, sdata);
                break;
        case NL80211_IFTYPE_MONITOR:
-               if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
-                       break;
                list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list);
                break;
        default:
index 53e5aee4688569fb1291becbb9dc218ae4d47749..741e6c7edcb7c70701cc9c3f1e2ddc4b1d523d71 100644 (file)
@@ -1744,18 +1744,7 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
        wiphy_free(local->hw.wiphy);
 }
 EXPORT_SYMBOL(ieee80211_free_hw);
-
-static const char * const drop_reasons_monitor[] = {
-#define V(x)   #x,
-       [0] = "RX_DROP_MONITOR",
-       MAC80211_DROP_REASONS_MONITOR(V)
-};
-
-static struct drop_reason_list drop_reason_list_monitor = {
-       .reasons = drop_reasons_monitor,
-       .n_reasons = ARRAY_SIZE(drop_reasons_monitor),
-};
-
+#define V(x)   #x,
 static const char * const drop_reasons_unusable[] = {
        [0] = "RX_DROP_UNUSABLE",
        MAC80211_DROP_REASONS_UNUSABLE(V)
@@ -1784,8 +1773,6 @@ static int __init ieee80211_init(void)
        if (ret)
                goto err_netdev;
 
-       drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR,
-                                    &drop_reason_list_monitor);
        drop_reasons_register_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE,
                                     &drop_reason_list_unusable);
 
@@ -1804,7 +1791,6 @@ static void __exit ieee80211_exit(void)
 
        ieee80211_iface_exit();
 
-       drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_MONITOR);
        drop_reasons_unregister_subsys(SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE);
 
        rcu_barrier();
index 1e28efe4203c017cd2d0362e2981db2cc728f95c..d33970009e00d584cea915850b15fa564e0471af 100644 (file)
@@ -1045,14 +1045,14 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
                if (is_multicast_ether_addr(hdr->addr1)) {
                        if (ieee80211_has_tods(hdr->frame_control) ||
                            !ieee80211_has_fromds(hdr->frame_control))
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
                        if (ether_addr_equal(hdr->addr3, dev_addr))
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
                } else {
                        if (!ieee80211_has_a4(hdr->frame_control))
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
                        if (ether_addr_equal(hdr->addr4, dev_addr))
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
                }
        }
 
@@ -1064,20 +1064,20 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
                struct ieee80211_mgmt *mgmt;
 
                if (!ieee80211_is_mgmt(hdr->frame_control))
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                if (ieee80211_is_action(hdr->frame_control)) {
                        u8 category;
 
                        /* make sure category field is present */
                        if (rx->skb->len < IEEE80211_MIN_ACTION_SIZE)
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
 
                        mgmt = (struct ieee80211_mgmt *)hdr;
                        category = mgmt->u.action.category;
                        if (category != WLAN_CATEGORY_MESH_ACTION &&
                            category != WLAN_CATEGORY_SELF_PROTECTED)
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
                        return RX_CONTINUE;
                }
 
@@ -1087,7 +1087,7 @@ static ieee80211_rx_result ieee80211_rx_mesh_check(struct ieee80211_rx_data *rx)
                    ieee80211_is_auth(hdr->frame_control))
                        return RX_CONTINUE;
 
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        return RX_CONTINUE;
@@ -1513,7 +1513,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
                        hdrlen = ieee80211_hdrlen(hdr->frame_control);
 
                        if (rx->skb->len < hdrlen + 8)
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
 
                        skb_copy_bits(rx->skb, hdrlen + 6, &ethertype, 2);
                        if (ethertype == rx->sdata->control_port_protocol)
@@ -1526,7 +1526,7 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
                                               GFP_ATOMIC))
                        return RX_DROP_U_SPURIOUS;
 
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        return RX_CONTINUE;
@@ -1862,7 +1862,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
                                cfg80211_rx_unexpected_4addr_frame(
                                        rx->sdata->dev, sta->sta.addr,
                                        GFP_ATOMIC);
-                       return RX_DROP_M_UNEXPECTED_4ADDR_FRAME;
+                       return RX_DROP_U_UNEXPECTED_4ADDR_FRAME;
                }
                /*
                 * Update counter and free packet here to avoid
@@ -1997,7 +1997,7 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
                                cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
                                                             skb->data,
                                                             skb->len);
-                       return RX_DROP_M_BAD_BCN_KEYIDX;
+                       return RX_DROP_U_BAD_BCN_KEYIDX;
                }
 
                rx->key = ieee80211_rx_get_bigtk(rx, mmie_keyidx);
@@ -2011,11 +2011,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
 
                if (mmie_keyidx < NUM_DEFAULT_KEYS ||
                    mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS)
-                       return RX_DROP_M_BAD_MGMT_KEYIDX; /* unexpected BIP keyidx */
+                       return RX_DROP_U_BAD_MGMT_KEYIDX; /* unexpected BIP keyidx */
                if (rx->link_sta) {
                        if (ieee80211_is_group_privacy_action(skb) &&
                            test_sta_flag(rx->sta, WLAN_STA_MFP))
-                               return RX_DROP_MONITOR;
+                               return RX_DROP;
 
                        rx->key = rcu_dereference(rx->link_sta->gtk[mmie_keyidx]);
                }
@@ -2100,11 +2100,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_rx_data *rx)
 
        if (rx->key) {
                if (unlikely(rx->key->flags & KEY_FLAG_TAINTED))
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                /* TODO: add threshold stuff again */
        } else {
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        switch (rx->key->conf.cipher) {
@@ -2278,7 +2278,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
                goto out;
 
        if (is_multicast_ether_addr(hdr->addr1))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        I802_DEBUG_INC(rx->local->rx_handlers_fragments);
 
@@ -2333,7 +2333,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
                                          rx->seqno_idx, hdr);
        if (!entry) {
                I802_DEBUG_INC(rx->local->rx_handlers_drop_defrag);
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        /* "The receiver shall discard MSDUs and MMPDUs whose constituent
@@ -2855,25 +2855,25 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
                return RX_CONTINUE;
 
        if (!pskb_may_pull(skb, sizeof(*eth) + 6))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        mesh_hdr = (struct ieee80211s_hdr *)(skb->data + sizeof(*eth));
        mesh_hdrlen = ieee80211_get_mesh_hdrlen(mesh_hdr);
 
        if (!pskb_may_pull(skb, sizeof(*eth) + mesh_hdrlen))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        eth = (struct ethhdr *)skb->data;
        multicast = is_multicast_ether_addr(eth->h_dest);
 
        mesh_hdr = (struct ieee80211s_hdr *)(eth + 1);
        if (!mesh_hdr->ttl)
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        /* frame is in RMC, don't forward */
        if (is_multicast_ether_addr(eth->h_dest) &&
            mesh_rmc_check(sdata, eth->h_source, mesh_hdr))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        /* forward packet */
        if (sdata->crypto_tx_tailroom_needed_cnt)
@@ -2890,7 +2890,7 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
                        /* has_a4 already checked in ieee80211_rx_mesh_check */
                        proxied_addr = mesh_hdr->eaddr2;
                else
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                rcu_read_lock();
                mppath = mpp_path_lookup(sdata, proxied_addr);
@@ -2922,14 +2922,14 @@ ieee80211_rx_mesh_data(struct ieee80211_sub_if_data *sdata, struct sta_info *sta
                        goto rx_accept;
 
                IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_ttl);
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        if (!ifmsh->mshcfg.dot11MeshForwarding) {
                if (is_multicast_ether_addr(eth->h_dest))
                        goto rx_accept;
 
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        skb_set_queue_mapping(skb, ieee802_1d_to_ac[skb->priority]);
@@ -3122,7 +3122,7 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
                return RX_CONTINUE;
 
        if (unlikely(!ieee80211_is_data_present(fc)))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
                switch (rx->sdata->vif.type) {
@@ -3179,19 +3179,16 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
                return RX_CONTINUE;
 
        if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
-       /*
-        * Send unexpected-4addr-frame event to hostapd. For older versions,
-        * also drop the frame to cooked monitor interfaces.
-        */
+       /* Send unexpected-4addr-frame event to hostapd */
        if (ieee80211_has_a4(hdr->frame_control) &&
            sdata->vif.type == NL80211_IFTYPE_AP) {
                if (rx->sta &&
                    !test_and_set_sta_flag(rx->sta, WLAN_STA_4ADDR_EVENT))
                        cfg80211_rx_unexpected_4addr_frame(
                                rx->sdata->dev, rx->sta->sta.addr, GFP_ATOMIC);
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        res = __ieee80211_data_to_8023(rx, &port_control);
@@ -3203,7 +3200,7 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
                return res;
 
        if (!ieee80211_frame_allowed(rx, fc))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        /* directly handle TDLS channel switch requests/responses */
        if (unlikely(((struct ethhdr *)rx->skb->data)->h_proto ==
@@ -3268,11 +3265,11 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
                };
 
                if (!rx->sta)
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                if (skb_copy_bits(skb, offsetof(struct ieee80211_bar, control),
                                  &bar_data, sizeof(bar_data)))
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                tid = le16_to_cpu(bar_data.control) >> 12;
 
@@ -3284,7 +3281,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
 
                tid_agg_rx = rcu_dereference(rx->sta->ampdu_mlme.tid_rx[tid]);
                if (!tid_agg_rx)
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                start_seq_num = le16_to_cpu(bar_data.start_seq_num) >> 4;
                event.u.ba.tid = tid;
@@ -3308,12 +3305,7 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx, struct sk_buff_head *frames)
                return RX_QUEUED;
        }
 
-       /*
-        * After this point, we only want management frames,
-        * so we can drop all remaining control frames to
-        * cooked monitor interfaces.
-        */
-       return RX_DROP_MONITOR;
+       return RX_DROP;
 }
 
 static void ieee80211_process_sa_query_req(struct ieee80211_sub_if_data *sdata,
@@ -3422,10 +3414,10 @@ ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
         * and unknown (reserved) frames are useless.
         */
        if (rx->skb->len < 24)
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        if (!ieee80211_is_mgmt(mgmt->frame_control))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        /* drop too small action frames */
        if (ieee80211_is_action(mgmt->frame_control) &&
@@ -3951,17 +3943,16 @@ ieee80211_rx_h_action_return(struct ieee80211_rx_data *rx)
         * ones. For all other modes we will return them to the sender,
         * setting the 0x80 bit in the action category, as required by
         * 802.11-2012 9.24.4.
-        * Newer versions of hostapd shall also use the management frame
-        * registration mechanisms, but older ones still use cooked
-        * monitor interfaces so push all frames there.
+        * Newer versions of hostapd use the management frame registration
+        * mechanisms and old cooked monitor interface is no longer supported.
         */
        if (!(status->rx_flags & IEEE80211_RX_MALFORMED_ACTION_FRM) &&
            (sdata->vif.type == NL80211_IFTYPE_AP ||
             sdata->vif.type == NL80211_IFTYPE_AP_VLAN))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        if (is_multicast_ether_addr(mgmt->da))
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        /* do not return rejected action frames */
        if (mgmt->u.action.category & 0x80)
@@ -4006,7 +3997,7 @@ ieee80211_rx_h_ext(struct ieee80211_rx_data *rx)
                return RX_CONTINUE;
 
        if (sdata->vif.type != NL80211_IFTYPE_STATION)
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        /* for now only beacons are ext, so queue them */
        ieee80211_queue_skb_to_iface(sdata, rx->link_id, rx->sta, rx->skb);
@@ -4027,7 +4018,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
            sdata->vif.type != NL80211_IFTYPE_ADHOC &&
            sdata->vif.type != NL80211_IFTYPE_OCB &&
            sdata->vif.type != NL80211_IFTYPE_STATION)
-               return RX_DROP_MONITOR;
+               return RX_DROP;
 
        switch (stype) {
        case cpu_to_le16(IEEE80211_STYPE_AUTH):
@@ -4038,32 +4029,32 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
        case cpu_to_le16(IEEE80211_STYPE_DEAUTH):
                if (is_multicast_ether_addr(mgmt->da) &&
                    !is_broadcast_ether_addr(mgmt->da))
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                /* process only for station/IBSS */
                if (sdata->vif.type != NL80211_IFTYPE_STATION &&
                    sdata->vif.type != NL80211_IFTYPE_ADHOC)
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
                break;
        case cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP):
        case cpu_to_le16(IEEE80211_STYPE_REASSOC_RESP):
        case cpu_to_le16(IEEE80211_STYPE_DISASSOC):
                if (is_multicast_ether_addr(mgmt->da) &&
                    !is_broadcast_ether_addr(mgmt->da))
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
 
                /* process only for station */
                if (sdata->vif.type != NL80211_IFTYPE_STATION)
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
                break;
        case cpu_to_le16(IEEE80211_STYPE_PROBE_REQ):
                /* process only for ibss and mesh */
                if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
                    sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
-                       return RX_DROP_MONITOR;
+                       return RX_DROP;
                break;
        default:
-               return RX_DROP_MONITOR;
+               return RX_DROP;
        }
 
        ieee80211_queue_skb_to_iface(sdata, rx->link_id, rx->sta, rx->skb);
@@ -4071,82 +4062,9 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
        return RX_QUEUED;
 }
 
-static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx,
-                                       struct ieee80211_rate *rate,
-                                       ieee80211_rx_result reason)
-{
-       struct ieee80211_sub_if_data *sdata;
-       struct ieee80211_local *local = rx->local;
-       struct sk_buff *skb = rx->skb, *skb2;
-       struct net_device *prev_dev = NULL;
-       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);
-       int needed_headroom;
-
-       /*
-        * If cooked monitor has been processed already, then
-        * don't do it again. If not, set the flag.
-        */
-       if (rx->flags & IEEE80211_RX_CMNTR)
-               goto out_free_skb;
-       rx->flags |= IEEE80211_RX_CMNTR;
-
-       /* If there are no cooked monitor interfaces, just free the SKB */
-       if (!local->cooked_mntrs)
-               goto out_free_skb;
-
-       /* room for the radiotap header based on driver features */
-       needed_headroom = ieee80211_rx_radiotap_hdrlen(local, status, skb);
-
-       if (skb_headroom(skb) < needed_headroom &&
-           pskb_expand_head(skb, needed_headroom, 0, GFP_ATOMIC))
-               goto out_free_skb;
-
-       /* prepend radiotap information */
-       ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom,
-                                        false);
-
-       skb_reset_mac_header(skb);
-       skb->ip_summed = CHECKSUM_UNNECESSARY;
-       skb->pkt_type = PACKET_OTHERHOST;
-       skb->protocol = htons(ETH_P_802_2);
-
-       list_for_each_entry_rcu(sdata, &local->interfaces, list) {
-               if (!ieee80211_sdata_running(sdata))
-                       continue;
-
-               if (sdata->vif.type != NL80211_IFTYPE_MONITOR ||
-                   !(sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES))
-                       continue;
-
-               if (prev_dev) {
-                       skb2 = skb_clone(skb, GFP_ATOMIC);
-                       if (skb2) {
-                               skb2->dev = prev_dev;
-                               netif_receive_skb(skb2);
-                       }
-               }
-
-               prev_dev = sdata->dev;
-               dev_sw_netstats_rx_add(sdata->dev, skb->len);
-       }
-
-       if (prev_dev) {
-               skb->dev = prev_dev;
-               netif_receive_skb(skb);
-               return;
-       }
-
- out_free_skb:
-       kfree_skb_reason(skb, (__force u32)reason);
-}
-
 static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
                                         ieee80211_rx_result res)
 {
-       struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
-       struct ieee80211_supported_band *sband;
-       struct ieee80211_rate *rate = NULL;
-
        if (res == RX_QUEUED) {
                I802_DEBUG_INC(rx->sdata->local->rx_handlers_queued);
                return;
@@ -4158,23 +4076,13 @@ static void ieee80211_rx_handlers_result(struct ieee80211_rx_data *rx,
                        rx->link_sta->rx_stats.dropped++;
        }
 
-       if (u32_get_bits((__force u32)res, SKB_DROP_REASON_SUBSYS_MASK) ==
-                       SKB_DROP_REASON_SUBSYS_MAC80211_UNUSABLE) {
-               kfree_skb_reason(rx->skb, (__force u32)res);
-               return;
-       }
-
-       sband = rx->local->hw.wiphy->bands[status->band];
-       if (status->encoding == RX_ENC_LEGACY)
-               rate = &sband->bitrates[status->rate_idx];
-
-       ieee80211_rx_cooked_monitor(rx, rate, res);
+       kfree_skb_reason(rx->skb, (__force u32)res);
 }
 
 static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
                                  struct sk_buff_head *frames)
 {
-       ieee80211_rx_result res = RX_DROP_MONITOR;
+       ieee80211_rx_result res = RX_DROP;
        struct sk_buff *skb;
 
 #define CALL_RXH(rxh)                  \
@@ -4238,7 +4146,7 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx,
 static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx)
 {
        struct sk_buff_head reorder_release;
-       ieee80211_rx_result res = RX_DROP_MONITOR;
+       ieee80211_rx_result res = RX_DROP;
 
        __skb_queue_head_init(&reorder_release);
 
index 5f28f3633fa0a45f299ed88916b4a8c7eb8209f0..b17b3cc7fb903d81c9ec0e821765ef4d3628c10a 100644 (file)
@@ -895,8 +895,7 @@ static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
 }
 
 void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
-                         int retry_count, bool send_to_cooked,
-                         struct ieee80211_tx_status *status)
+                         int retry_count, struct ieee80211_tx_status *status)
 {
        struct sk_buff *skb2;
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -930,10 +929,6 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
                        if (sdata->u.mntr.flags & MONITOR_FLAG_SKIP_TX)
                                continue;
 
-                       if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) &&
-                           !send_to_cooked)
-                               continue;
-
                        if (prev_dev) {
                                skb2 = skb_clone(skb, GFP_ATOMIC);
                                if (skb2) {
@@ -964,7 +959,6 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
        struct ieee80211_tx_info *info = status->info;
        struct sta_info *sta;
        __le16 fc;
-       bool send_to_cooked;
        bool acked;
        bool noack_success;
        struct ieee80211_bar *bar;
@@ -1091,28 +1085,10 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
 
        ieee80211_report_used_skb(local, skb, false, status->ack_hwtstamp);
 
-       /* this was a transmitted frame, but now we want to reuse it */
-       skb_orphan(skb);
-
-       /* Need to make a copy before skb->cb gets cleared */
-       send_to_cooked = !!(info->flags & IEEE80211_TX_CTL_INJECTED) ||
-                        !(ieee80211_is_data(fc));
-
-       /*
-        * This is a bit racy but we can avoid a lot of work
-        * with this test...
-        */
-       if (!local->tx_mntrs && (!send_to_cooked || !local->cooked_mntrs)) {
-               if (status->free_list)
-                       list_add_tail(&skb->list, status->free_list);
-               else
-                       dev_kfree_skb(skb);
-               return;
-       }
-
-       /* send to monitor interfaces */
-       ieee80211_tx_monitor(local, skb, retry_count,
-                            send_to_cooked, status);
+       if (status->free_list)
+               list_add_tail(&skb->list, status->free_list);
+       else
+               dev_kfree_skb(skb);
 }
 
 void ieee80211_tx_status_skb(struct ieee80211_hw *hw, struct sk_buff *skb)
index a24636bda67936b4dc0f6a730b7aaa2986e56003..1289df373795eb357b035691bcc7a7e2e573aa60 100644 (file)
@@ -5617,7 +5617,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
        if (!copy)
                return bcn;
 
-       ieee80211_tx_monitor(hw_to_local(hw), copy, 1, false, NULL);
+       ieee80211_tx_monitor(hw_to_local(hw), copy, 1, NULL);
 
        return bcn;
 }