1 // SPDX-License-Identifier: GPL-2.0 2 /* drivers/net/wireless/virt_wifi.c 3 * 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. 6 * 7 * Copyright (C) 2018 Google, Inc. 8 * 9 * Author: schuffelen@google.com 10 */ 11 12 #include <net/cfg80211.h> 13 #include <net/rtnetlink.h> 14 #include <linux/etherdevice.h> 15 #include <linux/math64.h> 16 #include <linux/module.h> 17 18 static struct wiphy *common_wiphy; 19 20 struct virt_wifi_wiphy_priv { 21 struct delayed_work scan_result; 22 struct cfg80211_scan_request *scan_request; 23 bool being_deleted; 24 }; 25 26 static struct ieee80211_channel channel_2ghz = { 27 .band = NL80211_BAND_2GHZ, 28 .center_freq = 2432, 29 .hw_value = 2432, 30 .max_power = 20, 31 }; 32 33 static struct ieee80211_rate bitrates_2ghz[] = { 34 { .bitrate = 10 }, 35 { .bitrate = 20 }, 36 { .bitrate = 55 }, 37 { .bitrate = 110 }, 38 { .bitrate = 60 }, 39 { .bitrate = 120 }, 40 { .bitrate = 240 }, 41 }; 42 43 static struct ieee80211_supported_band band_2ghz = { 44 .channels = &channel_2ghz, 45 .bitrates = bitrates_2ghz, 46 .band = NL80211_BAND_2GHZ, 47 .n_channels = 1, 48 .n_bitrates = ARRAY_SIZE(bitrates_2ghz), 49 .ht_cap = { 50 .ht_supported = true, 51 .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 52 IEEE80211_HT_CAP_GRN_FLD | 53 IEEE80211_HT_CAP_SGI_20 | 54 IEEE80211_HT_CAP_SGI_40 | 55 IEEE80211_HT_CAP_DSSSCCK40, 56 .ampdu_factor = 0x3, 57 .ampdu_density = 0x6, 58 .mcs = { 59 .rx_mask = {0xff, 0xff}, 60 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 61 }, 62 }, 63 }; 64 65 static struct ieee80211_channel channel_5ghz = { 66 .band = NL80211_BAND_5GHZ, 67 .center_freq = 5240, 68 .hw_value = 5240, 69 .max_power = 20, 70 }; 71 72 static struct ieee80211_rate bitrates_5ghz[] = { 73 { .bitrate = 60 }, 74 { .bitrate = 120 }, 75 { .bitrate = 240 }, 76 }; 77 78 #define RX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ 79 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \ 80 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \ 81 IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \ 82 IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \ 83 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \ 84 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \ 85 IEEE80211_VHT_MCS_SUPPORT_0_9 << 14) 86 87 #define TX_MCS_MAP (IEEE80211_VHT_MCS_SUPPORT_0_9 << 0 | \ 88 IEEE80211_VHT_MCS_SUPPORT_0_9 << 2 | \ 89 IEEE80211_VHT_MCS_SUPPORT_0_9 << 4 | \ 90 IEEE80211_VHT_MCS_SUPPORT_0_9 << 6 | \ 91 IEEE80211_VHT_MCS_SUPPORT_0_9 << 8 | \ 92 IEEE80211_VHT_MCS_SUPPORT_0_9 << 10 | \ 93 IEEE80211_VHT_MCS_SUPPORT_0_9 << 12 | \ 94 IEEE80211_VHT_MCS_SUPPORT_0_9 << 14) 95 96 static struct ieee80211_supported_band band_5ghz = { 97 .channels = &channel_5ghz, 98 .bitrates = bitrates_5ghz, 99 .band = NL80211_BAND_5GHZ, 100 .n_channels = 1, 101 .n_bitrates = ARRAY_SIZE(bitrates_5ghz), 102 .ht_cap = { 103 .ht_supported = true, 104 .cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 | 105 IEEE80211_HT_CAP_GRN_FLD | 106 IEEE80211_HT_CAP_SGI_20 | 107 IEEE80211_HT_CAP_SGI_40 | 108 IEEE80211_HT_CAP_DSSSCCK40, 109 .ampdu_factor = 0x3, 110 .ampdu_density = 0x6, 111 .mcs = { 112 .rx_mask = {0xff, 0xff}, 113 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, 114 }, 115 }, 116 .vht_cap = { 117 .vht_supported = true, 118 .cap = IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454 | 119 IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ | 120 IEEE80211_VHT_CAP_RXLDPC | 121 IEEE80211_VHT_CAP_SHORT_GI_80 | 122 IEEE80211_VHT_CAP_SHORT_GI_160 | 123 IEEE80211_VHT_CAP_TXSTBC | 124 IEEE80211_VHT_CAP_RXSTBC_1 | 125 IEEE80211_VHT_CAP_RXSTBC_2 | 126 IEEE80211_VHT_CAP_RXSTBC_3 | 127 IEEE80211_VHT_CAP_RXSTBC_4 | 128 IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_MASK, 129 .vht_mcs = { 130 .rx_mcs_map = cpu_to_le16(RX_MCS_MAP), 131 .tx_mcs_map = cpu_to_le16(TX_MCS_MAP), 132 } 133 }, 134 }; 135 136 /* Assigned at module init. Guaranteed locally-administered and unicast. */ 137 static u8 fake_router_bssid[ETH_ALEN] __ro_after_init = {}; 138 139 #define VIRT_WIFI_SSID "VirtWifi" 140 #define VIRT_WIFI_SSID_LEN 8 141 142 static void virt_wifi_inform_bss(struct wiphy *wiphy) 143 { 144 u64 tsf = div_u64(ktime_get_boottime_ns(), 1000); 145 struct cfg80211_bss *informed_bss; 146 static const struct { 147 u8 tag; 148 u8 len; 149 u8 ssid[8] __nonstring; 150 } __packed ssid = { 151 .tag = WLAN_EID_SSID, 152 .len = VIRT_WIFI_SSID_LEN, 153 .ssid = VIRT_WIFI_SSID, 154 }; 155 156 informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz, 157 CFG80211_BSS_FTYPE_PRESP, 158 fake_router_bssid, tsf, 159 WLAN_CAPABILITY_ESS, 0, 160 (void *)&ssid, sizeof(ssid), 161 DBM_TO_MBM(-50), GFP_KERNEL); 162 cfg80211_put_bss(wiphy, informed_bss); 163 } 164 165 /* Called with the rtnl lock held. */ 166 static int virt_wifi_scan(struct wiphy *wiphy, 167 struct cfg80211_scan_request *request) 168 { 169 struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy); 170 171 wiphy_debug(wiphy, "scan\n"); 172 173 if (priv->scan_request || priv->being_deleted) 174 return -EBUSY; 175 176 priv->scan_request = request; 177 schedule_delayed_work(&priv->scan_result, HZ * 2); 178 179 return 0; 180 } 181 182 /* Acquires and releases the rdev BSS lock. */ 183 static void virt_wifi_scan_result(struct work_struct *work) 184 { 185 struct virt_wifi_wiphy_priv *priv = 186 container_of(work, struct virt_wifi_wiphy_priv, 187 scan_result.work); 188 struct wiphy *wiphy = priv_to_wiphy(priv); 189 struct cfg80211_scan_info scan_info = { .aborted = false }; 190 191 virt_wifi_inform_bss(wiphy); 192 193 /* Schedules work which acquires and releases the rtnl lock. */ 194 cfg80211_scan_done(priv->scan_request, &scan_info); 195 priv->scan_request = NULL; 196 } 197 198 /* May acquire and release the rdev BSS lock. */ 199 static void virt_wifi_cancel_scan(struct wiphy *wiphy) 200 { 201 struct virt_wifi_wiphy_priv *priv = wiphy_priv(wiphy); 202 203 cancel_delayed_work_sync(&priv->scan_result); 204 /* Clean up dangling callbacks if necessary. */ 205 if (priv->scan_request) { 206 struct cfg80211_scan_info scan_info = { .aborted = true }; 207 /* Schedules work which acquires and releases the rtnl lock. */ 208 cfg80211_scan_done(priv->scan_request, &scan_info); 209 priv->scan_request = NULL; 210 } 211 } 212 213 struct virt_wifi_netdev_priv { 214 struct delayed_work connect; 215 struct net_device *lowerdev; 216 struct net_device *upperdev; 217 u32 tx_packets; 218 u32 tx_failed; 219 u32 connect_requested_ssid_len; 220 u8 connect_requested_ssid[IEEE80211_MAX_SSID_LEN]; 221 u8 connect_requested_bss[ETH_ALEN]; 222 bool is_up; 223 bool is_connected; 224 bool being_deleted; 225 }; 226 227 /* Called with the rtnl lock held. */ 228 static int virt_wifi_connect(struct wiphy *wiphy, struct net_device *netdev, 229 struct cfg80211_connect_params *sme) 230 { 231 struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); 232 bool could_schedule; 233 234 if (priv->being_deleted || !priv->is_up) 235 return -EBUSY; 236 237 if (!sme->ssid) 238 return -EINVAL; 239 240 priv->connect_requested_ssid_len = sme->ssid_len; 241 memcpy(priv->connect_requested_ssid, sme->ssid, sme->ssid_len); 242 243 could_schedule = schedule_delayed_work(&priv->connect, HZ * 2); 244 if (!could_schedule) 245 return -EBUSY; 246 247 if (sme->bssid) { 248 ether_addr_copy(priv->connect_requested_bss, sme->bssid); 249 } else { 250 virt_wifi_inform_bss(wiphy); 251 eth_zero_addr(priv->connect_requested_bss); 252 } 253 254 wiphy_debug(wiphy, "connect\n"); 255 256 return 0; 257 } 258 259 /* Acquires and releases the rdev event lock. */ 260 static void virt_wifi_connect_complete(struct work_struct *work) 261 { 262 struct virt_wifi_netdev_priv *priv = 263 container_of(work, struct virt_wifi_netdev_priv, connect.work); 264 u8 *requested_bss = priv->connect_requested_bss; 265 bool right_addr = ether_addr_equal(requested_bss, fake_router_bssid); 266 bool right_ssid = priv->connect_requested_ssid_len == VIRT_WIFI_SSID_LEN && 267 !memcmp(priv->connect_requested_ssid, VIRT_WIFI_SSID, 268 priv->connect_requested_ssid_len); 269 u16 status = WLAN_STATUS_SUCCESS; 270 271 if (is_zero_ether_addr(requested_bss)) 272 requested_bss = NULL; 273 274 if (!priv->is_up || (requested_bss && !right_addr) || !right_ssid) 275 status = WLAN_STATUS_UNSPECIFIED_FAILURE; 276 else 277 priv->is_connected = true; 278 279 /* Schedules an event that acquires the rtnl lock. */ 280 cfg80211_connect_result(priv->upperdev, 281 priv->is_connected ? fake_router_bssid : NULL, 282 NULL, 0, NULL, 0, 283 status, GFP_KERNEL); 284 netif_carrier_on(priv->upperdev); 285 } 286 287 /* May acquire and release the rdev event lock. */ 288 static void virt_wifi_cancel_connect(struct net_device *netdev) 289 { 290 struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); 291 292 /* If there is work pending, clean up dangling callbacks. */ 293 if (cancel_delayed_work_sync(&priv->connect)) { 294 /* Schedules an event that acquires the rtnl lock. */ 295 cfg80211_connect_result(priv->upperdev, 296 priv->connect_requested_bss, NULL, 0, 297 NULL, 0, 298 WLAN_STATUS_UNSPECIFIED_FAILURE, 299 GFP_KERNEL); 300 } 301 } 302 303 /* Called with the rtnl lock held. Acquires the rdev event lock. */ 304 static int virt_wifi_disconnect(struct wiphy *wiphy, struct net_device *netdev, 305 u16 reason_code) 306 { 307 struct virt_wifi_netdev_priv *priv = netdev_priv(netdev); 308 309 if (priv->being_deleted) 310 return -EBUSY; 311 312 wiphy_debug(wiphy, "disconnect\n"); 313 virt_wifi_cancel_connect(netdev); 314 315 cfg80211_disconnected(netdev, reason_code, NULL, 0, true, GFP_KERNEL); 316 priv->is_connected = false; 317 netif_carrier_off(netdev); 318 319 return 0; 320 } 321 322 /* Called with the rtnl lock held. */ 323 static int virt_wifi_get_station(struct wiphy *wiphy, 324 struct wireless_dev *wdev, const u8 *mac, 325 struct station_info *sinfo) 326 { 327 struct net_device *dev = wdev->netdev; 328 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 329 330 wiphy_debug(wiphy, "get_station\n"); 331 332 if (!priv->is_connected || !ether_addr_equal(mac, fake_router_bssid)) 333 return -ENOENT; 334 335 sinfo->filled = BIT_ULL(NL80211_STA_INFO_TX_PACKETS) | 336 BIT_ULL(NL80211_STA_INFO_TX_FAILED) | 337 BIT_ULL(NL80211_STA_INFO_SIGNAL) | 338 BIT_ULL(NL80211_STA_INFO_TX_BITRATE); 339 sinfo->tx_packets = priv->tx_packets; 340 sinfo->tx_failed = priv->tx_failed; 341 /* For CFG80211_SIGNAL_TYPE_MBM, value is expressed in _dBm_ */ 342 sinfo->signal = -50; 343 sinfo->txrate = (struct rate_info) { 344 .legacy = 10, /* units are 100kbit/s */ 345 }; 346 return 0; 347 } 348 349 /* Called with the rtnl lock held. */ 350 static int virt_wifi_dump_station(struct wiphy *wiphy, struct wireless_dev *wdev, 351 int idx, u8 *mac, struct station_info *sinfo) 352 { 353 struct virt_wifi_netdev_priv *priv = netdev_priv(wdev->netdev); 354 355 wiphy_debug(wiphy, "dump_station\n"); 356 357 if (idx != 0 || !priv->is_connected) 358 return -ENOENT; 359 360 ether_addr_copy(mac, fake_router_bssid); 361 return virt_wifi_get_station(wiphy, wdev, fake_router_bssid, sinfo); 362 } 363 364 static const struct cfg80211_ops virt_wifi_cfg80211_ops = { 365 .scan = virt_wifi_scan, 366 367 .connect = virt_wifi_connect, 368 .disconnect = virt_wifi_disconnect, 369 370 .get_station = virt_wifi_get_station, 371 .dump_station = virt_wifi_dump_station, 372 }; 373 374 /* Acquires and releases the rtnl lock. */ 375 static struct wiphy *virt_wifi_make_wiphy(void) 376 { 377 struct wiphy *wiphy; 378 struct virt_wifi_wiphy_priv *priv; 379 int err; 380 381 wiphy = wiphy_new(&virt_wifi_cfg80211_ops, sizeof(*priv)); 382 383 if (!wiphy) 384 return NULL; 385 386 wiphy->max_scan_ssids = 4; 387 wiphy->max_scan_ie_len = 1000; 388 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 389 390 wiphy->bands[NL80211_BAND_2GHZ] = &band_2ghz; 391 wiphy->bands[NL80211_BAND_5GHZ] = &band_5ghz; 392 wiphy->bands[NL80211_BAND_60GHZ] = NULL; 393 394 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 395 396 priv = wiphy_priv(wiphy); 397 priv->being_deleted = false; 398 priv->scan_request = NULL; 399 INIT_DELAYED_WORK(&priv->scan_result, virt_wifi_scan_result); 400 401 err = wiphy_register(wiphy); 402 if (err < 0) { 403 wiphy_free(wiphy); 404 return NULL; 405 } 406 407 return wiphy; 408 } 409 410 /* Acquires and releases the rtnl lock. */ 411 static void virt_wifi_destroy_wiphy(struct wiphy *wiphy) 412 { 413 struct virt_wifi_wiphy_priv *priv; 414 415 WARN(!wiphy, "%s called with null wiphy", __func__); 416 if (!wiphy) 417 return; 418 419 priv = wiphy_priv(wiphy); 420 priv->being_deleted = true; 421 virt_wifi_cancel_scan(wiphy); 422 423 if (wiphy->registered) 424 wiphy_unregister(wiphy); 425 wiphy_free(wiphy); 426 } 427 428 /* Enters and exits a RCU-bh critical section. */ 429 static netdev_tx_t virt_wifi_start_xmit(struct sk_buff *skb, 430 struct net_device *dev) 431 { 432 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 433 434 priv->tx_packets++; 435 if (!priv->is_connected) { 436 priv->tx_failed++; 437 return NET_XMIT_DROP; 438 } 439 440 skb->dev = priv->lowerdev; 441 return dev_queue_xmit(skb); 442 } 443 444 /* Called with rtnl lock held. */ 445 static int virt_wifi_net_device_open(struct net_device *dev) 446 { 447 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 448 449 priv->is_up = true; 450 return 0; 451 } 452 453 /* Called with rtnl lock held. */ 454 static int virt_wifi_net_device_stop(struct net_device *dev) 455 { 456 struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev); 457 458 n_priv->is_up = false; 459 460 if (!dev->ieee80211_ptr) 461 return 0; 462 463 virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); 464 virt_wifi_cancel_connect(dev); 465 netif_carrier_off(dev); 466 467 return 0; 468 } 469 470 static int virt_wifi_net_device_get_iflink(const struct net_device *dev) 471 { 472 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 473 474 return READ_ONCE(priv->lowerdev->ifindex); 475 } 476 477 static const struct net_device_ops virt_wifi_ops = { 478 .ndo_start_xmit = virt_wifi_start_xmit, 479 .ndo_open = virt_wifi_net_device_open, 480 .ndo_stop = virt_wifi_net_device_stop, 481 .ndo_get_iflink = virt_wifi_net_device_get_iflink, 482 }; 483 484 /* Invoked as part of rtnl lock release. */ 485 static void virt_wifi_net_device_destructor(struct net_device *dev) 486 { 487 /* Delayed past dellink to allow nl80211 to react to the device being 488 * deleted. 489 */ 490 kfree(dev->ieee80211_ptr); 491 dev->ieee80211_ptr = NULL; 492 } 493 494 /* No lock interaction. */ 495 static void virt_wifi_setup(struct net_device *dev) 496 { 497 ether_setup(dev); 498 dev->netdev_ops = &virt_wifi_ops; 499 dev->needs_free_netdev = true; 500 } 501 502 /* Called in a RCU read critical section from netif_receive_skb */ 503 static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb) 504 { 505 struct sk_buff *skb = *pskb; 506 struct virt_wifi_netdev_priv *priv = 507 rcu_dereference(skb->dev->rx_handler_data); 508 509 if (!priv->is_connected) 510 return RX_HANDLER_PASS; 511 512 /* GFP_ATOMIC because this is a packet interrupt handler. */ 513 skb = skb_share_check(skb, GFP_ATOMIC); 514 if (!skb) { 515 dev_err(&priv->upperdev->dev, "can't skb_share_check\n"); 516 return RX_HANDLER_CONSUMED; 517 } 518 519 *pskb = skb; 520 skb->dev = priv->upperdev; 521 skb->pkt_type = PACKET_HOST; 522 return RX_HANDLER_ANOTHER; 523 } 524 525 /* Called with rtnl lock held. */ 526 static int virt_wifi_newlink(struct net_device *dev, 527 struct rtnl_newlink_params *params, 528 struct netlink_ext_ack *extack) 529 { 530 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 531 struct net *link_net = rtnl_newlink_link_net(params); 532 struct nlattr **tb = params->tb; 533 int err; 534 535 if (!tb[IFLA_LINK]) 536 return -EINVAL; 537 538 netif_carrier_off(dev); 539 540 priv->upperdev = dev; 541 priv->lowerdev = __dev_get_by_index(link_net, 542 nla_get_u32(tb[IFLA_LINK])); 543 544 if (!priv->lowerdev) 545 return -ENODEV; 546 if (!tb[IFLA_MTU]) 547 dev->mtu = priv->lowerdev->mtu; 548 else if (dev->mtu > priv->lowerdev->mtu) 549 return -EINVAL; 550 551 err = netdev_rx_handler_register(priv->lowerdev, virt_wifi_rx_handler, 552 priv); 553 if (err) { 554 dev_err(&priv->lowerdev->dev, 555 "can't netdev_rx_handler_register: %d\n", err); 556 return err; 557 } 558 559 eth_hw_addr_inherit(dev, priv->lowerdev); 560 netif_stacked_transfer_operstate(priv->lowerdev, dev); 561 562 dev->ieee80211_ptr = kzalloc_obj(*dev->ieee80211_ptr); 563 564 if (!dev->ieee80211_ptr) { 565 err = -ENOMEM; 566 goto remove_handler; 567 } 568 569 dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION; 570 dev->ieee80211_ptr->wiphy = common_wiphy; 571 572 err = register_netdevice(dev); 573 if (err) { 574 dev_err(&priv->lowerdev->dev, "can't register_netdevice: %d\n", 575 err); 576 goto free_wireless_dev; 577 } 578 579 err = netdev_upper_dev_link(priv->lowerdev, dev, extack); 580 if (err) { 581 dev_err(&priv->lowerdev->dev, "can't netdev_upper_dev_link: %d\n", 582 err); 583 goto unregister_netdev; 584 } 585 586 dev->priv_destructor = virt_wifi_net_device_destructor; 587 priv->being_deleted = false; 588 priv->is_connected = false; 589 priv->is_up = false; 590 INIT_DELAYED_WORK(&priv->connect, virt_wifi_connect_complete); 591 __module_get(THIS_MODULE); 592 593 return 0; 594 unregister_netdev: 595 unregister_netdevice(dev); 596 free_wireless_dev: 597 kfree(dev->ieee80211_ptr); 598 dev->ieee80211_ptr = NULL; 599 remove_handler: 600 netdev_rx_handler_unregister(priv->lowerdev); 601 602 return err; 603 } 604 605 /* Called with rtnl lock held. */ 606 static void virt_wifi_dellink(struct net_device *dev, 607 struct list_head *head) 608 { 609 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 610 611 if (dev->ieee80211_ptr) 612 virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); 613 614 priv->being_deleted = true; 615 virt_wifi_cancel_connect(dev); 616 netif_carrier_off(dev); 617 618 netdev_rx_handler_unregister(priv->lowerdev); 619 netdev_upper_dev_unlink(priv->lowerdev, dev); 620 621 unregister_netdevice_queue(dev, head); 622 module_put(THIS_MODULE); 623 624 /* Deleting the wiphy is handled in the module destructor. */ 625 } 626 627 static struct rtnl_link_ops virt_wifi_link_ops = { 628 .kind = "virt_wifi", 629 .setup = virt_wifi_setup, 630 .newlink = virt_wifi_newlink, 631 .dellink = virt_wifi_dellink, 632 .priv_size = sizeof(struct virt_wifi_netdev_priv), 633 }; 634 635 static bool netif_is_virt_wifi_dev(const struct net_device *dev) 636 { 637 return rcu_access_pointer(dev->rx_handler) == virt_wifi_rx_handler; 638 } 639 640 static int virt_wifi_event(struct notifier_block *this, unsigned long event, 641 void *ptr) 642 { 643 struct net_device *lower_dev = netdev_notifier_info_to_dev(ptr); 644 struct virt_wifi_netdev_priv *priv; 645 struct net_device *upper_dev; 646 LIST_HEAD(list_kill); 647 648 if (!netif_is_virt_wifi_dev(lower_dev)) 649 return NOTIFY_DONE; 650 651 switch (event) { 652 case NETDEV_UNREGISTER: 653 priv = rtnl_dereference(lower_dev->rx_handler_data); 654 if (!priv) 655 return NOTIFY_DONE; 656 657 upper_dev = priv->upperdev; 658 659 upper_dev->rtnl_link_ops->dellink(upper_dev, &list_kill); 660 unregister_netdevice_many(&list_kill); 661 break; 662 } 663 664 return NOTIFY_DONE; 665 } 666 667 static struct notifier_block virt_wifi_notifier = { 668 .notifier_call = virt_wifi_event, 669 }; 670 671 /* Acquires and releases the rtnl lock. */ 672 static int __init virt_wifi_init_module(void) 673 { 674 int err; 675 676 /* Guaranteed to be locally-administered and not multicast. */ 677 eth_random_addr(fake_router_bssid); 678 679 err = register_netdevice_notifier(&virt_wifi_notifier); 680 if (err) 681 return err; 682 683 err = -ENOMEM; 684 common_wiphy = virt_wifi_make_wiphy(); 685 if (!common_wiphy) 686 goto notifier; 687 688 err = rtnl_link_register(&virt_wifi_link_ops); 689 if (err) 690 goto destroy_wiphy; 691 692 return 0; 693 694 destroy_wiphy: 695 virt_wifi_destroy_wiphy(common_wiphy); 696 notifier: 697 unregister_netdevice_notifier(&virt_wifi_notifier); 698 return err; 699 } 700 701 /* Acquires and releases the rtnl lock. */ 702 static void __exit virt_wifi_cleanup_module(void) 703 { 704 /* Will delete any devices that depend on the wiphy. */ 705 rtnl_link_unregister(&virt_wifi_link_ops); 706 virt_wifi_destroy_wiphy(common_wiphy); 707 unregister_netdevice_notifier(&virt_wifi_notifier); 708 } 709 710 module_init(virt_wifi_init_module); 711 module_exit(virt_wifi_cleanup_module); 712 713 MODULE_LICENSE("GPL v2"); 714 MODULE_AUTHOR("Cody Schuffelen <schuffelen@google.com>"); 715 MODULE_DESCRIPTION("Driver for a wireless wrapper of ethernet devices"); 716 MODULE_ALIAS_RTNL_LINK("virt_wifi"); 717