diff options
author | Felix Fietkau <nbd@nbd.name> | 2024-10-09 10:25:51 +0200 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2024-10-23 16:46:26 +0200 |
commit | 342afe693ee765a215343fe1a1af0d6c8b8e10a3 (patch) | |
tree | e8eb00282719510946bdbdb6c91307e8a801fbe1 /net/mac80211 | |
parent | 754905ce1a327ee3297548e132367038cc62b3d8 (diff) | |
download | lwn-342afe693ee765a215343fe1a1af0d6c8b8e10a3.tar.gz lwn-342afe693ee765a215343fe1a1af0d6c8b8e10a3.zip |
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>
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/rx.c | 54 |
1 files changed, 28 insertions, 26 deletions
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index d032bfb00ade..4849af232ee6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -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); - } + skb->dev = prev_sdata->dev; + dev_sw_netstats_rx_add(skb->dev, skb->len); + netif_receive_skb(skb); + prev_sdata = sdata; + } - if (skb) { - skb->dev = sdata->dev; - dev_sw_netstats_rx_add(skb->dev, skb->len); - netif_receive_skb(skb); - } + 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); } - - if (last_monitor) - break; } - /* this happens if last_monitor was erroneously false */ - dev_kfree_skb(monskb); - - /* ditto */ if (!origskb) return NULL; |