1 // SPDX-License-Identifier: GPL-2.0
2 /* drivers/net/wireless/virt_wifi.c
4 * A fake implementation of cfg80211_ops that can be tacked on to an ethernet
5 * net_device to make it appear as a wireless connection.
7 * Copyright (C) 2018 Google, Inc.
9 * Author: schuffelen@google.com
12 #include <net/cfg80211.h>
13 #include <net/rtnetlink.h>
14 #include <linux/etherdevice.h>
15 #include <linux/module.h>
17 static struct wiphy
*common_wiphy
;
19 struct virt_wifi_wiphy_priv
{
20 struct delayed_work scan_result
;
21 struct cfg80211_scan_request
*scan_request
;
25 static struct ieee80211_channel channel_2ghz
= {
26 .band
= NL80211_BAND_2GHZ
,
32 static struct ieee80211_rate bitrates_2ghz
[] = {
42 static struct ieee80211_supported_band band_2ghz
= {
43 .channels
= &channel_2ghz
,
44 .bitrates
= bitrates_2ghz
,
45 .band
= NL80211_BAND_2GHZ
,
47 .n_bitrates
= ARRAY_SIZE(bitrates_2ghz
),
50 .cap
= IEEE80211_HT_CAP_SUP_WIDTH_20_40
|
51 IEEE80211_HT_CAP_GRN_FLD
|
52 IEEE80211_HT_CAP_SGI_20
|
53 IEEE80211_HT_CAP_SGI_40
|
54 IEEE80211_HT_CAP_DSSSCCK40
,
58 .rx_mask
= {0xff, 0xff},
59 .tx_params
= IEEE80211_HT_MCS_TX_DEFINED
,
64 static struct ieee80211_channel channel_5ghz
= {
65 .band
= NL80211_BAND_5GHZ
,
71 static struct ieee80211_rate bitrates_5ghz
[] = {
77 #define RX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \
78 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \
79 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \
80 IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \
81 IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \
82 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \
83 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \
84 IEEE80211_VHT_MCS_SUPPORT_0_9 << 14)
86 #define TX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \
87 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \
88 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \
89 IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \
90 IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \
91 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \
92 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \
93 IEEE80211_VHT_MCS_SUPPORT_0_9 << 14)
95 static struct ieee80211_supported_band band_5ghz
= {
96 .channels
= &channel_5ghz
,
97 .bitrates
= bitrates_5ghz
,
98 .band
= NL80211_BAND_5GHZ
,
100 .n_bitrates
= ARRAY_SIZE(bitrates_5ghz
),
102 .ht_supported
= true,
103 .cap
= IEEE80211_HT_CAP_SUP_WIDTH_20_40
|
104 IEEE80211_HT_CAP_GRN_FLD
|
105 IEEE80211_HT_CAP_SGI_20
|
106 IEEE80211_HT_CAP_SGI_40
|
107 IEEE80211_HT_CAP_DSSSCCK40
,
109 .ampdu_density
= 0x6,
111 .rx_mask
= {0xff, 0xff},
112 .tx_params
= IEEE80211_HT_MCS_TX_DEFINED
,
116 .vht_supported
= true,
117 .cap
= IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454
|
118 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ
|
119 IEEE80211_VHT_CAP_RXLDPC
|
120 IEEE80211_VHT_CAP_SHORT_GI_80
|
121 IEEE80211_VHT_CAP_SHORT_GI_160
|
122 IEEE80211_VHT_CAP_TXSTBC
|
123 IEEE80211_VHT_CAP_RXSTBC_1
|
124 IEEE80211_VHT_CAP_RXSTBC_2
|
125 IEEE80211_VHT_CAP_RXSTBC_3
|
126 IEEE80211_VHT_CAP_RXSTBC_4
|
127 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK
,
129 .rx_mcs_map
= cpu_to_le16(RX_MCS_MAP
),
130 .tx_mcs_map
= cpu_to_le16(TX_MCS_MAP
),
135 /* Assigned at module init. Guaranteed locally-administered and unicast. */
136 static u8 fake_router_bssid
[ETH_ALEN
] __ro_after_init
= {};
138 /* Called with the rtnl lock held. */
139 static int virt_wifi_scan(struct wiphy
*wiphy
,
140 struct cfg80211_scan_request
*request
)
142 struct virt_wifi_wiphy_priv
*priv
= wiphy_priv(wiphy
);
144 wiphy_debug(wiphy
, "scan\n");
146 if (priv
->scan_request
|| priv
->being_deleted
)
149 priv
->scan_request
= request
;
150 schedule_delayed_work(&priv
->scan_result
, HZ
* 2);
155 /* Acquires and releases the rdev BSS lock. */
156 static void virt_wifi_scan_result(struct work_struct
*work
)
163 .tag
= WLAN_EID_SSID
, .len
= 8, .ssid
= "VirtWifi",
165 struct cfg80211_bss
*informed_bss
;
166 struct virt_wifi_wiphy_priv
*priv
=
167 container_of(work
, struct virt_wifi_wiphy_priv
,
169 struct wiphy
*wiphy
= priv_to_wiphy(priv
);
170 struct cfg80211_scan_info scan_info
= { .aborted
= false };
172 informed_bss
= cfg80211_inform_bss(wiphy
, &channel_5ghz
,
173 CFG80211_BSS_FTYPE_PRESP
,
175 ktime_get_boottime_ns(),
176 WLAN_CAPABILITY_ESS
, 0,
177 (void *)&ssid
, sizeof(ssid
),
178 DBM_TO_MBM(-50), GFP_KERNEL
);
179 cfg80211_put_bss(wiphy
, informed_bss
);
181 /* Schedules work which acquires and releases the rtnl lock. */
182 cfg80211_scan_done(priv
->scan_request
, &scan_info
);
183 priv
->scan_request
= NULL
;
186 /* May acquire and release the rdev BSS lock. */
187 static void virt_wifi_cancel_scan(struct wiphy
*wiphy
)
189 struct virt_wifi_wiphy_priv
*priv
= wiphy_priv(wiphy
);
191 cancel_delayed_work_sync(&priv
->scan_result
);
192 /* Clean up dangling callbacks if necessary. */
193 if (priv
->scan_request
) {
194 struct cfg80211_scan_info scan_info
= { .aborted
= true };
195 /* Schedules work which acquires and releases the rtnl lock. */
196 cfg80211_scan_done(priv
->scan_request
, &scan_info
);
197 priv
->scan_request
= NULL
;
201 struct virt_wifi_netdev_priv
{
202 struct delayed_work connect
;
203 struct net_device
*lowerdev
;
204 struct net_device
*upperdev
;
207 u8 connect_requested_bss
[ETH_ALEN
];
213 /* Called with the rtnl lock held. */
214 static int virt_wifi_connect(struct wiphy
*wiphy
, struct net_device
*netdev
,
215 struct cfg80211_connect_params
*sme
)
217 struct virt_wifi_netdev_priv
*priv
= netdev_priv(netdev
);
220 if (priv
->being_deleted
|| !priv
->is_up
)
223 could_schedule
= schedule_delayed_work(&priv
->connect
, HZ
* 2);
228 ether_addr_copy(priv
->connect_requested_bss
, sme
->bssid
);
230 eth_zero_addr(priv
->connect_requested_bss
);
232 wiphy_debug(wiphy
, "connect\n");
237 /* Acquires and releases the rdev event lock. */
238 static void virt_wifi_connect_complete(struct work_struct
*work
)
240 struct virt_wifi_netdev_priv
*priv
=
241 container_of(work
, struct virt_wifi_netdev_priv
, connect
.work
);
242 u8
*requested_bss
= priv
->connect_requested_bss
;
243 bool has_addr
= !is_zero_ether_addr(requested_bss
);
244 bool right_addr
= ether_addr_equal(requested_bss
, fake_router_bssid
);
245 u16 status
= WLAN_STATUS_SUCCESS
;
247 if (!priv
->is_up
|| (has_addr
&& !right_addr
))
248 status
= WLAN_STATUS_UNSPECIFIED_FAILURE
;
250 priv
->is_connected
= true;
252 /* Schedules an event that acquires the rtnl lock. */
253 cfg80211_connect_result(priv
->upperdev
, requested_bss
, NULL
, 0, NULL
, 0,
255 netif_carrier_on(priv
->upperdev
);
258 /* May acquire and release the rdev event lock. */
259 static void virt_wifi_cancel_connect(struct net_device
*netdev
)
261 struct virt_wifi_netdev_priv
*priv
= netdev_priv(netdev
);
263 /* If there is work pending, clean up dangling callbacks. */
264 if (cancel_delayed_work_sync(&priv
->connect
)) {
265 /* Schedules an event that acquires the rtnl lock. */
266 cfg80211_connect_result(priv
->upperdev
,
267 priv
->connect_requested_bss
, NULL
, 0,
269 WLAN_STATUS_UNSPECIFIED_FAILURE
,
274 /* Called with the rtnl lock held. Acquires the rdev event lock. */
275 static int virt_wifi_disconnect(struct wiphy
*wiphy
, struct net_device
*netdev
,
278 struct virt_wifi_netdev_priv
*priv
= netdev_priv(netdev
);
280 if (priv
->being_deleted
)
283 wiphy_debug(wiphy
, "disconnect\n");
284 virt_wifi_cancel_connect(netdev
);
286 cfg80211_disconnected(netdev
, reason_code
, NULL
, 0, true, GFP_KERNEL
);
287 priv
->is_connected
= false;
288 netif_carrier_off(netdev
);
293 /* Called with the rtnl lock held. */
294 static int virt_wifi_get_station(struct wiphy
*wiphy
, struct net_device
*dev
,
295 const u8
*mac
, struct station_info
*sinfo
)
297 struct virt_wifi_netdev_priv
*priv
= netdev_priv(dev
);
299 wiphy_debug(wiphy
, "get_station\n");
301 if (!priv
->is_connected
|| !ether_addr_equal(mac
, fake_router_bssid
))
304 sinfo
->filled
= BIT_ULL(NL80211_STA_INFO_TX_PACKETS
) |
305 BIT_ULL(NL80211_STA_INFO_TX_FAILED
) |
306 BIT_ULL(NL80211_STA_INFO_SIGNAL
) |
307 BIT_ULL(NL80211_STA_INFO_TX_BITRATE
);
308 sinfo
->tx_packets
= priv
->tx_packets
;
309 sinfo
->tx_failed
= priv
->tx_failed
;
310 /* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_ */
312 sinfo
->txrate
= (struct rate_info
) {
313 .legacy
= 10, /* units are 100kbit/s */
318 /* Called with the rtnl lock held. */
319 static int virt_wifi_dump_station(struct wiphy
*wiphy
, struct net_device
*dev
,
320 int idx
, u8
*mac
, struct station_info
*sinfo
)
322 struct virt_wifi_netdev_priv
*priv
= netdev_priv(dev
);
324 wiphy_debug(wiphy
, "dump_station\n");
326 if (idx
!= 0 || !priv
->is_connected
)
329 ether_addr_copy(mac
, fake_router_bssid
);
330 return virt_wifi_get_station(wiphy
, dev
, fake_router_bssid
, sinfo
);
333 static const struct cfg80211_ops virt_wifi_cfg80211_ops
= {
334 .scan
= virt_wifi_scan
,
336 .connect
= virt_wifi_connect
,
337 .disconnect
= virt_wifi_disconnect
,
339 .get_station
= virt_wifi_get_station
,
340 .dump_station
= virt_wifi_dump_station
,
343 /* Acquires and releases the rtnl lock. */
344 static struct wiphy
*virt_wifi_make_wiphy(void)
347 struct virt_wifi_wiphy_priv
*priv
;
350 wiphy
= wiphy_new(&virt_wifi_cfg80211_ops
, sizeof(*priv
));
355 wiphy
->max_scan_ssids
= 4;
356 wiphy
->max_scan_ie_len
= 1000;
357 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
359 wiphy
->bands
[NL80211_BAND_2GHZ
] = &band_2ghz
;
360 wiphy
->bands
[NL80211_BAND_5GHZ
] = &band_5ghz
;
361 wiphy
->bands
[NL80211_BAND_60GHZ
] = NULL
;
363 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
);
365 priv
= wiphy_priv(wiphy
);
366 priv
->being_deleted
= false;
367 priv
->scan_request
= NULL
;
368 INIT_DELAYED_WORK(&priv
->scan_result
, virt_wifi_scan_result
);
370 err
= wiphy_register(wiphy
);
379 /* Acquires and releases the rtnl lock. */
380 static void virt_wifi_destroy_wiphy(struct wiphy
*wiphy
)
382 struct virt_wifi_wiphy_priv
*priv
;
384 WARN(!wiphy
, "%s called with null wiphy", __func__
);
388 priv
= wiphy_priv(wiphy
);
389 priv
->being_deleted
= true;
390 virt_wifi_cancel_scan(wiphy
);
392 if (wiphy
->registered
)
393 wiphy_unregister(wiphy
);
397 /* Enters and exits a RCU-bh critical section. */
398 static netdev_tx_t
virt_wifi_start_xmit(struct sk_buff
*skb
,
399 struct net_device
*dev
)
401 struct virt_wifi_netdev_priv
*priv
= netdev_priv(dev
);
404 if (!priv
->is_connected
) {
406 return NET_XMIT_DROP
;
409 skb
->dev
= priv
->lowerdev
;
410 return dev_queue_xmit(skb
);
413 /* Called with rtnl lock held. */
414 static int virt_wifi_net_device_open(struct net_device
*dev
)
416 struct virt_wifi_netdev_priv
*priv
= netdev_priv(dev
);
422 /* Called with rtnl lock held. */
423 static int virt_wifi_net_device_stop(struct net_device
*dev
)
425 struct virt_wifi_netdev_priv
*n_priv
= netdev_priv(dev
);
427 n_priv
->is_up
= false;
429 if (!dev
->ieee80211_ptr
)
432 virt_wifi_cancel_scan(dev
->ieee80211_ptr
->wiphy
);
433 virt_wifi_cancel_connect(dev
);
434 netif_carrier_off(dev
);
439 static int virt_wifi_net_device_get_iflink(const struct net_device
*dev
)
441 struct virt_wifi_netdev_priv
*priv
= netdev_priv(dev
);
443 return priv
->lowerdev
->ifindex
;
446 static const struct net_device_ops virt_wifi_ops
= {
447 .ndo_start_xmit
= virt_wifi_start_xmit
,
448 .ndo_open
= virt_wifi_net_device_open
,
449 .ndo_stop
= virt_wifi_net_device_stop
,
450 .ndo_get_iflink
= virt_wifi_net_device_get_iflink
,
453 /* Invoked as part of rtnl lock release. */
454 static void virt_wifi_net_device_destructor(struct net_device
*dev
)
456 /* Delayed past dellink to allow nl80211 to react to the device being
459 kfree(dev
->ieee80211_ptr
);
460 dev
->ieee80211_ptr
= NULL
;
463 /* No lock interaction. */
464 static void virt_wifi_setup(struct net_device
*dev
)
467 dev
->netdev_ops
= &virt_wifi_ops
;
468 dev
->needs_free_netdev
= true;
471 /* Called in a RCU read critical section from netif_receive_skb */
472 static rx_handler_result_t
virt_wifi_rx_handler(struct sk_buff
**pskb
)
474 struct sk_buff
*skb
= *pskb
;
475 struct virt_wifi_netdev_priv
*priv
=
476 rcu_dereference(skb
->dev
->rx_handler_data
);
478 if (!priv
->is_connected
)
479 return RX_HANDLER_PASS
;
481 /* GFP_ATOMIC because this is a packet interrupt handler. */
482 skb
= skb_share_check(skb
, GFP_ATOMIC
);
484 dev_err(&priv
->upperdev
->dev
, "can't skb_share_check\n");
485 return RX_HANDLER_CONSUMED
;
489 skb
->dev
= priv
->upperdev
;
490 skb
->pkt_type
= PACKET_HOST
;
491 return RX_HANDLER_ANOTHER
;
494 /* Called with rtnl lock held. */
495 static int virt_wifi_newlink(struct net
*src_net
, struct net_device
*dev
,
496 struct nlattr
*tb
[], struct nlattr
*data
[],
497 struct netlink_ext_ack
*extack
)
499 struct virt_wifi_netdev_priv
*priv
= netdev_priv(dev
);
505 netif_carrier_off(dev
);
507 priv
->upperdev
= dev
;
508 priv
->lowerdev
= __dev_get_by_index(src_net
,
509 nla_get_u32(tb
[IFLA_LINK
]));
514 dev
->mtu
= priv
->lowerdev
->mtu
;
515 else if (dev
->mtu
> priv
->lowerdev
->mtu
)
518 err
= netdev_rx_handler_register(priv
->lowerdev
, virt_wifi_rx_handler
,
521 dev_err(&priv
->lowerdev
->dev
,
522 "can't netdev_rx_handler_register: %d\n", err
);
526 eth_hw_addr_inherit(dev
, priv
->lowerdev
);
527 netif_stacked_transfer_operstate(priv
->lowerdev
, dev
);
529 SET_NETDEV_DEV(dev
, &priv
->lowerdev
->dev
);
530 dev
->ieee80211_ptr
= kzalloc(sizeof(*dev
->ieee80211_ptr
), GFP_KERNEL
);
532 if (!dev
->ieee80211_ptr
) {
537 dev
->ieee80211_ptr
->iftype
= NL80211_IFTYPE_STATION
;
538 dev
->ieee80211_ptr
->wiphy
= common_wiphy
;
540 err
= register_netdevice(dev
);
542 dev_err(&priv
->lowerdev
->dev
, "can't register_netdevice: %d\n",
544 goto free_wireless_dev
;
547 err
= netdev_upper_dev_link(priv
->lowerdev
, dev
, extack
);
549 dev_err(&priv
->lowerdev
->dev
, "can't netdev_upper_dev_link: %d\n",
551 goto unregister_netdev
;
554 dev
->priv_destructor
= virt_wifi_net_device_destructor
;
555 priv
->being_deleted
= false;
556 priv
->is_connected
= false;
558 INIT_DELAYED_WORK(&priv
->connect
, virt_wifi_connect_complete
);
559 __module_get(THIS_MODULE
);
563 unregister_netdevice(dev
);
565 kfree(dev
->ieee80211_ptr
);
566 dev
->ieee80211_ptr
= NULL
;
568 netdev_rx_handler_unregister(priv
->lowerdev
);
573 /* Called with rtnl lock held. */
574 static void virt_wifi_dellink(struct net_device
*dev
,
575 struct list_head
*head
)
577 struct virt_wifi_netdev_priv
*priv
= netdev_priv(dev
);
579 if (dev
->ieee80211_ptr
)
580 virt_wifi_cancel_scan(dev
->ieee80211_ptr
->wiphy
);
582 priv
->being_deleted
= true;
583 virt_wifi_cancel_connect(dev
);
584 netif_carrier_off(dev
);
586 netdev_rx_handler_unregister(priv
->lowerdev
);
587 netdev_upper_dev_unlink(priv
->lowerdev
, dev
);
589 unregister_netdevice_queue(dev
, head
);
590 module_put(THIS_MODULE
);
592 /* Deleting the wiphy is handled in the module destructor. */
595 static struct rtnl_link_ops virt_wifi_link_ops
= {
597 .setup
= virt_wifi_setup
,
598 .newlink
= virt_wifi_newlink
,
599 .dellink
= virt_wifi_dellink
,
600 .priv_size
= sizeof(struct virt_wifi_netdev_priv
),
603 static bool netif_is_virt_wifi_dev(const struct net_device
*dev
)
605 return rcu_access_pointer(dev
->rx_handler
) == virt_wifi_rx_handler
;
608 static int virt_wifi_event(struct notifier_block
*this, unsigned long event
,
611 struct net_device
*lower_dev
= netdev_notifier_info_to_dev(ptr
);
612 struct virt_wifi_netdev_priv
*priv
;
613 struct net_device
*upper_dev
;
614 LIST_HEAD(list_kill
);
616 if (!netif_is_virt_wifi_dev(lower_dev
))
620 case NETDEV_UNREGISTER
:
621 priv
= rtnl_dereference(lower_dev
->rx_handler_data
);
625 upper_dev
= priv
->upperdev
;
627 upper_dev
->rtnl_link_ops
->dellink(upper_dev
, &list_kill
);
628 unregister_netdevice_many(&list_kill
);
635 static struct notifier_block virt_wifi_notifier
= {
636 .notifier_call
= virt_wifi_event
,
639 /* Acquires and releases the rtnl lock. */
640 static int __init
virt_wifi_init_module(void)
644 /* Guaranteed to be locallly-administered and not multicast. */
645 eth_random_addr(fake_router_bssid
);
647 err
= register_netdevice_notifier(&virt_wifi_notifier
);
652 common_wiphy
= virt_wifi_make_wiphy();
656 err
= rtnl_link_register(&virt_wifi_link_ops
);
663 virt_wifi_destroy_wiphy(common_wiphy
);
665 unregister_netdevice_notifier(&virt_wifi_notifier
);
669 /* Acquires and releases the rtnl lock. */
670 static void __exit
virt_wifi_cleanup_module(void)
672 /* Will delete any devices that depend on the wiphy. */
673 rtnl_link_unregister(&virt_wifi_link_ops
);
674 virt_wifi_destroy_wiphy(common_wiphy
);
675 unregister_netdevice_notifier(&virt_wifi_notifier
);
678 module_init(virt_wifi_init_module
);
679 module_exit(virt_wifi_cleanup_module
);
681 MODULE_LICENSE("GPL v2");
682 MODULE_AUTHOR("Cody Schuffelen <schuffelen@google.com>");
683 MODULE_DESCRIPTION("Driver for a wireless wrapper of ethernet devices");
684 MODULE_ALIAS_RTNL_LINK("virt_wifi");