From: Benjamin Berg For MLD stations, userspace may need to explicitly transmit a frame to a specific link address. In that case, it needs to ensure that no address translation happens. In the reverse case of an RX, userspace may need to know the link address for a frame. By passing the information whether a STA is known for the frame, userspace knows whether link translation happened and can do the reverse lookup when needed. This is important for flows where a STA is still registered but the connection has been lost and it is returning again. Signed-off-by: Benjamin Berg --- include/net/cfg80211.h | 4 ++++ include/uapi/linux/nl80211.h | 7 +++++++ net/wireless/nl80211.c | 8 +++++++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index fc01de19c798..5063911cba56 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -3919,6 +3919,7 @@ struct cfg80211_update_ft_ies_params { * @link_id: for MLO, the link ID to transmit on, -1 if not given; note * that the link ID isn't validated (much), it's in range but the * link might not exist (or be used by the receiver STA) + * @no_sta: set if the frame should not be transmitted using an existing STA */ struct cfg80211_mgmt_tx_params { struct ieee80211_channel *chan; @@ -3931,6 +3932,7 @@ struct cfg80211_mgmt_tx_params { int n_csa_offsets; const u16 *csa_offsets; int link_id; + bool no_sta; }; /** @@ -9025,6 +9027,7 @@ void cfg80211_conn_failed(struct net_device *dev, const u8 *mac_addr, * @flags: flags, as defined in &enum nl80211_rxmgmt_flags * @rx_tstamp: Hardware timestamp of frame RX in nanoseconds * @ack_tstamp: Hardware timestamp of ack TX in nanoseconds + * @no_sta: set if no station is known for the frame (relevant for MLD) */ struct cfg80211_rx_info { int freq; @@ -9036,6 +9039,7 @@ struct cfg80211_rx_info { u32 flags; u64 rx_tstamp; u64 ack_tstamp; + bool no_sta; }; /** diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h index b63f71850906..1466c043974c 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -2984,6 +2984,11 @@ enum nl80211_commands { * this feature during association. This is a flag attribute. * Currently only supported in mac80211 drivers. * + * @NL80211_ATTR_FRAME_CMD_NO_STA: Valid for NL80211_CMD_FRAME to denote that + * the kernel had no station for a received frame or should not use a + * known station to transmit a frame. This is relevant to know whether + * MLD address translation happened or to disable it when sending a frame. + * * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use @@ -3557,6 +3562,8 @@ enum nl80211_attrs { NL80211_ATTR_UHR_CAPABILITY, NL80211_ATTR_DISABLE_UHR, + NL80211_ATTR_FRAME_CMD_NO_STA, + /* add attributes here, update the policy in nl80211.c */ __NL80211_ATTR_AFTER_LAST, diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 6e58b238a1f8..56a9c63ddd76 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -946,6 +946,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_UHR_CAPABILITY] = NLA_POLICY_VALIDATE_FN(NLA_BINARY, validate_uhr_capa, 255), [NL80211_ATTR_DISABLE_UHR] = { .type = NLA_FLAG }, + [NL80211_ATTR_FRAME_CMD_NO_STA] = { .type = NLA_FLAG }, }; /* policy for the key attributes */ @@ -14020,6 +14021,9 @@ static int nl80211_tx_mgmt(struct sk_buff *skb, struct genl_info *info) !(wdev->valid_links & BIT(params.link_id))) return -EINVAL; + params.no_sta = + nla_get_flag(info->attrs[NL80211_ATTR_FRAME_CMD_NO_STA]); + params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); @@ -20581,7 +20585,9 @@ int nl80211_send_mgmt(struct cfg80211_registered_device *rdev, (info->ack_tstamp && nla_put_u64_64bit(msg, NL80211_ATTR_TX_HW_TIMESTAMP, info->ack_tstamp, - NL80211_ATTR_PAD))) + NL80211_ATTR_PAD)) || + (info->no_sta && + nla_put_flag(msg, NL80211_ATTR_FRAME_CMD_NO_STA))) goto nla_put_failure; genlmsg_end(msg, hdr); -- 2.53.0