wifi: mac80211: refactor ieee80211_rx_monitor

Rework the monitor mode interface iteration to get rid of the last_monitor
condition. Preparation for further filtering received monitor packets.

Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/d57d82f109643894325beb9db6da8f001fc533eb.1728462320.git-series.nbd@nbd.name
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
Felix Fietkau 2024-10-09 10:25:51 +02:00 committed by Johannes Berg
parent 754905ce1a
commit 342afe693e

View File

@ -762,8 +762,8 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
struct ieee80211_rate *rate)
{
struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(origskb);
struct ieee80211_sub_if_data *sdata;
struct sk_buff *monskb = NULL;
struct ieee80211_sub_if_data *sdata, *prev_sdata = NULL;
struct sk_buff *skb, *monskb = NULL;
int present_fcs_len = 0;
unsigned int rtap_space = 0;
struct ieee80211_sub_if_data *monitor_sdata =
@ -837,8 +837,10 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
ieee80211_handle_mu_mimo_mon(monitor_sdata, origskb, rtap_space);
list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) {
bool last_monitor = list_is_last(&sdata->u.mntr.list,
&local->mon_list);
if (!prev_sdata) {
prev_sdata = sdata;
continue;
}
if (ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR))
ieee80211_handle_mu_mimo_mon(sdata, origskb, rtap_space);
@ -846,34 +848,34 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
if (!monskb)
monskb = ieee80211_make_monitor_skb(local, &origskb,
rate, rtap_space,
only_monitor &&
last_monitor);
false);
if (!monskb)
continue;
if (monskb) {
struct sk_buff *skb;
skb = skb_clone(monskb, GFP_ATOMIC);
if (!skb)
continue;
if (last_monitor) {
skb = monskb;
monskb = NULL;
} else {
skb = skb_clone(monskb, GFP_ATOMIC);
}
if (skb) {
skb->dev = sdata->dev;
dev_sw_netstats_rx_add(skb->dev, skb->len);
netif_receive_skb(skb);
}
}
if (last_monitor)
break;
skb->dev = prev_sdata->dev;
dev_sw_netstats_rx_add(skb->dev, skb->len);
netif_receive_skb(skb);
prev_sdata = sdata;
}
/* this happens if last_monitor was erroneously false */
dev_kfree_skb(monskb);
if (prev_sdata) {
if (monskb)
skb = monskb;
else
skb = ieee80211_make_monitor_skb(local, &origskb,
rate, rtap_space,
only_monitor);
if (skb) {
skb->dev = prev_sdata->dev;
dev_sw_netstats_rx_add(skb->dev, skb->len);
netif_receive_skb(skb);
}
}
/* ditto */
if (!origskb)
return NULL;