aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/rx.c
diff options
context:
space:
mode:
authorAndrei Otcheretianski <andrei.otcheretianski@intel.com>2022-06-30 15:37:37 +0300
committerJohannes Berg <johannes.berg@intel.com>2022-07-15 11:43:20 +0200
commitd06faef148837e39c320ed0b20a325165c6ba8d4 (patch)
tree7e98501ef55856a902d092ac1103160c0d101a71 /net/mac80211/rx.c
parentwifi: cfg80211/mac80211: Support control port TX from specific link (diff)
downloadlinux-dev-d06faef148837e39c320ed0b20a325165c6ba8d4.tar.xz
linux-dev-d06faef148837e39c320ed0b20a325165c6ba8d4.zip
wifi: mac80211: Allow EAPOL frames from link addresses
Allow transmitting EAPOL frames not only from the interface address (which is the MLD address) but also any link addresses, in order to support non-MLO stations on AP interfaces. Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/rx.c')
-rw-r--r--net/mac80211/rx.c60
1 files changed, 30 insertions, 30 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index c70156e49d0d..1c798c11648e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2532,6 +2532,35 @@ __ieee80211_data_to_8023(struct ieee80211_rx_data *rx, bool *port_control)
return 0;
}
+static bool ieee80211_is_our_addr(struct ieee80211_sub_if_data *sdata,
+ const u8 *addr, int *out_link_id)
+{
+ unsigned int link_id;
+
+ /* non-MLO, or MLD address replaced by hardware */
+ if (ether_addr_equal(sdata->vif.addr, addr))
+ return true;
+
+ if (!sdata->vif.valid_links)
+ return false;
+
+ for (link_id = 0; link_id < ARRAY_SIZE(sdata->vif.link_conf); link_id++) {
+ struct ieee80211_bss_conf *conf;
+
+ conf = rcu_dereference(sdata->vif.link_conf[link_id]);
+
+ if (!conf)
+ continue;
+ if (ether_addr_equal(conf->addr, addr)) {
+ if (out_link_id)
+ *out_link_id = link_id;
+ return true;
+ }
+ }
+
+ return false;
+}
+
/*
* requires that rx->skb is a frame with ethernet header
*/
@@ -2547,7 +2576,7 @@ static bool ieee80211_frame_allowed(struct ieee80211_rx_data *rx, __le16 fc)
* all other destination addresses for them.
*/
if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol))
- return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) ||
+ return ieee80211_is_our_addr(rx->sdata, ehdr->h_dest, NULL) ||
ether_addr_equal(ehdr->h_dest, pae_group_addr);
if (ieee80211_802_1x_port_control(rx) ||
@@ -4143,35 +4172,6 @@ static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
is_broadcast_ether_addr(raddr);
}
-static bool ieee80211_is_our_addr(struct ieee80211_sub_if_data *sdata,
- const u8 *addr, int *out_link_id)
-{
- unsigned int link_id;
-
- /* non-MLO, or MLD address replaced by hardware */
- if (ether_addr_equal(sdata->vif.addr, addr))
- return true;
-
- if (!sdata->vif.valid_links)
- return false;
-
- for (link_id = 0; link_id < ARRAY_SIZE(sdata->vif.link_conf); link_id++) {
- struct ieee80211_bss_conf *conf;
-
- conf = rcu_dereference(sdata->vif.link_conf[link_id]);
-
- if (!conf)
- continue;
- if (ether_addr_equal(conf->addr, addr)) {
- if (out_link_id)
- *out_link_id = link_id;
- return true;
- }
- }
-
- return false;
-}
-
static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx)
{
struct ieee80211_sub_if_data *sdata = rx->sdata;