Skip to content

Commit 53873f1

Browse files
committed
cfg80211: make wdev_list accessible to drivers
There's no harm in having drivers read the list, since they can use RCU protection or RTNL locking; allow this to not require each and every driver to also implement its own bookkeeping. Signed-off-by: Johannes Berg <[email protected]>
1 parent 8b9b2f0 commit 53873f1

File tree

9 files changed

+31
-24
lines changed

9 files changed

+31
-24
lines changed

include/net/cfg80211.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3189,6 +3189,9 @@ struct wiphy_vendor_command {
31893189
* @vht_capa_mod_mask: Specify what VHT capabilities can be over-ridden.
31903190
* If null, then none can be over-ridden.
31913191
*
3192+
* @wdev_list: the list of associated (virtual) interfaces; this list must
3193+
* not be modified by the driver, but can be read with RTNL/RCU protection.
3194+
*
31923195
* @max_acl_mac_addrs: Maximum number of MAC addresses that the device
31933196
* supports for ACL.
31943197
*
@@ -3328,6 +3331,8 @@ struct wiphy {
33283331
const struct ieee80211_ht_cap *ht_capa_mod_mask;
33293332
const struct ieee80211_vht_cap *vht_capa_mod_mask;
33303333

3334+
struct list_head wdev_list;
3335+
33313336
/* the network namespace this phy lives in currently */
33323337
possible_net_t _net;
33333338

net/wireless/chan.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,7 +739,7 @@ static bool cfg80211_ir_permissive_chan(struct wiphy *wiphy,
739739
* and thus fail the GO instantiation, consider only the interfaces of
740740
* the current registered device.
741741
*/
742-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
742+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
743743
struct ieee80211_channel *other_chan = NULL;
744744
int r1, r2;
745745

net/wireless/core.c

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
*
44
* Copyright 2006-2010 Johannes Berg <[email protected]>
55
* Copyright 2013-2014 Intel Mobile Communications GmbH
6+
* Copyright 2015 Intel Deutschland GmbH
67
*/
78

89
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -157,7 +158,7 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
157158
if (!(rdev->wiphy.flags & WIPHY_FLAG_NETNS_OK))
158159
return -EOPNOTSUPP;
159160

160-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
161+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
161162
if (!wdev->netdev)
162163
continue;
163164
wdev->netdev->features &= ~NETIF_F_NETNS_LOCAL;
@@ -171,7 +172,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
171172
/* failed -- clean up to old netns */
172173
net = wiphy_net(&rdev->wiphy);
173174

174-
list_for_each_entry_continue_reverse(wdev, &rdev->wdev_list,
175+
list_for_each_entry_continue_reverse(wdev,
176+
&rdev->wiphy.wdev_list,
175177
list) {
176178
if (!wdev->netdev)
177179
continue;
@@ -230,7 +232,7 @@ void cfg80211_shutdown_all_interfaces(struct wiphy *wiphy)
230232

231233
ASSERT_RTNL();
232234

233-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
235+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
234236
if (wdev->netdev) {
235237
dev_close(wdev->netdev);
236238
continue;
@@ -298,7 +300,8 @@ void cfg80211_destroy_ifaces(struct cfg80211_registered_device *rdev)
298300
kfree(item);
299301
spin_unlock_irq(&rdev->destroy_list_lock);
300302

301-
list_for_each_entry_safe(wdev, tmp, &rdev->wdev_list, list) {
303+
list_for_each_entry_safe(wdev, tmp,
304+
&rdev->wiphy.wdev_list, list) {
302305
if (nlportid == wdev->owner_nlportid)
303306
rdev_del_virtual_intf(rdev, wdev);
304307
}
@@ -410,7 +413,7 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
410413
dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx);
411414
}
412415

413-
INIT_LIST_HEAD(&rdev->wdev_list);
416+
INIT_LIST_HEAD(&rdev->wiphy.wdev_list);
414417
INIT_LIST_HEAD(&rdev->beacon_registrations);
415418
spin_lock_init(&rdev->beacon_registrations_lock);
416419
spin_lock_init(&rdev->bss_lock);
@@ -799,7 +802,7 @@ void wiphy_unregister(struct wiphy *wiphy)
799802
nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
800803
rdev->wiphy.registered = false;
801804

802-
WARN_ON(!list_empty(&rdev->wdev_list));
805+
WARN_ON(!list_empty(&rdev->wiphy.wdev_list));
803806

804807
/*
805808
* First remove the hardware from everywhere, this makes
@@ -1021,7 +1024,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
10211024
spin_lock_init(&wdev->mgmt_registrations_lock);
10221025

10231026
wdev->identifier = ++rdev->wdev_id;
1024-
list_add_rcu(&wdev->list, &rdev->wdev_list);
1027+
list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
10251028
rdev->devlist_generation++;
10261029
/* can only change netns with wiphy */
10271030
dev->features |= NETIF_F_NETNS_LOCAL;

net/wireless/core.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,7 @@ struct cfg80211_registered_device {
5050
/* wiphy index, internal only */
5151
int wiphy_idx;
5252

53-
/* associated wireless interfaces, protected by rtnl or RCU */
54-
struct list_head wdev_list;
53+
/* protected by RTNL */
5554
int devlist_generation, wdev_id;
5655
int opencount;
5756
wait_queue_head_t dev_wait;

net/wireless/nl80211.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
103103
if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
104104
continue;
105105

106-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
106+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
107107
if (have_ifidx && wdev->netdev &&
108108
wdev->netdev->ifindex == ifidx) {
109109
result = wdev;
@@ -149,7 +149,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
149149
tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
150150
if (tmp) {
151151
/* make sure wdev exists */
152-
list_for_each_entry(wdev, &tmp->wdev_list, list) {
152+
list_for_each_entry(wdev, &tmp->wiphy.wdev_list, list) {
153153
if (wdev->identifier != (u32)wdev_id)
154154
continue;
155155
found = true;
@@ -535,7 +535,7 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
535535
*rdev = wiphy_to_rdev(wiphy);
536536
*wdev = NULL;
537537

538-
list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
538+
list_for_each_entry(tmp, &(*rdev)->wiphy.wdev_list, list) {
539539
if (tmp->identifier == cb->args[1]) {
540540
*wdev = tmp;
541541
break;
@@ -2490,7 +2490,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
24902490
}
24912491
if_idx = 0;
24922492

2493-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
2493+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
24942494
if (if_idx < if_start) {
24952495
if_idx++;
24962496
continue;
@@ -2762,7 +2762,7 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
27622762
spin_lock_init(&wdev->mgmt_registrations_lock);
27632763

27642764
wdev->identifier = ++rdev->wdev_id;
2765-
list_add_rcu(&wdev->list, &rdev->wdev_list);
2765+
list_add_rcu(&wdev->list, &rdev->wiphy.wdev_list);
27662766
rdev->devlist_generation++;
27672767
break;
27682768
default:
@@ -3298,7 +3298,7 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
32983298
struct wireless_dev *wdev;
32993299
bool ret = false;
33003300

3301-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
3301+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
33023302
if (wdev->iftype != NL80211_IFTYPE_AP &&
33033303
wdev->iftype != NL80211_IFTYPE_P2P_GO)
33043304
continue;
@@ -10392,7 +10392,7 @@ static int nl80211_prepare_vendor_dump(struct sk_buff *skb,
1039210392
*wdev = NULL;
1039310393

1039410394
if (cb->args[1]) {
10395-
list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
10395+
list_for_each_entry(tmp, &wiphy->wdev_list, list) {
1039610396
if (tmp->identifier == cb->args[1] - 1) {
1039710397
*wdev = tmp;
1039810398
break;
@@ -13413,7 +13413,7 @@ static int nl80211_netlink_notify(struct notifier_block * nb,
1341313413
sched_scan_req->owner_nlportid == notify->portid)
1341413414
schedule_scan_stop = true;
1341513415

13416-
list_for_each_entry_rcu(wdev, &rdev->wdev_list, list) {
13416+
list_for_each_entry_rcu(wdev, &rdev->wiphy.wdev_list, list) {
1341713417
cfg80211_mlme_unregister_socket(wdev, notify->portid);
1341813418

1341913419
if (wdev->owner_nlportid == notify->portid)

net/wireless/reg.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1639,7 +1639,7 @@ static void reg_leave_invalid_chans(struct wiphy *wiphy)
16391639

16401640
ASSERT_RTNL();
16411641

1642-
list_for_each_entry(wdev, &rdev->wdev_list, list)
1642+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
16431643
if (!reg_wdev_chan_valid(wiphy, wdev))
16441644
cfg80211_leave(rdev, wdev);
16451645
}

net/wireless/sme.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ void cfg80211_conn_work(struct work_struct *work)
223223

224224
rtnl_lock();
225225

226-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
226+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
227227
if (!wdev->netdev)
228228
continue;
229229

@@ -617,7 +617,7 @@ static bool cfg80211_is_all_idle(void)
617617
* count as new regulatory hints.
618618
*/
619619
list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
620-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
620+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
621621
wdev_lock(wdev);
622622
if (wdev->conn || wdev->current_bss)
623623
is_all_idle = false;

net/wireless/sysfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ static void cfg80211_leave_all(struct cfg80211_registered_device *rdev)
9191
{
9292
struct wireless_dev *wdev;
9393

94-
list_for_each_entry(wdev, &rdev->wdev_list, list)
94+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
9595
cfg80211_leave(rdev, wdev);
9696
}
9797

net/wireless/util.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -986,7 +986,7 @@ void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev)
986986

987987
ASSERT_RTNL();
988988

989-
list_for_each_entry(wdev, &rdev->wdev_list, list)
989+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list)
990990
cfg80211_process_wdev_events(wdev);
991991
}
992992

@@ -1560,7 +1560,7 @@ int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
15601560
if (!beacon_int)
15611561
return -EINVAL;
15621562

1563-
list_for_each_entry(wdev, &rdev->wdev_list, list) {
1563+
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
15641564
if (!wdev->beacon_interval)
15651565
continue;
15661566
if (wdev->beacon_interval != beacon_int) {

0 commit comments

Comments
 (0)