Commit f64331d5 authored by Johannes Berg's avatar Johannes Berg

mac80211: keep a separate list of monitor interfaces that are up

In addition to keeping monitor interfaces on the regular list of
interfaces, keep those that are up and not in cooked mode on a
separate list. This saves having to iterate all interfaces when
delivering to monitor interfaces.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 96b08fd6
...@@ -839,6 +839,8 @@ struct txq_info { ...@@ -839,6 +839,8 @@ struct txq_info {
struct ieee80211_if_mntr { struct ieee80211_if_mntr {
u32 flags; u32 flags;
u8 mu_follow_addr[ETH_ALEN] __aligned(2); u8 mu_follow_addr[ETH_ALEN] __aligned(2);
struct list_head list;
}; };
/** /**
...@@ -1259,6 +1261,7 @@ struct ieee80211_local { ...@@ -1259,6 +1261,7 @@ struct ieee80211_local {
/* see iface.c */ /* see iface.c */
struct list_head interfaces; struct list_head interfaces;
struct list_head mon_list; /* only that are IFF_UP && !cooked */
struct mutex iflist_mtx; struct mutex iflist_mtx;
/* /*
......
...@@ -676,7 +676,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) ...@@ -676,7 +676,8 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
set_bit(SDATA_STATE_RUNNING, &sdata->state); set_bit(SDATA_STATE_RUNNING, &sdata->state);
if (sdata->vif.type == NL80211_IFTYPE_WDS) { switch (sdata->vif.type) {
case NL80211_IFTYPE_WDS:
/* Create STA entry for the WDS peer */ /* Create STA entry for the WDS peer */
sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr, sta = sta_info_alloc(sdata, sdata->u.wds.remote_addr,
GFP_KERNEL); GFP_KERNEL);
...@@ -697,8 +698,17 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) ...@@ -697,8 +698,17 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
rate_control_rate_init(sta); rate_control_rate_init(sta);
netif_carrier_on(dev); netif_carrier_on(dev);
} else if (sdata->vif.type == NL80211_IFTYPE_P2P_DEVICE) { break;
case NL80211_IFTYPE_P2P_DEVICE:
rcu_assign_pointer(local->p2p_sdata, sdata); rcu_assign_pointer(local->p2p_sdata, sdata);
break;
case NL80211_IFTYPE_MONITOR:
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
break;
list_add_tail_rcu(&sdata->u.mntr.list, &local->mon_list);
break;
default:
break;
} }
/* /*
...@@ -816,6 +826,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, ...@@ -816,6 +826,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
case NL80211_IFTYPE_AP: case NL80211_IFTYPE_AP:
cancel_work_sync(&sdata->u.ap.request_smps_work); cancel_work_sync(&sdata->u.ap.request_smps_work);
break; break;
case NL80211_IFTYPE_MONITOR:
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
break;
list_del_rcu(&sdata->u.mntr.list);
break;
default: default:
break; break;
} }
......
...@@ -603,6 +603,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len, ...@@ -603,6 +603,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t priv_data_len,
ARRAY_SIZE(local->ext_capa); ARRAY_SIZE(local->ext_capa);
INIT_LIST_HEAD(&local->interfaces); INIT_LIST_HEAD(&local->interfaces);
INIT_LIST_HEAD(&local->mon_list);
__hw_addr_init(&local->mc_list); __hw_addr_init(&local->mc_list);
......
...@@ -593,16 +593,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, ...@@ -593,16 +593,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb,
skb->pkt_type = PACKET_OTHERHOST; skb->pkt_type = PACKET_OTHERHOST;
skb->protocol = htons(ETH_P_802_2); skb->protocol = htons(ETH_P_802_2);
list_for_each_entry_rcu(sdata, &local->interfaces, list) { list_for_each_entry_rcu(sdata, &local->mon_list, u.mntr.list) {
if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
continue;
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
continue;
if (!ieee80211_sdata_running(sdata))
continue;
if (prev_dev) { if (prev_dev) {
skb2 = skb_clone(skb, GFP_ATOMIC); skb2 = skb_clone(skb, GFP_ATOMIC);
if (skb2) { if (skb2) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment