Commit 754905ce authored by Felix Fietkau's avatar Felix Fietkau Committed by Johannes Berg
Browse files

wifi: mac80211: add support for the monitor SKIP_TX flag



Do not pass locally sent packets to monitor interfaces with this flag set.
Skip processing tx packets on the status call entirely if no monitor
interfaces without this flag are present.

Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/c327bb57ef8dadaa6a0e8e4dc2f5f99ae8123e6c.1728462320.git-series.nbd@nbd.name


Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent a77e527b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1368,7 +1368,7 @@ struct ieee80211_local {
	spinlock_t queue_stop_reason_lock;

	int open_count;
	int monitors, cooked_mntrs;
	int monitors, cooked_mntrs, tx_mntrs;
	/* number of interfaces with corresponding FIF_ flags */
	int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll,
	    fif_probe_req;
+2 −0
Original line number Diff line number Diff line
@@ -1094,6 +1094,8 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
	ADJUST(CONTROL, control);
	ADJUST(CONTROL, pspoll);
	ADJUST(OTHER_BSS, other_bss);
	if (!(flags & MONITOR_FLAG_SKIP_TX))
		local->tx_mntrs += offset;

#undef ADJUST
}
+4 −1
Original line number Diff line number Diff line
@@ -927,6 +927,9 @@ void ieee80211_tx_monitor(struct ieee80211_local *local, struct sk_buff *skb,
			if (!ieee80211_sdata_running(sdata))
				continue;

			if (sdata->u.mntr.flags & MONITOR_FLAG_SKIP_TX)
				continue;

			if ((sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES) &&
			    !send_to_cooked)
				continue;
@@ -1099,7 +1102,7 @@ static void __ieee80211_tx_status(struct ieee80211_hw *hw,
	 * This is a bit racy but we can avoid a lot of work
	 * with this test...
	 */
	if (!local->monitors && (!send_to_cooked || !local->cooked_mntrs)) {
	if (!local->tx_mntrs && (!send_to_cooked || !local->cooked_mntrs)) {
		if (status->free_list)
			list_add_tail(&skb->list, status->free_list);
		else