]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mac80211: Accept frames on NAN DATA interfaces
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Thu, 26 Mar 2026 10:14:42 +0000 (12:14 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 7 Apr 2026 13:36:04 +0000 (15:36 +0200)
Accept frames there were received on NAN DATA interfaces:

- Data frames, both multicast or unicast
- Non-Public action frames, both multicast or unicast
- Unicast secure management frames
- FromDS and ToDS are 0.

While at it, check FromDS/ToDS also for NAN management frames.

Accept only data frames from devices that are part of the NAN
cluster.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260326121156.0e6f37d4a40c.Iaa84cc3d063392f0150fcdf2bf610bdb41062f70@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/rx.c

index dbdd67c181d8a275c5d0f5f7d75aa8acb04074f4..a00b734209296350826b10ca642e03468e937dc4 100644 (file)
@@ -4469,6 +4469,9 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
        u8 *bssid = ieee80211_get_bssid(hdr, skb->len, sdata->vif.type);
        bool multicast = is_multicast_ether_addr(hdr->addr1) ||
                         ieee80211_is_s1g_beacon(hdr->frame_control);
+       static const u8 nan_network_id[ETH_ALEN] __aligned(2) = {
+               0x51, 0x6F, 0x9A, 0x01, 0x00, 0x00
+       };
 
        switch (sdata->vif.type) {
        case NL80211_IFTYPE_STATION:
@@ -4597,6 +4600,10 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
                       (ieee80211_is_auth(hdr->frame_control) &&
                        ether_addr_equal(sdata->vif.addr, hdr->addr1));
        case NL80211_IFTYPE_NAN:
+               if (ieee80211_has_tods(hdr->frame_control) ||
+                   ieee80211_has_fromds(hdr->frame_control))
+                       return false;
+
                /* Accept only frames that are addressed to the NAN cluster
                 * (based on the Cluster ID). From these frames, accept only
                 * action frames or authentication frames that are addressed to
@@ -4608,7 +4615,35 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
                         (ieee80211_is_auth(hdr->frame_control) &&
                          ether_addr_equal(sdata->vif.addr, hdr->addr1)));
        case NL80211_IFTYPE_NAN_DATA:
-               return false;
+               if (ieee80211_has_tods(hdr->frame_control) ||
+                   ieee80211_has_fromds(hdr->frame_control))
+                       return false;
+
+               if (ieee80211_is_data(hdr->frame_control)) {
+                       struct ieee80211_sub_if_data *nmi;
+
+                       nmi = rcu_dereference(sdata->u.nan_data.nmi);
+                       if (!nmi)
+                               return false;
+
+                       if (!ether_addr_equal(nmi->wdev.u.nan.cluster_id,
+                                             hdr->addr3))
+                               return false;
+
+                       return multicast ||
+                              ether_addr_equal(sdata->vif.addr, hdr->addr1);
+               }
+
+               /* Non-public action frames (unicast or multicast) */
+               if (ieee80211_is_action(hdr->frame_control) &&
+                   !ieee80211_is_public_action(hdr, skb->len) &&
+                   (ether_addr_equal(nan_network_id, hdr->addr1) ||
+                    ether_addr_equal(sdata->vif.addr, hdr->addr1)))
+                       return true;
+
+               /* Unicast secure management frames */
+               return ether_addr_equal(sdata->vif.addr, hdr->addr1) &&
+                      ieee80211_is_unicast_robust_mgmt_frame(skb);
        default:
                break;
        }