wifi: mac80211_hwsim: handle links for wmediumd/virtio
authorJohannes Berg <johannes.berg@intel.com>
Wed, 20 Jul 2022 20:35:44 +0000 (22:35 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Fri, 22 Jul 2022 12:28:20 +0000 (14:28 +0200)
For wmediumd/virtio, handle both the RX channel for links,
as well as the link addresses when links are added/removed.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/mac80211_hwsim.c

index 39dd437207cac2a8b971680d738d9728d3414b5a..6e55f153ff26e95a635adcaa75caa04dffc63732 100644 (file)
@@ -2995,6 +2995,24 @@ static int mac80211_hwsim_change_vif_links(struct ieee80211_hw *hw,
                                           u16 old_links, u16 new_links,
                                           struct ieee80211_bss_conf *old[IEEE80211_MLD_MAX_NUM_LINKS])
 {
+       unsigned long rem = old_links & ~new_links ?: BIT(0);
+       unsigned long add = new_links & ~old_links;
+       int i;
+
+       for_each_set_bit(i, &rem, IEEE80211_MLD_MAX_NUM_LINKS)
+               mac80211_hwsim_config_mac_nl(hw, old[i]->addr, false);
+
+       for_each_set_bit(i, &add, IEEE80211_MLD_MAX_NUM_LINKS) {
+               struct ieee80211_bss_conf *link_conf;
+
+               /* FIXME: figure out how to get the locking here */
+               link_conf = rcu_dereference_protected(vif->link_conf[i], 1);
+               if (WARN_ON(!link_conf))
+                       continue;
+
+               mac80211_hwsim_config_mac_nl(hw, link_conf->addr, true);
+       }
+
        return 0;
 }
 
@@ -4478,16 +4496,28 @@ 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));
        if (info->attrs[HWSIM_ATTR_FREQ]) {
+               struct tx_iter_data iter_data = {};
+
                /* 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
+                * ("hw" scan/remain-on-channel), regular channels and links,
+                * 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 != channel->center_freq) {
-                       mutex_unlock(&data2->mutex);
+               iter_data.channel = ieee80211_get_channel(data2->hw->wiphy,
+                                                         rx_status.freq);
+               if (!iter_data.channel)
                        goto out;
+
+               mutex_lock(&data2->mutex);
+               if (!hwsim_chans_compat(iter_data.channel, channel)) {
+                       ieee80211_iterate_active_interfaces_atomic(
+                               data2->hw, IEEE80211_IFACE_ITER_NORMAL,
+                               mac80211_hwsim_tx_iter, &iter_data);
+                       if (!iter_data.receive) {
+                               mutex_unlock(&data2->mutex);
+                               goto out;
+                       }
                }
                mutex_unlock(&data2->mutex);
        } else {