diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 6461a7bd0169..9aa7d2d4a184 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -4009,6 +4009,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; @@ -4021,6 +4022,7 @@ struct cfg80211_mgmt_tx_params { int n_csa_offsets; const u16 *csa_offsets; int link_id; + bool no_sta; }; /** @@ -9501,6 +9503,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; @@ -9512,6 +9515,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 32553cacf988..510102febc26 100644 --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h @@ -3185,6 +3185,11 @@ enum nl80211_commands { * The aggregated message always precedes the per-link messages for the * same station within a dump sequence. * + * @NL80211_ATTR_FRAME_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 @@ -3785,6 +3790,8 @@ enum nl80211_attrs { NL80211_ATTR_STA_DUMP_LINK_STATS, + NL80211_ATTR_FRAME_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 b081eeaf7016..e77a4c81d031 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -1097,6 +1097,7 @@ static const struct nla_policy nl80211_policy[NUM_NL80211_ATTR] = { [NL80211_ATTR_NPCA_PUNCT_BITMAP] = NLA_POLICY_FULL_RANGE(NLA_U32, &nl80211_punct_bitmap_range), [NL80211_ATTR_STA_DUMP_LINK_STATS] = { .type = NLA_FLAG }, + [NL80211_ATTR_FRAME_NO_STA] = { .type = NLA_FLAG }, }; /* policy for the key attributes */ @@ -14873,6 +14874,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_NO_STA]); + params.buf = nla_data(info->attrs[NL80211_ATTR_FRAME]); params.len = nla_len(info->attrs[NL80211_ATTR_FRAME]); @@ -22042,7 +22046,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_NO_STA))) goto nla_put_failure; genlmsg_end(msg, hdr);