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:
(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
(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;
}