mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 18:03:10 -04:00
wifi: cfg80211/nl80211: add STA-mode peer probing
Add NL80211_EXT_FEATURE_PROBE_AP to allow drivers to advertise support for probing the associated AP from STA/P2P-client mode. Extend nl80211_probe_peer() to accept STA/P2P-client interfaces when the driver advertises NL80211_EXT_FEATURE_PROBE_AP; in that case the MAC attribute must be omitted (the peer is implied by the association). Update cfg80211_probe_status() to accept an optional peer address and a link_id parameter (-1 for non-MLO), and include NL80211_ATTR_MLO_LINK_ID in the event when link_id >= 0. Update all callers. Signed-off-by: Priyansha Tiwari <priyansha.tiwari@oss.qualcomm.com> Link: https://patch.msgid.link/20260611062225.2144241-3-pritiwa@qti.qualcomm.com Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
committed by
Johannes Berg
parent
4ab9b637b9
commit
010e955c20
@@ -2326,7 +2326,7 @@ static void wil_probe_client_handle(struct wil6210_priv *wil,
|
||||
*/
|
||||
bool alive = (sta->status == wil_sta_connected);
|
||||
|
||||
cfg80211_probe_status(ndev, sta->addr, req->cookie, alive,
|
||||
cfg80211_probe_status(ndev, sta->addr, req->cookie, -1, alive,
|
||||
0, false, GFP_KERNEL);
|
||||
}
|
||||
|
||||
|
||||
@@ -5086,8 +5086,8 @@ struct mgmt_frame_regs {
|
||||
* @tdls_mgmt: Transmit a TDLS management frame.
|
||||
* @tdls_oper: Perform a high-level TDLS operation (e.g. TDLS link setup).
|
||||
*
|
||||
* @probe_peer: probe an associated client, must return a cookie that it
|
||||
* later passes to cfg80211_probe_status().
|
||||
* @probe_peer: probe a connected peer (AP: STA MAC required; STA: no MAC),
|
||||
* must return a cookie that is later passed to cfg80211_probe_status().
|
||||
*
|
||||
* @set_noack_map: Set the NoAck Map for the TIDs.
|
||||
*
|
||||
@@ -9846,15 +9846,17 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, const u8 *addr,
|
||||
/**
|
||||
* cfg80211_probe_status - notify userspace about probe status
|
||||
* @dev: the device the probe was sent on
|
||||
* @addr: the address of the peer
|
||||
* @cookie: the cookie filled in @probe_client previously
|
||||
* @peer: The peer MAC address (or MLD address for MLO) or %NULL if not
|
||||
* applicable (e.g. for STA/P2P-client)
|
||||
* @cookie: the cookie filled in @probe_peer previously
|
||||
* @link_id: The link ID on which the probe was sent (or -1 for non-MLO)
|
||||
* @acked: indicates whether probe was acked or not
|
||||
* @ack_signal: signal strength (in dBm) of the ACK frame.
|
||||
* @is_valid_ack_signal: indicates the ack_signal is valid or not.
|
||||
* @gfp: allocation flags
|
||||
*/
|
||||
void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
u64 cookie, bool acked, s32 ack_signal,
|
||||
void cfg80211_probe_status(struct net_device *dev, const u8 *peer, u64 cookie,
|
||||
int link_id, bool acked, s32 ack_signal,
|
||||
bool is_valid_ack_signal, gfp_t gfp);
|
||||
|
||||
/**
|
||||
|
||||
@@ -922,13 +922,15 @@
|
||||
* and wasn't already in a 4-addr VLAN. The event will be sent similarly
|
||||
* to the %NL80211_CMD_UNEXPECTED_FRAME event, to the same listener.
|
||||
*
|
||||
* @NL80211_CMD_PROBE_PEER: Probe an associated station on an AP interface
|
||||
* by sending a null data frame to it and reporting when the frame is
|
||||
* acknowledged. This is used to allow timing out inactive clients. Uses
|
||||
* %NL80211_ATTR_IFINDEX and %NL80211_ATTR_MAC. The command returns a
|
||||
* direct reply with an %NL80211_ATTR_COOKIE that is later used to match
|
||||
* up the event with the request. The event includes the same data and
|
||||
* has %NL80211_ATTR_ACK set if the frame was ACKed.
|
||||
* @NL80211_CMD_PROBE_PEER: Probe a connected peer by sending a null data
|
||||
* frame and reporting when the frame is acknowledged.
|
||||
* In AP/GO mode, %NL80211_ATTR_MAC is required to identify the client.
|
||||
* In STA/P2P-client mode, %NL80211_ATTR_MAC must be omitted (the AP is
|
||||
* implied); the driver must advertise %NL80211_EXT_FEATURE_PROBE_AP.
|
||||
* The command returns a direct reply with an %NL80211_ATTR_COOKIE that
|
||||
* is later used to match up the event with the request. The event
|
||||
* includes the same data and has %NL80211_ATTR_ACK set if the frame
|
||||
* was ACKed.
|
||||
*
|
||||
* @NL80211_CMD_REGISTER_BEACONS: Register this socket to receive beacons from
|
||||
* other BSSes when any interfaces are in AP mode. This helps implement
|
||||
@@ -7086,6 +7088,9 @@ enum nl80211_feature_flags {
|
||||
* LTF key seed via %NL80211_KEY_LTF_SEED. The seed is used to generate
|
||||
* secure LTF keys for secure LTF measurement sessions.
|
||||
*
|
||||
* @NL80211_EXT_FEATURE_PROBE_AP: Driver supports probing the associated AP
|
||||
* in STA mode using @NL80211_CMD_PROBE_PEER.
|
||||
*
|
||||
* @NUM_NL80211_EXT_FEATURES: number of extended features.
|
||||
* @MAX_NL80211_EXT_FEATURES: highest extended feature index.
|
||||
*/
|
||||
@@ -7167,6 +7172,7 @@ enum nl80211_ext_feature_index {
|
||||
NL80211_EXT_FEATURE_IEEE8021X_AUTH,
|
||||
NL80211_EXT_FEATURE_ROC_ADDR_FILTER,
|
||||
NL80211_EXT_FEATURE_SET_KEY_LTF_SEED,
|
||||
NL80211_EXT_FEATURE_PROBE_AP,
|
||||
|
||||
/* add new features before the definition below */
|
||||
NUM_NL80211_EXT_FEATURES,
|
||||
|
||||
@@ -655,7 +655,7 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local,
|
||||
GFP_ATOMIC);
|
||||
else if (ieee80211_is_any_nullfunc(hdr->frame_control))
|
||||
cfg80211_probe_status(sdata->dev, hdr->addr1,
|
||||
cookie, acked,
|
||||
cookie, -1, acked,
|
||||
info->status.ack_signal,
|
||||
is_valid_ack_signal,
|
||||
GFP_ATOMIC);
|
||||
|
||||
@@ -16157,16 +16157,32 @@ static int nl80211_probe_peer(struct sk_buff *skb, struct genl_info *info)
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
const u8 *addr;
|
||||
const u8 *addr = NULL;
|
||||
u64 cookie;
|
||||
int err;
|
||||
|
||||
if (wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO)
|
||||
/* Allow in AP, STA, and their P2P counterparts */
|
||||
switch (wdev->iftype) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
case NL80211_IFTYPE_P2P_GO:
|
||||
if (!info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
break;
|
||||
case NL80211_IFTYPE_STATION:
|
||||
case NL80211_IFTYPE_P2P_CLIENT:
|
||||
if (!wiphy_ext_feature_isset(&rdev->wiphy,
|
||||
NL80211_EXT_FEATURE_PROBE_AP))
|
||||
return -EOPNOTSUPP;
|
||||
if (!wdev->connected)
|
||||
return -ENOLINK;
|
||||
/* STA/P2P-client probes the currently associated AP/GO. */
|
||||
if (info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (!info->attrs[NL80211_ATTR_MAC])
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!rdev->ops->probe_peer)
|
||||
return -EOPNOTSUPP;
|
||||
@@ -16182,8 +16198,6 @@ static int nl80211_probe_peer(struct sk_buff *skb, struct genl_info *info)
|
||||
goto free_msg;
|
||||
}
|
||||
|
||||
addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
|
||||
|
||||
err = rdev_probe_peer(rdev, dev, addr, &cookie);
|
||||
if (err)
|
||||
goto free_msg;
|
||||
@@ -22597,8 +22611,8 @@ void cfg80211_sta_opmode_change_notify(struct net_device *dev, const u8 *mac,
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_sta_opmode_change_notify);
|
||||
|
||||
void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
u64 cookie, bool acked, s32 ack_signal,
|
||||
void cfg80211_probe_status(struct net_device *dev, const u8 *peer, u64 cookie,
|
||||
int link_id, bool acked, s32 ack_signal,
|
||||
bool is_valid_ack_signal, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
@@ -22606,7 +22620,7 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
struct sk_buff *msg;
|
||||
void *hdr;
|
||||
|
||||
trace_cfg80211_probe_status(dev, addr, cookie, acked);
|
||||
trace_cfg80211_probe_status(dev, peer, cookie, acked);
|
||||
|
||||
msg = nlmsg_new(NLMSG_DEFAULT_SIZE, gfp);
|
||||
|
||||
@@ -22621,12 +22635,18 @@ void cfg80211_probe_status(struct net_device *dev, const u8 *addr,
|
||||
|
||||
if (nla_put_u32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx) ||
|
||||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, dev->ifindex) ||
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
|
||||
(peer && nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, peer)) ||
|
||||
nla_put_u64_64bit(msg, NL80211_ATTR_COOKIE, cookie,
|
||||
NL80211_ATTR_PAD) ||
|
||||
(acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
|
||||
(is_valid_ack_signal && nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL,
|
||||
ack_signal)))
|
||||
NL80211_ATTR_PAD))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (link_id >= 0 &&
|
||||
nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id))
|
||||
goto nla_put_failure;
|
||||
|
||||
if ((acked && nla_put_flag(msg, NL80211_ATTR_ACK)) ||
|
||||
(is_valid_ack_signal &&
|
||||
nla_put_s32(msg, NL80211_ATTR_ACK_SIGNAL, ack_signal)))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
|
||||
Reference in New Issue
Block a user