mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 12:21:22 -05:00
wifi: cfg80211/mac80211: report link ID for unexpected frames
The upper layer may require the link ID to properly handle unexpected frames. For instance, if hostapd, operating as an AP MLD, receives a data frame from a non-associated STA, it must send deauthentication to the link on which the STA is operating. Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com> Reviewed-by: Money Wang <money.wang@mediatek.com> Link: https://patch.msgid.link/20250721065159.1740992-1-michael-cy.lee@mediatek.com [edit commit message] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
committed by
Johannes Berg
parent
4970e393eb
commit
84b62b72b4
@@ -9048,6 +9048,7 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
|
||||
/**
|
||||
* cfg80211_rx_spurious_frame - inform userspace about a spurious frame
|
||||
* @dev: The device the frame matched to
|
||||
* @link_id: the link the frame was received on, -1 if not applicable or unknown
|
||||
* @addr: the transmitter address
|
||||
* @gfp: context flags
|
||||
*
|
||||
@@ -9057,13 +9058,14 @@ void cfg80211_pmksa_candidate_notify(struct net_device *dev, int index,
|
||||
* Return: %true if the frame was passed to userspace (or this failed
|
||||
* for a reason other than not having a subscription.)
|
||||
*/
|
||||
bool cfg80211_rx_spurious_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
bool cfg80211_rx_spurious_frame(struct net_device *dev, const u8 *addr,
|
||||
int link_id, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_rx_unexpected_4addr_frame - inform about unexpected WDS frame
|
||||
* @dev: The device the frame matched to
|
||||
* @addr: the transmitter address
|
||||
* @link_id: the link the frame was received on, -1 if not applicable or unknown
|
||||
* @gfp: context flags
|
||||
*
|
||||
* This function is used in AP mode (only!) to inform userspace that
|
||||
@@ -9073,8 +9075,8 @@ bool cfg80211_rx_spurious_frame(struct net_device *dev,
|
||||
* Return: %true if the frame was passed to userspace (or this failed
|
||||
* for a reason other than not having a subscription.)
|
||||
*/
|
||||
bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp);
|
||||
bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, const u8 *addr,
|
||||
int link_id, gfp_t gfp);
|
||||
|
||||
/**
|
||||
* cfg80211_probe_status - notify userspace about probe status
|
||||
|
||||
@@ -1532,9 +1532,8 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx)
|
||||
}
|
||||
|
||||
if (rx->sdata->vif.type == NL80211_IFTYPE_AP &&
|
||||
cfg80211_rx_spurious_frame(rx->sdata->dev,
|
||||
hdr->addr2,
|
||||
GFP_ATOMIC))
|
||||
cfg80211_rx_spurious_frame(rx->sdata->dev, hdr->addr2,
|
||||
rx->link_id, GFP_ATOMIC))
|
||||
return RX_DROP_U_SPURIOUS;
|
||||
|
||||
return RX_DROP;
|
||||
@@ -1872,7 +1871,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
|
||||
if (!test_and_set_sta_flag(sta, WLAN_STA_4ADDR_EVENT))
|
||||
cfg80211_rx_unexpected_4addr_frame(
|
||||
rx->sdata->dev, sta->sta.addr,
|
||||
GFP_ATOMIC);
|
||||
rx->link_id, GFP_ATOMIC);
|
||||
return RX_DROP_U_UNEXPECTED_4ADDR_FRAME;
|
||||
}
|
||||
/*
|
||||
@@ -3191,7 +3190,8 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx)
|
||||
if (rx->sta &&
|
||||
!test_and_set_sta_flag(rx->sta, WLAN_STA_4ADDR_EVENT))
|
||||
cfg80211_rx_unexpected_4addr_frame(
|
||||
rx->sdata->dev, rx->sta->sta.addr, GFP_ATOMIC);
|
||||
rx->sdata->dev, rx->sta->sta.addr, rx->link_id,
|
||||
GFP_ATOMIC);
|
||||
return RX_DROP;
|
||||
}
|
||||
|
||||
|
||||
@@ -19755,7 +19755,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr,
|
||||
EXPORT_SYMBOL(cfg80211_conn_failed);
|
||||
|
||||
static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
|
||||
const u8 *addr, gfp_t gfp)
|
||||
const u8 *addr, int link_id, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
|
||||
@@ -19778,7 +19778,9 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
|
||||
|
||||
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))
|
||||
nla_put(msg, NL80211_ATTR_MAC, ETH_ALEN, addr) ||
|
||||
(link_id >= 0 &&
|
||||
nla_put_u8(msg, NL80211_ATTR_MLO_LINK_ID, link_id)))
|
||||
goto nla_put_failure;
|
||||
|
||||
genlmsg_end(msg, hdr);
|
||||
@@ -19790,13 +19792,13 @@ static bool __nl80211_unexpected_frame(struct net_device *dev, u8 cmd,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool cfg80211_rx_spurious_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp)
|
||||
bool cfg80211_rx_spurious_frame(struct net_device *dev, const u8 *addr,
|
||||
int link_id, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
bool ret;
|
||||
|
||||
trace_cfg80211_rx_spurious_frame(dev, addr);
|
||||
trace_cfg80211_rx_spurious_frame(dev, addr, link_id);
|
||||
|
||||
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO)) {
|
||||
@@ -19804,19 +19806,19 @@ bool cfg80211_rx_spurious_frame(struct net_device *dev,
|
||||
return false;
|
||||
}
|
||||
ret = __nl80211_unexpected_frame(dev, NL80211_CMD_UNEXPECTED_FRAME,
|
||||
addr, gfp);
|
||||
addr, link_id, gfp);
|
||||
trace_cfg80211_return_bool(ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(cfg80211_rx_spurious_frame);
|
||||
|
||||
bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
|
||||
const u8 *addr, gfp_t gfp)
|
||||
bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev, const u8 *addr,
|
||||
int link_id, gfp_t gfp)
|
||||
{
|
||||
struct wireless_dev *wdev = dev->ieee80211_ptr;
|
||||
bool ret;
|
||||
|
||||
trace_cfg80211_rx_unexpected_4addr_frame(dev, addr);
|
||||
trace_cfg80211_rx_unexpected_4addr_frame(dev, addr, link_id);
|
||||
|
||||
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
|
||||
wdev->iftype != NL80211_IFTYPE_P2P_GO &&
|
||||
@@ -19826,7 +19828,7 @@ bool cfg80211_rx_unexpected_4addr_frame(struct net_device *dev,
|
||||
}
|
||||
ret = __nl80211_unexpected_frame(dev,
|
||||
NL80211_CMD_UNEXPECTED_4ADDR_FRAME,
|
||||
addr, gfp);
|
||||
addr, link_id, gfp);
|
||||
trace_cfg80211_return_bool(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -3570,27 +3570,30 @@ TRACE_EVENT(cfg80211_cac_event,
|
||||
);
|
||||
|
||||
DECLARE_EVENT_CLASS(cfg80211_rx_evt,
|
||||
TP_PROTO(struct net_device *netdev, const u8 *addr),
|
||||
TP_ARGS(netdev, addr),
|
||||
TP_PROTO(struct net_device *netdev, const u8 *addr, int link_id),
|
||||
TP_ARGS(netdev, addr, link_id),
|
||||
TP_STRUCT__entry(
|
||||
NETDEV_ENTRY
|
||||
MAC_ENTRY(addr)
|
||||
__field(int, link_id)
|
||||
),
|
||||
TP_fast_assign(
|
||||
NETDEV_ASSIGN;
|
||||
MAC_ASSIGN(addr, addr);
|
||||
__entry->link_id = link_id;
|
||||
),
|
||||
TP_printk(NETDEV_PR_FMT ", %pM", NETDEV_PR_ARG, __entry->addr)
|
||||
TP_printk(NETDEV_PR_FMT ", %pM, link_id:%d", NETDEV_PR_ARG,
|
||||
__entry->addr, __entry->link_id)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_spurious_frame,
|
||||
TP_PROTO(struct net_device *netdev, const u8 *addr),
|
||||
TP_ARGS(netdev, addr)
|
||||
TP_PROTO(struct net_device *netdev, const u8 *addr, int link_id),
|
||||
TP_ARGS(netdev, addr, link_id)
|
||||
);
|
||||
|
||||
DEFINE_EVENT(cfg80211_rx_evt, cfg80211_rx_unexpected_4addr_frame,
|
||||
TP_PROTO(struct net_device *netdev, const u8 *addr),
|
||||
TP_ARGS(netdev, addr)
|
||||
TP_PROTO(struct net_device *netdev, const u8 *addr, int link_id),
|
||||
TP_ARGS(netdev, addr, link_id)
|
||||
);
|
||||
|
||||
TRACE_EVENT(cfg80211_ibss_joined,
|
||||
|
||||
Reference in New Issue
Block a user