mac80211_hwsim: check ATTR_FREQ for wmediumd (netlink) packets
authorAdam Welle <arwelle@cert.org>
Tue, 1 Dec 2015 22:13:52 +0000 (17:13 -0500)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 4 Dec 2015 13:43:32 +0000 (14:43 +0100)
If a packet is received from netlink with the frequency value set it is
checked against the current radio's frequency and discarded if different.
The frequency is also checked against data2->tmp_chan to support the "hw"
off-channel/scan case.

Signed-off-by: Adam Welle <arwelle@cert.org>
[allow both simultaneously, add locking]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/mac80211_hwsim.c

index 297b192b9e13d5e0629bd4c51ad34a31f675c3ca..c32889a1e39cf53d4e2d1ab3a4bfc2b8b492af1e 100644 (file)
@@ -2879,10 +2879,25 @@ static int hwsim_cloned_frame_received_nl(struct sk_buff *skb_2,
 
        /* A frame is received from user space */
        memset(&rx_status, 0, sizeof(rx_status));
-       /* TODO: Check ATTR_FREQ if it exists, and maybe throw away off-channel
-        * packets?
-        */
-       rx_status.freq = data2->channel->center_freq;
+       if (info->attrs[HWSIM_ATTR_FREQ]) {
+               /* throw away off-channel packets, but allow both the temporary
+                * ("hw" scan/remain-on-channel) and regular channel, since the
+                * internal datapath also allows this
+                */
+               mutex_lock(&data2->mutex);
+               rx_status.freq = nla_get_u32(info->attrs[HWSIM_ATTR_FREQ]);
+
+               if (rx_status.freq != data2->channel->center_freq &&
+                   (!data2->tmp_chan ||
+                    rx_status.freq != data2->tmp_chan->center_freq)) {
+                       mutex_unlock(&data2->mutex);
+                       goto out;
+               }
+               mutex_unlock(&data2->mutex);
+       } else {
+               rx_status.freq = data2->channel->center_freq;
+       }
+
        rx_status.band = data2->channel->band;
        rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
        rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);