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 dev_kfree_skb_any(skb); 438 return NET_XMIT_DROP; 439 } 440 441 skb->dev = priv->lowerdev; 442 return dev_queue_xmit(skb); 443 } 444 445 /* Called with rtnl lock held. */ 446 static int virt_wifi_net_device_open(struct net_device *dev) 447 { 448 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 449 450 priv->is_up = true; 451 return 0; 452 } 453 454 /* Called with rtnl lock held. */ 455 static int virt_wifi_net_device_stop(struct net_device *dev) 456 { 457 struct virt_wifi_netdev_priv *n_priv = netdev_priv(dev); 458 459 n_priv->is_up = false; 460 461 if (!dev->ieee80211_ptr) 462 return 0; 463 464 virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); 465 virt_wifi_cancel_connect(dev); 466 netif_carrier_off(dev); 467 468 return 0; 469 } 470 471 static int virt_wifi_net_device_get_iflink(const struct net_device *dev) 472 { 473 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 474 475 return READ_ONCE(priv->lowerdev->ifindex); 476 } 477 478 static const struct net_device_ops virt_wifi_ops = { 479 .ndo_start_xmit = virt_wifi_start_xmit, 480 .ndo_open = virt_wifi_net_device_open, 481 .ndo_stop = virt_wifi_net_device_stop, 482 .ndo_get_iflink = virt_wifi_net_device_get_iflink, 483 }; 484 485 /* Invoked as part of rtnl lock release. */ 486 static void virt_wifi_net_device_destructor(struct net_device *dev) 487 { 488 /* Delayed past dellink to allow nl80211 to react to the device being 489 * deleted. 490 */ 491 kfree(dev->ieee80211_ptr); 492 dev->ieee80211_ptr = NULL; 493 } 494 495 /* No lock interaction. */ 496 static void virt_wifi_setup(struct net_device *dev) 497 { 498 ether_setup(dev); 499 dev->netdev_ops = &virt_wifi_ops; 500 dev->needs_free_netdev = true; 501 } 502 503 /* Called in a RCU read critical section from netif_receive_skb */ 504 static rx_handler_result_t virt_wifi_rx_handler(struct sk_buff **pskb) 505 { 506 struct sk_buff *skb = *pskb; 507 struct virt_wifi_netdev_priv *priv = 508 rcu_dereference(skb->dev->rx_handler_data); 509 510 if (!priv->is_connected) 511 return RX_HANDLER_PASS; 512 513 /* GFP_ATOMIC because this is a packet interrupt handler. */ 514 skb = skb_share_check(skb, GFP_ATOMIC); 515 if (!skb) { 516 dev_err(&priv->upperdev->dev, "can't skb_share_check\n"); 517 return RX_HANDLER_CONSUMED; 518 } 519 520 *pskb = skb; 521 skb->dev = priv->upperdev; 522 skb->pkt_type = PACKET_HOST; 523 return RX_HANDLER_ANOTHER; 524 } 525 526 /* Called with rtnl lock held. */ 527 static int virt_wifi_newlink(struct net_device *dev, 528 struct rtnl_newlink_params *params, 529 struct netlink_ext_ack *extack) 530 { 531 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 532 struct net *link_net = rtnl_newlink_link_net(params); 533 struct nlattr **tb = params->tb; 534 int err; 535 536 if (!tb[IFLA_LINK]) 537 return -EINVAL; 538 539 netif_carrier_off(dev); 540 541 priv->upperdev = dev; 542 priv->lowerdev = __dev_get_by_index(link_net, 543 nla_get_u32(tb[IFLA_LINK])); 544 545 if (!priv->lowerdev) 546 return -ENODEV; 547 if (!tb[IFLA_MTU]) 548 dev->mtu = priv->lowerdev->mtu; 549 else if (dev->mtu > priv->lowerdev->mtu) 550 return -EINVAL; 551 552 err = netdev_rx_handler_register(priv->lowerdev, virt_wifi_rx_handler, 553 priv); 554 if (err) { 555 dev_err(&priv->lowerdev->dev, 556 "can't netdev_rx_handler_register: %d\n", err); 557 return err; 558 } 559 560 eth_hw_addr_inherit(dev, priv->lowerdev); 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 netif_stacked_transfer_operstate(priv->lowerdev, dev); 587 588 dev->priv_destructor = virt_wifi_net_device_destructor; 589 priv->being_deleted = false; 590 priv->is_connected = false; 591 priv->is_up = false; 592 INIT_DELAYED_WORK(&priv->connect, virt_wifi_connect_complete); 593 __module_get(THIS_MODULE); 594 595 return 0; 596 unregister_netdev: 597 unregister_netdevice(dev); 598 free_wireless_dev: 599 kfree(dev->ieee80211_ptr); 600 dev->ieee80211_ptr = NULL; 601 remove_handler: 602 netdev_rx_handler_unregister(priv->lowerdev); 603 604 return err; 605 } 606 607 /* Called with rtnl lock held. */ 608 static void virt_wifi_dellink(struct net_device *dev, 609 struct list_head *head) 610 { 611 struct virt_wifi_netdev_priv *priv = netdev_priv(dev); 612 613 if (dev->ieee80211_ptr) 614 virt_wifi_cancel_scan(dev->ieee80211_ptr->wiphy); 615 616 priv->being_deleted = true; 617 virt_wifi_cancel_connect(dev); 618 netif_carrier_off(dev); 619 620 netdev_rx_handler_unregister(priv->lowerdev); 621 netdev_upper_dev_unlink(priv->lowerdev, dev); 622 623 unregister_netdevice_queue(dev, head); 624 module_put(THIS_MODULE); 625 626 /* Deleting the wiphy is handled in the module destructor. */ 627 } 628 629 static struct rtnl_link_ops virt_wifi_link_ops = { 630 .kind = "virt_wifi", 631 .setup = virt_wifi_setup, 632 .newlink = virt_wifi_newlink, 633 .dellink = virt_wifi_dellink, 634 .priv_size = sizeof(struct virt_wifi_netdev_priv), 635 }; 636 637 static bool netif_is_virt_wifi_dev(const struct net_device *dev) 638 { 639 return rcu_access_pointer(dev->rx_handler) == virt_wifi_rx_handler; 640 } 641 642 static int virt_wifi_event(struct notifier_block *this, unsigned long event, 643 void *ptr) 644 { 645 struct net_device *lower_dev = netdev_notifier_info_to_dev(ptr); 646 struct virt_wifi_netdev_priv *priv; 647 struct net_device *upper_dev; 648 LIST_HEAD(list_kill); 649 650 if (!netif_is_virt_wifi_dev(lower_dev)) 651 return NOTIFY_DONE; 652 653 switch (event) { 654 case NETDEV_UNREGISTER: 655 priv = rtnl_dereference(lower_dev->rx_handler_data); 656 if (!priv) 657 return NOTIFY_DONE; 658 659 upper_dev = priv->upperdev; 660 661 upper_dev->rtnl_link_ops->dellink(upper_dev, &list_kill); 662 unregister_netdevice_many(&list_kill); 663 break; 664 } 665 666 return NOTIFY_DONE; 667 } 668 669 static struct notifier_block virt_wifi_notifier = { 670 .notifier_call = virt_wifi_event, 671 }; 672 673 /* Acquires and releases the rtnl lock. */ 674 static int __init virt_wifi_init_module(void) 675 { 676 int err; 677 678 /* Guaranteed to be locally-administered and not multicast. */ 679 eth_random_addr(fake_router_bssid); 680 681 err = register_netdevice_notifier(&virt_wifi_notifier); 682 if (err) 683 return err; 684 685 err = -ENOMEM; 686 common_wiphy = virt_wifi_make_wiphy(); 687 if (!common_wiphy) 688 goto notifier; 689 690 err = rtnl_link_register(&virt_wifi_link_ops); 691 if (err) 692 goto destroy_wiphy; 693 694 return 0; 695 696 destroy_wiphy: 697 virt_wifi_destroy_wiphy(common_wiphy); 698 notifier: 699 unregister_netdevice_notifier(&virt_wifi_notifier); 700 return err; 701 } 702 703 /* Acquires and releases the rtnl lock. */ 704 static void __exit virt_wifi_cleanup_module(void) 705 { 706 /* Will delete any devices that depend on the wiphy. */ 707 rtnl_link_unregister(&virt_wifi_link_ops); 708 virt_wifi_destroy_wiphy(common_wiphy); 709 unregister_netdevice_notifier(&virt_wifi_notifier); 710 } 711 712 module_init(virt_wifi_init_module); 713 module_exit(virt_wifi_cleanup_module); 714 715 MODULE_LICENSE("GPL v2"); 716 MODULE_AUTHOR("Cody Schuffelen <schuffelen@google.com>"); 717 MODULE_DESCRIPTION("Driver for a wireless wrapper of ethernet devices"); 718 MODULE_ALIAS_RTNL_LINK("virt_wifi"); 719