Add a new wdev-only interface type NL80211_IFTYPE_PD to support Proximity Detection (PD) operations such as PASN, key install and peer measurement operations. This interface type operates without a netdev, similar to P2P_DEVICE and NAN interfaces. Implement support across cfg80211 and mac80211 layers with key management gated by the NL80211_EXT_FEATURE_SECURE_RTT feature flag, management frame registration and transmission capabilities, and proper channel context handling where PD interfaces are excluded from bandwidth calculations. The PD interface provides isolated functionality for PD PASN and PMSR without affecting existing network operations. Signed-off-by: Peddolla Harshavardhan Reddy --- include/uapi/linux/nl80211.h | 2 ++ net/mac80211/cfg.c | 2 ++ net/mac80211/chan.c | 2 ++ net/mac80211/iface.c | 6 +++++- net/mac80211/offchannel.c | 1 + net/mac80211/rx.c | 1 + net/mac80211/util.c | 1 + net/wireless/chan.c | 2 ++ net/wireless/core.c | 1 + net/wireless/mlme.c | 1 + net/wireless/nl80211.c | 27 +++++++++++++++++++++++++-- net/wireless/reg.c | 3 +++ net/wireless/util.c | 4 +++- 13 files changed, 49 insertions(+), 4 deletions(-) diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index 49f4704ce627..b1f0e72ec953 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3671,6 +3671,7 @@ enum nl80211_attrs { * @NL80211_IFTYPE_OCB: Outside Context of a BSS * This mode corresponds to the MIB variable dot11OCBActivated=true * @NL80211_IFTYPE_NAN: NAN device interface type (not a netdev) + * @NL80211_IFTYPE_PD: PD device interface type (not a netdev) * @NL80211_IFTYPE_MAX: highest interface type number currently defined * @NUM_NL80211_IFTYPES: number of defined interface types * @@ -3692,6 +3693,7 @@ enum nl80211_iftype { NL80211_IFTYPE_P2P_DEVICE, NL80211_IFTYPE_OCB, NL80211_IFTYPE_NAN, + NL80211_IFTYPE_PD, /* keep last */ NUM_NL80211_IFTYPES, diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index ee64ac8e0f61..dac211f9a438 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -713,6 +713,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct wireless_dev *wdev, case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: case NL80211_IFTYPE_UNSPECIFIED: case NUM_NL80211_IFTYPES: case NL80211_IFTYPE_P2P_CLIENT: @@ -3183,6 +3184,7 @@ static int ieee80211_scan(struct wiphy *wiphy, } break; case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: default: return -EOPNOTSUPP; } diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index 4447cf03c41b..00cbb13fb74b 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c @@ -473,6 +473,7 @@ ieee80211_get_chanctx_max_required_bw(struct ieee80211_local *local, break; case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: continue; case NL80211_IFTYPE_MONITOR: WARN_ON_ONCE(!ieee80211_hw_check(&local->hw, @@ -1414,6 +1415,7 @@ ieee80211_link_chanctx_reservation_complete(struct ieee80211_link_data *link) case NL80211_IFTYPE_P2P_GO: case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: case NUM_NL80211_IFTYPES: WARN_ON(1); break; diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 676b2a43c9f2..b647c6394b28 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c @@ -1369,6 +1369,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: /* no special treatment */ break; case NL80211_IFTYPE_UNSPECIFIED: @@ -1489,7 +1490,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) FIF_PROBE_REQ); if (sdata->vif.type != NL80211_IFTYPE_P2P_DEVICE && - sdata->vif.type != NL80211_IFTYPE_NAN) + sdata->vif.type != NL80211_IFTYPE_NAN && + sdata->vif.type != NL80211_IFTYPE_PD) changed |= ieee80211_reset_erp_info(sdata); ieee80211_link_info_change_notify(sdata, &sdata->deflink, changed); @@ -1504,6 +1506,7 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) break; case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: break; default: /* not reached */ @@ -1935,6 +1938,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, break; case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_PD: sdata->vif.bss_conf.bssid = sdata->vif.addr; break; case NL80211_IFTYPE_UNSPECIFIED: diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 5f398d38d1c9..04c6031dc46b 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c @@ -898,6 +898,7 @@ int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, need_offchan = true; break; case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: break; default: return -EOPNOTSUPP; diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 6c4b549444c6..ed3f7e3094ea 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -4621,6 +4621,7 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) (ieee80211_is_public_action(hdr, skb->len) || (ieee80211_is_auth(hdr->frame_control) && ether_addr_equal(sdata->vif.addr, hdr->addr1))); + case NL80211_IFTYPE_PD: default: break; } diff --git a/net/mac80211/util.c b/net/mac80211/util.c index b2e6c8b98381..2fa81fb57093 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c @@ -2121,6 +2121,7 @@ int ieee80211_reconfig(struct ieee80211_local *local) case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_PD: /* nothing to do */ break; case NL80211_IFTYPE_UNSPECIFIED: diff --git a/net/wireless/chan.c b/net/wireless/chan.c index d9d4e043bb39..31b621de3f9b 100644 --- a/net/wireless/chan.c +++ b/net/wireless/chan.c @@ -796,6 +796,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy, case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_PD: break; case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_UNSPECIFIED: @@ -919,6 +920,7 @@ bool cfg80211_beaconing_iface_active(struct wireless_dev *wdev) case NL80211_IFTYPE_P2P_DEVICE: /* Can NAN type be considered as beaconing interface? */ case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: break; case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_WDS: diff --git a/net/wireless/core.c b/net/wireless/core.c index 23afc250bc10..67a603129c42 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c @@ -1420,6 +1420,7 @@ void cfg80211_leave(struct cfg80211_registered_device *rdev, break; case NL80211_IFTYPE_AP_VLAN: case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_PD: /* nothing to do */ break; case NL80211_IFTYPE_UNSPECIFIED: diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 5cd86253a62e..6d13093ce449 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c @@ -939,6 +939,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev, * public action frames */ case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: default: err = -EOPNOTSUPP; break; diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 2d22fd405c39..293fdd07ac7a 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1711,6 +1711,11 @@ static int nl80211_key_allowed(struct wireless_dev *wdev) NL80211_EXT_FEATURE_SECURE_NAN)) return 0; return -EINVAL; + case NL80211_IFTYPE_PD: + if (wiphy_ext_feature_isset(wdev->wiphy, + NL80211_EXT_FEATURE_SECURE_RTT)) + return 0; + return -EINVAL; case NL80211_IFTYPE_UNSPECIFIED: case NL80211_IFTYPE_OCB: case NL80211_IFTYPE_MONITOR: @@ -4739,6 +4744,7 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) return -EOPNOTSUPP; if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN || + type == NL80211_IFTYPE_PD || rdev->wiphy.features & NL80211_FEATURE_MAC_ON_CREATE) && info->attrs[NL80211_ATTR_MAC]) { nla_memcpy(params.macaddr, info->attrs[NL80211_ATTR_MAC], @@ -4795,8 +4801,9 @@ static int _nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) break; case NL80211_IFTYPE_NAN: case NL80211_IFTYPE_P2P_DEVICE: + case NL80211_IFTYPE_PD: /* - * P2P Device and NAN do not have a netdev, so don't go + * P2P Device, NAN and PD do not have a netdev, so don't go * through the netdev notifier and must be added here */ cfg80211_init_wdev(wdev); @@ -10537,7 +10544,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) wiphy = &rdev->wiphy; - if (wdev->iftype == NL80211_IFTYPE_NAN) + if (wdev->iftype == NL80211_IFTYPE_NAN || + wdev->iftype == NL80211_IFTYPE_PD) return -EOPNOTSUPP; if (!rdev->ops->scan) @@ -13954,6 +13962,11 @@ static int nl80211_register_mgmt(struct sk_buff *skb, struct genl_info *info) WIPHY_NAN_FLAGS_USERSPACE_DE)) return -EOPNOTSUPP; break; + case NL80211_IFTYPE_PD: + if (!wiphy_ext_feature_isset(wdev->wiphy, + NL80211_EXT_FEATURE_SECURE_RTT)) + return -EOPNOTSUPP; + break; default: return -EOPNOTSUPP; } @@ -14017,6 +14030,11 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) WIPHY_NAN_FLAGS_USERSPACE_DE)) return -EOPNOTSUPP; break; + case NL80211_IFTYPE_PD: + if (!wiphy_ext_feature_isset(wdev->wiphy, + NL80211_EXT_FEATURE_SECURE_RTT)) + return -EOPNOTSUPP; + break; default: return -EOPNOTSUPP; } @@ -14142,6 +14160,11 @@ static int nl80211_tx_mgmt_cancel_wait(struct sk_buff *skb, struct genl_info *in NL80211_EXT_FEATURE_SECURE_NAN)) return -EOPNOTSUPP; break; + case NL80211_IFTYPE_PD: + if (!wiphy_ext_feature_isset(wdev->wiphy, + NL80211_EXT_FEATURE_SECURE_RTT)) + return -EOPNOTSUPP; + break; default: return -EOPNOTSUPP; } diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 1c5c38d18feb..fb7eaee734b4 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c @@ -2411,6 +2411,9 @@ static bool reg_wdev_chan_valid(struct wiphy *wiphy, struct wireless_dev *wdev) case NL80211_IFTYPE_NAN: /* we have no info, but NAN is also pretty universal */ continue; + case NL80211_IFTYPE_PD: + /* we have no info, but PD is also pretty universal */ + continue; default: /* others not implemented for now */ WARN_ON_ONCE(1); diff --git a/net/wireless/util.c b/net/wireless/util.c index 0a0cea018fc5..d558c4bc00f0 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c @@ -1186,7 +1186,8 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, /* cannot change into P2P device or NAN */ if (ntype == NL80211_IFTYPE_P2P_DEVICE || - ntype == NL80211_IFTYPE_NAN) + ntype == NL80211_IFTYPE_NAN || + ntype == NL80211_IFTYPE_PD) return -EOPNOTSUPP; if (!rdev->ops->change_virtual_intf || @@ -1250,6 +1251,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, case NL80211_IFTYPE_P2P_DEVICE: case NL80211_IFTYPE_WDS: case NL80211_IFTYPE_NAN: + case NL80211_IFTYPE_PD: WARN_ON(1); break; } -- 2.34.1