summaryrefslogtreecommitdiff
path: root/net/mac80211/tx.c
diff options
context:
space:
mode:
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>2022-06-30 15:27:59 +0300
committerJohannes Berg <johannes.berg@intel.com>2022-07-15 12:43:19 +0300
commit67207bab9341418698ae1029b28a44b58c39257e (patch)
tree7eebc87214b192fb0d31e3c1cc043043c0198a33 /net/mac80211/tx.c
parentd2bc52498b6bafb7c2d80347b9f8fea9e3c7fc66 (diff)
downloadlinux-67207bab9341418698ae1029b28a44b58c39257e.tar.xz
wifi: cfg80211/mac80211: Support control port TX from specific link
In case of authentication with a legacy station, link addressed EAPOL frames should be sent. Support it. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/tx.c')
-rw-r--r--net/mac80211/tx.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4a7a714de79e..8f25cfe0d543 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -5674,7 +5674,7 @@ void ieee80211_tx_skb_tid(struct ieee80211_sub_if_data *sdata,
int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len,
const u8 *dest, __be16 proto, bool unencrypted,
- u64 *cookie)
+ int link_id, u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
@@ -5714,7 +5714,23 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev,
ehdr = skb_push(skb, sizeof(struct ethhdr));
memcpy(ehdr->h_dest, dest, ETH_ALEN);
- memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
+
+ if (link_id < 0) {
+ memcpy(ehdr->h_source, sdata->vif.addr, ETH_ALEN);
+ } else {
+ struct ieee80211_bss_conf *link_conf;
+
+ rcu_read_lock();
+ link_conf = rcu_dereference(sdata->vif.link_conf[link_id]);
+ if (!link_conf) {
+ dev_kfree_skb(skb);
+ rcu_read_unlock();
+ return -ENOLINK;
+ }
+ memcpy(ehdr->h_source, link_conf->addr, ETH_ALEN);
+ rcu_read_unlock();
+ }
+
ehdr->h_proto = proto;
skb->dev = dev;